diff --git a/apps/benchmarks/UniformGridCPU/CMakeLists.txt b/apps/benchmarks/UniformGridCPU/CMakeLists.txt index a2f06826e40553f9c157c5b5e5200ba8ed2b26b2..785a0911c1576fada809edfa5e7cb0512cf16b6b 100644 --- a/apps/benchmarks/UniformGridCPU/CMakeLists.txt +++ b/apps/benchmarks/UniformGridCPU/CMakeLists.txt @@ -15,15 +15,6 @@ foreach(streaming_pattern pull push aa esotwist) waLBerla_generate_target_from_python(NAME UniformGridCPUGenerated_${config} FILE UniformGridCPU.py CODEGEN_CFG ${config} - OUT_FILES UniformGridCPU_LbKernel.cpp UniformGridCPU_LbKernel.h - UniformGridCPU_PackInfoEven.cpp UniformGridCPU_PackInfoEven.h - UniformGridCPU_PackInfoOdd.cpp UniformGridCPU_PackInfoOdd.h - UniformGridCPU_NoSlip.cpp UniformGridCPU_NoSlip.h - UniformGridCPU_UBB.cpp UniformGridCPU_UBB.h - UniformGridCPU_MacroSetter.cpp UniformGridCPU_MacroSetter.h - UniformGridCPU_MacroGetter.cpp UniformGridCPU_MacroGetter.h - UniformGridCPU_StreamOnlyKernel.cpp UniformGridCPU_StreamOnlyKernel.h - UniformGridCPU_InfoHeader.h ) diff --git a/cmake/waLBerlaHelperFunctions.cmake b/cmake/waLBerlaHelperFunctions.cmake index 8bfb85ec5ada70ba8a73aaa8e43f9871910a14f1..a587996ede4d5be20e5f8e1bbc6586195c4ed0cf 100644 --- a/cmake/waLBerlaHelperFunctions.cmake +++ b/cmake/waLBerlaHelperFunctions.cmake @@ -40,6 +40,7 @@ function( waLBerla_generate_target_from_python ) set( options ) set( oneValueArgs NAME FILE CODEGEN_CFG) set( multiValueArgs OUT_FILES) + cmake_parse_arguments( PYGEN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) if( NOT WALBERLA_BUILD_WITH_CODEGEN ) if( WALBERLA_LOG_SKIPPED ) @@ -55,14 +56,24 @@ function( waLBerla_generate_target_from_python ) else() set( codegenCfg "default_codegen") endif() - set( generatedSourceFiles ${PYGEN_OUT_FILES} ) - set( generatedWithAbsolutePath ) - foreach( filename ${generatedSourceFiles} ) - list(APPEND generatedWithAbsolutePath ${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}/${filename}) - endforeach() - execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${WALBERLA_PYTHON_DIR}:$ENV{PYTHONPATH} ${Python_EXECUTABLE} ${sourceFile} -l OUTPUT_VARIABLE FOO) - message(${FOO}) + set( WALBERLA_PYTHON_DIR ${walberla_SOURCE_DIR}/python) + + if (PYGEN_OUT_FILES) + set( generatedSourceFiles ${PYGEN_OUT_FILES} ) + set( generatedWithAbsolutePath ) + foreach( filename ${generatedSourceFiles} ) + list(APPEND generatedWithAbsolutePath ${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}/${filename}) + endforeach() + else() + set( analyserScript ${WALBERLA_PYTHON_DIR}/pystencils_walberla/codegen_output_analyser.py ) + execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${WALBERLA_PYTHON_DIR}:$ENV{PYTHONPATH} ${Python_EXECUTABLE} ${analyserScript} OUTPUT_VARIABLE generatedSourceFiles OUTPUT_STRIP_TRAILING_WHITESPACE) + + set( generatedWithAbsolutePath ) + foreach( filename ${generatedSourceFiles} ) + list(APPEND generatedWithAbsolutePath ${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}/${filename}) + endforeach() + endif () set(cmakeVars "\\\{ " "\"WALBERLA_OPTIMIZE_FOR_LOCALHOST\": \"${WALBERLA_OPTIMIZE_FOR_LOCALHOST}\"," @@ -75,7 +86,6 @@ function( waLBerla_generate_target_from_python ) string(REPLACE "\"" "\\\"" cmakeVars ${cmakeVars}) # even one more quoting level required string(REPLACE "\n" "" cmakeVars ${cmakeVars}) # remove newline characters - set( WALBERLA_PYTHON_DIR ${walberla_SOURCE_DIR}/python) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}") add_custom_command(OUTPUT ${generatedWithAbsolutePath} diff --git a/python/pystencils_walberla/codegen_output_analyser.py b/python/pystencils_walberla/codegen_output_analyser.py new file mode 100644 index 0000000000000000000000000000000000000000..f27401fc97c91df9e54fff6b9f111f39aba7b0a0 --- /dev/null +++ b/python/pystencils_walberla/codegen_output_analyser.py @@ -0,0 +1,88 @@ +import ast +import sys + + +class GenerationFunctionsAnalyser(ast.NodeVisitor): + """Receives a codegen script and stores which of the imports come from pystencils_walberla or lbmpy_walberla.""" + + def __init__(self): + self.imports = set() + + def visit_ImportFrom(self, node): + if "pystencils_walberla" in node.module or "lbmpy_walberla" in node.module: + for alias in node.names: + self.imports.add(alias.name) + self.generic_visit(node) + + +class CodegenScriptAnalyser(ast.NodeVisitor): + """Receives a codegen script and stores the names of the output-files that will be generated by the script. + + Args: + codegen_functions: A list of functions that will be used by the codegen script to generate the files. This + list can be obtained automatically with the `GenerationFunctionsAnalyser` + """ + def __init__(self, codegen_functions, gpu=False): + self.codegen_functions = codegen_functions + self.functions = list() + self.gpu = gpu + + def visit_Call(self, node): + if isinstance(node.func, ast.Name): + if node.func.id in self.codegen_functions: + name = node.func.id + class_name = node.args[1].value + target = None + for keyword in node.keywords: + if keyword.arg == 'target': + target = keyword.value.attr + for arg in node.args: + if hasattr(arg, "value"): + if hasattr(arg.value, "attr") and arg.value.attr == "Target": + target = arg.attr + + fct = (name, class_name, target) + if self.gpu: + if (name, class_name, "CPU") in self.functions: + idx = self.functions.index((name, class_name, "CPU")) + self.functions[idx] = (name, class_name, target) + else: + self.functions.append(fct) + else: + if target != "GPU": + self.functions.append(fct) + self.generic_visit(node) + + +r = open('/Users/holzer/walberla/apps/benchmarks/UniformGridCPU/UniformGridCPU.py', 'r') +t = ast.parse(r.read()) + + +import_analyzer = GenerationFunctionsAnalyser() +import_analyzer.visit(t) +codegen_functions = import_analyzer.imports + +if 'CodeGeneration' in codegen_functions: + codegen_functions.remove('CodeGeneration') + +analyzer = CodegenScriptAnalyser(codegen_functions) +analyzer.visit(t) + +file_list = [] +for fct in analyzer.functions: + if fct[1] == "UniformGridCPU_PackInfo": + file_list.append(fct[1] + "Even.cpp") + file_list.append(fct[1] + "Even.h") + file_list.append(fct[1] + "Odd.cpp") + file_list.append(fct[1] + "Odd.h") + else: + if fct[2] == "CPU": + file_list.append(fct[1] + ".cpp") + file_list.append(fct[1] + ".h") + elif fct[2] == "GPU": + file_list.append(fct[1] + ".h") + file_list.append(fct[1] + ".cu") + elif fct[2] is None: + file_list.append(fct[1] + ".h") + +print(";".join(file_list))