def test_roundtrip(self, input_path): reader = CodeReader() fortran_code = reader.read_file(input_path) results_path = pathlib.Path(APPS_RESULTS_ROOT, 'flash5') results_path.mkdir(exist_ok=True) basic_check_fortran_code(self, input_path, fortran_code, results=results_path, suffix=None) parser = Parser.find(Language.find('Fortran'))() fortran_ast = parser.parse(fortran_code, input_path) basic_check_fortran_ast(self, input_path, fortran_ast, results=results_path) ast_generalizer = AstGeneralizer.find(Language.find('Fortran'))() syntax = ast_generalizer.generalize(fortran_ast) basic_check_python_ast(self, input_path, syntax, results=results_path) unparser = Unparser.find(Language.find('Fortran'))() code = unparser.unparse(syntax) basic_check_fortran_code(self, input_path, code, results=results_path)
def test_inline_syntax(self): language = Language.find('Python 3') parser = Parser.find(language)() for (target, inlined), target_inlined in INLINING_EXAMPLES.items(): target_code = CodeReader.read_function(target) inlined_code = CodeReader.read_function(inlined) reference_code = CodeReader.read_function(target_inlined) target_syntax = parser.parse(target_code).body[0] inlined_syntax = parser.parse(inlined_code).body[0] with self.subTest(target=target, inlined=inlined): target_inlined_syntax = inline_syntax(target_syntax, inlined_syntax, verbose=False) target_inlined_code = horast.unparse(target_inlined_syntax) _LOG.warning('%s', target_inlined_code) self.assertEqual(reference_code.replace('_inlined(', '(').lstrip(), target_inlined_code.lstrip())
def test_partial_inline_burn(self): _ = self.app_source_folder.joinpath('physics', 'sourceTerms', 'Burn', 'BurnMain', 'nuclearBurn') inlined_path = _.joinpath('Aprox13', 'bn_mapNetworkToSpecies.F90') target_path = _.joinpath('Burn.F90') reader = CodeReader() inlined_code = reader.read_file(inlined_path) target_code = reader.read_file(target_path) parser = Parser.find(Language.find('Fortran'))() inlined_fortran_ast = parser.parse(inlined_code, inlined_path) # inlined_fortran_ast = inlined_fortran_ast.find('.//subroutine') target_fortran_ast = parser.parse(target_code, target_path) ast_generalizer = AstGeneralizer.find(Language.find('Fortran'))() inlined_syntax = ast_generalizer.generalize(inlined_fortran_ast) inlined_function = inlined_syntax.body[-1] # TODO: implement object finding to find function target_syntax = ast_generalizer.generalize(target_fortran_ast) target_function = target_syntax.body[-1] # TODO: implement object finding to find function # import horast # print(horast.unparse(inlined_function)) # print(horast.unparse(target_function)) # import ipdb; ipdb.set_trace() # import static_typing inlined_syntax = inline_syntax( target_function, inlined_function, # globals_={'NSPECIES': 13, 'st': static_typing, **globals()}, verbose=True) annotation = horast_nodes.OpenAccPragma('parallel loop') annotate_loop_syntax(inlined_syntax, annotation) unparser = Unparser.find(Language.find('Fortran'))() transformed_code = unparser.unparse(inlined_syntax) results_path = pathlib.Path(APPS_RESULTS_ROOT, 'flash5-inlined') results_path.mkdir(exist_ok=True) CodeWriter().write_file(transformed_code, results_path.joinpath('Burn.inlined_some.F90'))
def test_inline_flash_subset_hydro(self): app_name = 'FLASH-SUBSET' if app_name not in _APPS_ROOT_PATHS and app_name in _APPS_OPTIONAL: self.skipTest('{} directory not found'.format(app_name)) language = Language.find('Fortran') reader = CodeReader() parser = Parser.find(language)() ast_generalizer = AstGeneralizer.find(language)() f_unparser = Unparser.find(language)() py_unparser = Unparser.find(Language.find('Python'))() writer = CodeWriter() dir_name = app_name.lower() results_path = pathlib.Path(RESULTS_ROOT, 'transformations', 'inlining', dir_name) results_path.mkdir(parents=True, exist_ok=True) path_pairs = [ (pathlib.Path('physics/Hydro/HydroMain/unsplit/hy_upwindTransverseFlux_loop.F90'), pathlib.Path('physics/Hydro/HydroMain/unsplit/hy_upwindTransverseFlux.F90'), (1, 1)), (pathlib.Path('physics/Eos/EosMain/Eos_getData_loop1.F90'), pathlib.Path('physics/Eos/EosMain/Eos_getData.F90'), (1, 2))] for inlined_path, target_path, (index, extra_lines) in path_pairs: inlined_path = pathlib.Path(_APPS_ROOT_PATHS[app_name], 'source', inlined_path) target_path = pathlib.Path(_APPS_ROOT_PATHS[app_name], 'source', target_path) output_inlined_path = results_path.joinpath(inlined_path.name) output_target_path = results_path.joinpath(target_path.name) output_path = results_path.joinpath(target_path.with_suffix('').name + '_inlined.F90') inlined_xml = parser.parse('', inlined_path) inlined_xml = inlined_xml.find('.//subroutine') writer.write_file(ET.tostring(inlined_xml, 'utf-8').decode(), output_inlined_path.with_suffix('.xml')) inlined_syntax = ast_generalizer.generalize(inlined_xml) writer.write_file(typed_astunparse.dump(inlined_syntax), output_inlined_path.with_suffix('.ast.py')) writer.write_file(py_unparser.unparse(inlined_syntax), output_inlined_path.with_suffix('.py')) writer.write_file(f_unparser.unparse(inlined_syntax), output_inlined_path.with_suffix('.f95')) target_code = reader.read_file(target_path) target_xml = parser.parse(target_code, target_path) # import ipdb; ipdb.set_trace() target_xml = target_xml.findall('.//call')[index] writer.write_file(ET.tostring(target_xml, 'utf-8').decode(), output_target_path.with_suffix('.xml')) target_syntax = ast_generalizer.generalize(target_xml) writer.write_file(typed_astunparse.dump(target_syntax), output_target_path.with_suffix('.ast.py')) writer.write_file(py_unparser.unparse(target_syntax), output_target_path.with_suffix('.py')) writer.write_file(f_unparser.unparse(target_syntax), output_target_path.with_suffix('.f95')) mock_function = typed_ast3.FunctionDef( 'f', typed_ast3.arguments([], None, [], None, [], []), [typed_ast3.Expr(target_syntax)], [], None, None) output_syntax = inline_syntax(mock_function, inlined_syntax, globals_=globals()) output_syntax = st.augment(typed_ast3.Module(output_syntax.body, []), eval_=False) writer.write_file(typed_astunparse.dump(output_syntax), output_path.with_suffix('.ast.py')) writer.write_file(py_unparser.unparse(output_syntax), output_path.with_suffix('.py')) output_code = f_unparser.unparse(output_syntax) writer.write_file(output_code, output_path.with_suffix('.f95')) _LOG.warning('[%s %s] <- %i', target_xml.attrib['line_begin'], target_xml.attrib['line_end'], len(output_code)) total_code = replace_scope( target_code, int(target_xml.attrib['line_begin']), int(target_xml.attrib['line_end']) + extra_lines, output_code) writer.write_file(total_code, output_path)
for root, _, files in os.walk(str(pathlib.Path(_APPS_ROOT_PATHS['FFB-MINI'], 'src'))) for name in files if pathlib.Path(name).suffix in _FORTRAN_SUFFIXES and name not in { 'ddcom4.F', # SyntaxError - just not implemented yet 'ffb_mini_main.F90', # NotImplementedError 'f_test.F90', # NotImplementedError 'mod_maprof.F90', # NotImplementedError # OFP fails for the following files # issues need to be resolved upstream or files need to be modified 'bcgs3x.F', 'bcgsxe.F', 'calax3.F', 'callap.F', 'dd_mpi.F', 'e2plst.F', 'extrfn.F', 'gfutil.f', 'grad3x.F', 'les3x.F', 'lesrop.F', 'lesrpx.F', 'lessfx.F', 'lrfnms.F', 'makemesh.F90', 'miniapp_util.F', 'mfname.F', 'neibr2.F', 'nodlex.F', 'pres3e.F', 'rcmelm.F', 'rfname.F', 'srfexx.F', 'vel3d1.F', 'vel3d2.F'}]} def _prepare_roundtrip(case, language: Language): parser = Parser.find(language)() case.assertIsInstance(parser, Parser) ast_generalizer = AstGeneralizer.find(language)() case.assertIsInstance(ast_generalizer, AstGeneralizer) unparser = Unparser.find(language)() case.assertIsInstance(unparser, Unparser) return parser, ast_generalizer, unparser def _roundtrip_fortran(case, path, results_path, parser, ast_generalizer, unparser): with open(str(path)) as original_file: basic_check_fortran_code(case, path, original_file.read(), results=results_path, append_suffix=False) fortran_ast = parser.parse('', path) basic_check_fortran_ast(case, path, fortran_ast, results=results_path) tree = ast_generalizer.generalize(fortran_ast)