From c465376e0b746e15b6267ce015cc2d6e87d2d4f8 Mon Sep 17 00:00:00 2001
From: Henry <henry.korb@geo.uu.se>
Date: Thu, 15 Jun 2023 18:44:42 +0200
Subject: [PATCH] refactor Python bindings

---
 pythonbindings/CMakeLists.txt              | 79 +++++++++++++++++-----
 pythonbindings/src/basics/basics.cpp       |  8 +--
 pythonbindings/src/cpu/cpu.cpp             | 18 +++--
 pythonbindings/src/gpu/gpu.cpp             | 34 +++++-----
 pythonbindings/src/lbm/lbm.cpp             |  7 +-
 pythonbindings/src/{logger => }/logger.cpp | 24 +++----
 6 files changed, 102 insertions(+), 68 deletions(-)
 rename pythonbindings/src/{logger => }/logger.cpp (73%)

diff --git a/pythonbindings/CMakeLists.txt b/pythonbindings/CMakeLists.txt
index 037b68baf..c9bef9ef0 100644
--- a/pythonbindings/CMakeLists.txt
+++ b/pythonbindings/CMakeLists.txt
@@ -6,27 +6,78 @@ endif()
 
 project(VirtualFluidsPython LANGUAGES ${PYFLUIDS_LANGUAGES})
 
-pybind11_add_module(python_bindings MODULE src/VirtualFluids.cpp)
-target_compile_definitions(python_bindings PUBLIC VF_DOUBLE_ACCURACY)
+add_custom_target(python_bindings)
 
-set_target_properties(  python_bindings PROPERTIES
-                        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/pythonbindings/pyfluids
-                        OUTPUT_NAME "bindings")
+set(PYFLUIDS_DIR ${SKBUILD_PLATLIB_DIR}/pyfluids)
+set(PYMUPRASER_DIR ${SKBUILD_PLATLIB_DIR}/pymuparser)
+
+
+pybind11_add_module(basics_bindings MODULE src/basics/basics.cpp)
+set_target_properties(  basics_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "basics")
+target_link_libraries(basics_bindings PRIVATE basics)
+target_include_directories(basics_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(basics_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings basics_bindings)
+
+
+pybind11_add_module(logger_bindings MODULE src/logger.cpp)
+set_target_properties(  logger_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "logger")
+target_link_libraries(logger_bindings PRIVATE logger)
+target_include_directories(logger_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(logger_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings logger_bindings)
+
+
+pybind11_add_module(lbm_bindings MODULE src/lbm.cpp)
+set_target_properties(  lbm_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "lbm")
+target_link_libraries(lbm_bindings PRIVATE lbm)
+target_include_directories(lbm_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(lbm_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings lbm_bindings)
 
-target_link_libraries(python_bindings PRIVATE basics logger mpi lbm)
 
 IF(BUILD_VF_GPU)
-    set_source_files_properties(src/VirtualFluids.cpp PROPERTIES LANGUAGE CUDA)
+    pybind11_add_module(gpu_bindings MODULE src/gpu/gpu.cpp)
+    set_target_properties(  gpu_bindings PROPERTIES
+                            LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                            OUTPUT_NAME "gpu")
+    target_link_libraries(gpu_bindings PRIVATE basics)
+    set_source_files_properties(src/gpu/gpu.cpp PROPERTIES LANGUAGE CUDA)
+
+    target_include_directories(gpu_bindings PRIVATE ${VF_THIRD_DIR}/cuda_samples/)
 
-    target_include_directories(python_bindings PRIVATE ${VF_THIRD_DIR}/cuda_samples/)
-    target_compile_definitions(python_bindings PRIVATE VF_GPU_PYTHONBINDINGS)
+    target_link_libraries(gpu_bindings PRIVATE GridGenerator VirtualFluids_GPU)
+
+    target_include_directories(gpu_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+    target_include_directories(gpu_bindings PRIVATE ${CMAKE_BINARY_DIR})
+    add_dependencies(python_bindings gpu_bindings)
 
-    target_link_libraries(python_bindings PRIVATE GridGenerator VirtualFluids_GPU)
 ENDIF()
 
 IF(BUILD_VF_CPU)
-    target_compile_definitions(python_bindings PRIVATE VF_METIS VF_MPI VF_CPU_PYTHONBINDINGS)
-    target_link_libraries(python_bindings PRIVATE simulationconfig VirtualFluidsCore muparser)
+    pybind11_add_module(cpu_bindings MODULE src/cpu/cpu.cpp)
+    set_target_properties(  cpu_bindings PROPERTIES
+                            LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                            OUTPUT_NAME "cpu")
+    target_link_libraries(cpu_bindings PRIVATE simulationconfig VirtualFluidsCore muparser)
+
+    target_include_directories(cpu_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+    target_include_directories(cpu_bindings PRIVATE ${CMAKE_BINARY_DIR})
+
+    target_compile_definitions(cpu_bindings PUBLIC VF_DOUBLE_ACCURACY) # TODO: remove this and always set it dynamically
+    target_compile_definitions(basics_bindings PUBLIC VF_DOUBLE_ACCURACY)
+    target_compile_definitions(logger_bindings PUBLIC VF_DOUBLE_ACCURACY)
+    target_compile_definitions(lbm_bindings PUBLIC VF_DOUBLE_ACCURACY)
+
+    target_compile_definitions(cpu_bindings PRIVATE VF_METIS VF_MPI)
+    add_dependencies(python_bindings cpu_bindings)
+
 
     # include bindings for muparsers
     pybind11_add_module(pymuparser MODULE src/muParser.cpp)
@@ -40,7 +91,3 @@ IF(BUILD_VF_CPU)
     target_compile_definitions(pymuparser PRIVATE VF_METIS VF_MPI)
     target_link_libraries(pymuparser PRIVATE muparser)
 ENDIF()
-
-
-target_include_directories(python_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
-target_include_directories(python_bindings PRIVATE ${CMAKE_BINARY_DIR})
\ No newline at end of file
diff --git a/pythonbindings/src/basics/basics.cpp b/pythonbindings/src/basics/basics.cpp
index 0b294b7a8..126d8614e 100644
--- a/pythonbindings/src/basics/basics.cpp
+++ b/pythonbindings/src/basics/basics.cpp
@@ -37,12 +37,8 @@ namespace basics
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(basics, m)
     {
-        py::module basicsModule = parentModule.def_submodule("basics");
-
-        configuration::makeModule(basicsModule);
-
-        return basicsModule;
+        configuration::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/cpu/cpu.cpp b/pythonbindings/src/cpu/cpu.cpp
index 75143d913..baced0fc1 100644
--- a/pythonbindings/src/cpu/cpu.cpp
+++ b/pythonbindings/src/cpu/cpu.cpp
@@ -38,18 +38,16 @@
 #include "submodules/simulationparameters.cpp"
 #include "submodules/writer.cpp"
 
-namespace cpu
+namespace cpu_bindings
 {
     namespace py = pybind11;
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(cpu, m)
     {
-        py::module cpuModule = parentModule.def_submodule("cpu");
-        boundaryconditions::makeModule(cpuModule);
-        simulation::makeModule(cpuModule);
-        geometry::makeModule(cpuModule);
-        kernel::makeModule(cpuModule);
-        parameters::makeModule(cpuModule);
-        writer::makeModule(cpuModule);
-        return cpuModule;
+        boundaryconditions::makeModule(m);
+        simulation::makeModule(m);
+        geometry::makeModule(m);
+        kernel::makeModule(m);
+        parameters::makeModule(m);
+        writer::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/gpu/gpu.cpp b/pythonbindings/src/gpu/gpu.cpp
index 9eb160ae7..8946b1d8a 100644
--- a/pythonbindings/src/gpu/gpu.cpp
+++ b/pythonbindings/src/gpu/gpu.cpp
@@ -46,27 +46,25 @@
 #include "submodules/actuator_farm.cpp"
 #include "submodules/grid_scaling_factory.cpp"
 
-namespace gpu
+namespace gpu_bindings
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(gpu, m)
     {
-        py::module gpuModule = parentModule.def_submodule("gpu");
-        simulation::makeModule(gpuModule);
-        parameter::makeModule(gpuModule);
-        pre_collision_interactor::makeModule(gpuModule);
-        actuator_farm::makeModule(gpuModule);
-        boundary_conditions::makeModule(gpuModule);
-        transient_bc_setter::makeModule(gpuModule);
-        communicator::makeModule(gpuModule); 
-        cuda_memory_manager::makeModule(gpuModule);
-        probes::makeModule(gpuModule);
-        precursor_writer::makeModule(gpuModule);
-        grid_generator::makeModule(gpuModule);
-        grid_provider::makeModule(gpuModule);
-        turbulence_model::makeModule(gpuModule);
-        grid_scaling_factory::makeModule(gpuModule);
-        return gpuModule;
+        simulation::makeModule(m);
+        parameter::makeModule(m);
+        pre_collision_interactor::makeModule(m);
+        actuator_farm::makeModule(m);
+        boundary_conditions::makeModule(m);
+        transient_bc_setter::makeModule(m);
+        communicator::makeModule(m); 
+        cuda_memory_manager::makeModule(m);
+        probes::makeModule(m);
+        precursor_writer::makeModule(m);
+        grid_generator::makeModule(m);
+        grid_provider::makeModule(m);
+        turbulence_model::makeModule(m);
+        grid_scaling_factory::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/lbm/lbm.cpp b/pythonbindings/src/lbm/lbm.cpp
index 90fd4a71b..622cc9742 100644
--- a/pythonbindings/src/lbm/lbm.cpp
+++ b/pythonbindings/src/lbm/lbm.cpp
@@ -32,14 +32,11 @@
 //=======================================================================================
 #include <pybind11/pybind11.h>
 
-namespace lbm
+namespace lbm_bindings
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(lbm, m)
     {
-        py::module lbmModule = parentModule.def_submodule("lbm");
-
-        return lbmModule;
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/logger/logger.cpp b/pythonbindings/src/logger.cpp
similarity index 73%
rename from pythonbindings/src/logger/logger.cpp
rename to pythonbindings/src/logger.cpp
index c4c99c0a5..367ae6934 100644
--- a/pythonbindings/src/logger/logger.cpp
+++ b/pythonbindings/src/logger.cpp
@@ -33,25 +33,23 @@
 #include <pybind11/pybind11.h>
 #include <logger/Logger.h>
 
-namespace logging
+namespace logger_bindings
 {
+
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(logger, m)
     {
-        py::module loggerModule = parentModule.def_submodule("logger");
-
-        py::class_<vf::logging::Logger>(loggerModule, "Logger")
+        py::class_<vf::logging::Logger>(m, "Logger")
         .def_static("initialize_logger", &vf::logging::Logger::initializeLogger)
         .def_static("change_log_path", &vf::logging::Logger::changeLogPath, py::arg("path"));
 
         // use f-strings (f"text {float}") in python for compounded messages
-        loggerModule.def("vf_log_trace", [](std::string message){ VF_LOG_TRACE(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_debug", [](std::string message){ VF_LOG_DEBUG(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_info", [](std::string message){ VF_LOG_INFO(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_warning", [](std::string message){ VF_LOG_WARNING(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_critical", [](std::string message){ VF_LOG_CRITICAL(message); }, py::arg("message"));        
-
-        return loggerModule;
+        m.def("vf_log_trace", [](std::string message){ VF_LOG_TRACE(message); }, py::arg("message"));        
+        m.def("vf_log_debug", [](std::string message){ VF_LOG_DEBUG(message); }, py::arg("message"));        
+        m.def("vf_log_info", [](std::string message){ VF_LOG_INFO(message); }, py::arg("message"));        
+        m.def("vf_log_warning", [](std::string message){ VF_LOG_WARNING(message); }, py::arg("message"));        
+        m.def("vf_log_critical", [](std::string message){ VF_LOG_CRITICAL(message); }, py::arg("message"));       
     }
-} // namespace logging
+}
+
-- 
GitLab