From 0e5fc53cbe076f88d161b70e56fac039297ba6e6 Mon Sep 17 00:00:00 2001
From: Markus Holzer <markus.holzer@fau.de>
Date: Tue, 28 Feb 2023 10:07:00 +0100
Subject: [PATCH] Clean CMake with CodeGen

---
 .../UniformGridCPU/UniformGridCPU.py          |  1 -
 cmake/waLBerlaHelperFunctions.cmake           | 24 ++++----
 .../pystencils_walberla/cmake_integration.py  | 61 ++++++++-----------
 3 files changed, 38 insertions(+), 48 deletions(-)

diff --git a/apps/benchmarks/UniformGridCPU/UniformGridCPU.py b/apps/benchmarks/UniformGridCPU/UniformGridCPU.py
index f231da23c..cba55fac4 100644
--- a/apps/benchmarks/UniformGridCPU/UniformGridCPU.py
+++ b/apps/benchmarks/UniformGridCPU/UniformGridCPU.py
@@ -3,7 +3,6 @@ from dataclasses import replace
 import sympy as sp
 import pystencils as ps
 
-from pystencils.fast_approximation import insert_fast_divisions, insert_fast_sqrts
 from pystencils.simp.subexpression_insertion import insert_zeros, insert_aliases, insert_constants,\
     insert_symbol_times_minus_one
 
diff --git a/cmake/waLBerlaHelperFunctions.cmake b/cmake/waLBerlaHelperFunctions.cmake
index 56f67d248..c601d2d39 100644
--- a/cmake/waLBerlaHelperFunctions.cmake
+++ b/cmake/waLBerlaHelperFunctions.cmake
@@ -61,25 +61,23 @@ function( waLBerla_generate_target_from_python )
         list(APPEND generatedWithAbsolutePath ${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}/${filename})
     endforeach()
 
-    string (REPLACE ";" "\", \"" jsonFileList "${generatedWithAbsolutePath}" )
-    set(pythonParameters
-          "\\\{\"EXPECTED_FILES\": [\"${jsonFileList}\"], \"CMAKE_VARS\" : \\\{  "
-          "\"WALBERLA_OPTIMIZE_FOR_LOCALHOST\": \"${WALBERLA_OPTIMIZE_FOR_LOCALHOST}\","
-          "\"WALBERLA_DOUBLE_ACCURACY\": \"${WALBERLA_DOUBLE_ACCURACY}\","
-          "\"CODEGEN_CFG\": \"${codegenCfg}\","
-          "\"WALBERLA_BUILD_WITH_MPI\": \"${WALBERLA_BUILD_WITH_MPI}\","
-          "\"WALBERLA_BUILD_WITH_CUDA\": \"${WALBERLA_BUILD_WITH_CUDA}\","
-          "\"WALBERLA_BUILD_WITH_OPENMP\": \"${WALBERLA_BUILD_WITH_OPENMP}\" \\\} \\\}"
-          )
-    string(REPLACE "\"" "\\\"" pythonParameters ${pythonParameters})   # even one more quoting level required
-    string(REPLACE "\n" "" pythonParameters ${pythonParameters})  # remove newline characters
+    set(cmakeVars "\\\{  "
+            "\"WALBERLA_OPTIMIZE_FOR_LOCALHOST\": \"${WALBERLA_OPTIMIZE_FOR_LOCALHOST}\","
+            "\"WALBERLA_DOUBLE_ACCURACY\": \"${WALBERLA_DOUBLE_ACCURACY}\","
+            "\"CODEGEN_CFG\": \"${codegenCfg}\","
+            "\"WALBERLA_BUILD_WITH_MPI\": \"${WALBERLA_BUILD_WITH_MPI}\","
+            "\"WALBERLA_BUILD_WITH_CUDA\": \"${WALBERLA_BUILD_WITH_CUDA}\","
+            "\"WALBERLA_BUILD_WITH_OPENMP\": \"${WALBERLA_BUILD_WITH_OPENMP}\" \\\}"
+            )
+    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}
           DEPENDS ${sourceFile}
-          COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${WALBERLA_PYTHON_DIR}:$ENV{PYTHONPATH} ${Python_EXECUTABLE} ${sourceFile} ${pythonParameters}
+          COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${WALBERLA_PYTHON_DIR}:$ENV{PYTHONPATH} ${Python_EXECUTABLE} ${sourceFile} -f ${generatedWithAbsolutePath} -c ${cmakeVars}
           WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${codegenCfg}")
 
     add_library(${PYGEN_NAME} ${generatedWithAbsolutePath})
diff --git a/python/pystencils_walberla/cmake_integration.py b/python/pystencils_walberla/cmake_integration.py
index 14f25a172..2656cac32 100644
--- a/python/pystencils_walberla/cmake_integration.py
+++ b/python/pystencils_walberla/cmake_integration.py
@@ -9,19 +9,41 @@ Usage example:
     codegen.register(['MyClass.h', 'MyClass.cpp'], functionReturningTwoStringsForHeaderAndCpp)
 
 """
+import argparse
 import json
 import os
-import sys
-import warnings
 
 __all__ = ['CodeGeneration', 'ManualCodeGenerationContext']
 
+DEFAULT_CMAKE_VARS = {'WALBERLA_BUILD_WITH_OPENMP': False,
+                      'WALBERLA_OPTIMIZE_FOR_LOCALHOST': False,
+                      'WALBERLA_DOUBLE_ACCURACY': True,
+                      'WALBERLA_BUILD_WITH_MPI': True,
+                      'WALBERLA_BUILD_WITH_CUDA': False,
+                      "CODEGEN_CFG": ""}
+
+PARSE_HELPER = {"on":  True,  "1": True,  "yes": True,  "true":  True,
+                "off": False, "0": False, "no":  False, "false": False}
+
 
 class CodeGeneration:
     def __init__(self):
-        expected_files, cmake_vars = parse_json_args()
-        self.context = CodeGenerationContext(cmake_vars)
-        self.expected_files = expected_files
+        parser = argparse.ArgumentParser(description='Code Generation script for waLBerla.')
+        parser.add_argument('-f', '--files', nargs='*',
+                            help='List all files that will be generated with absolute path',
+                            default=[])
+        parser.add_argument('-c', '--cmake-args', type=json.loads,
+                            help='Provide CMake configuration (will be used in the codegen config)',
+                            default=DEFAULT_CMAKE_VARS)
+        parser.add_argument('-l', '--list-only',
+                            help="Script will not generate files but list files it would generated without this option")
+        args = parser.parse_args()
+
+        cmake_args = {key: PARSE_HELPER.get(str(value).lower(), value) for key, value in args.cmake_args.items()}
+
+        self.context = CodeGenerationContext(cmake_args)
+        self.expected_files = args.files
+        self.list_only = True if args.list_only else False
 
     def __enter__(self):
         return self.context
@@ -43,35 +65,6 @@ class CodeGeneration:
                 raise ValueError(error_message)
 
 
-def parse_json_args():
-    default = {'EXPECTED_FILES': [],
-               'CMAKE_VARS': {'WALBERLA_BUILD_WITH_OPENMP': False,
-                              'WALBERLA_OPTIMIZE_FOR_LOCALHOST': False,
-                              'WALBERLA_DOUBLE_ACCURACY': True,
-                              'WALBERLA_BUILD_WITH_MPI': True,
-                              'WALBERLA_BUILD_WITH_CUDA': False,
-                              "CODEGEN_CFG": ""}
-               }
-
-    if len(sys.argv) == 2:
-        try:
-            parsed = json.loads(sys.argv[1])
-        except json.JSONDecodeError:
-            warnings.warn("Could not parse JSON arguments: " + sys.argv[1])
-            parsed = default
-    else:
-        parsed = default
-    expected_files = parsed['EXPECTED_FILES']
-    cmake_vars = {}
-    for key, value in parsed['CMAKE_VARS'].items():
-        if str(value).lower() in ("on", "1", "yes", "true"):
-            value = True
-        elif str(value).lower() in ("off", "0", "no", "false"):
-            value = False
-        cmake_vars[key] = value
-    return expected_files, cmake_vars
-
-
 class CodeGenerationContext:
     def __init__(self, cmake_vars):
         self.files_written = []
-- 
GitLab