From 973942790e12e43b467c8e87da112fffd53f4380 Mon Sep 17 00:00:00 2001 From: Frederik Hennig <frederik.hennig@fau.de> Date: Wed, 5 Mar 2025 13:53:23 +0100 Subject: [PATCH] adapt to latest walberla and pystencils-sfg revisions --- CMakeLists.txt | 11 +-- cmake/codegen-requirements.txt | 4 +- src/sfg_walberla/api.py | 75 ++++++++++--------- src/sfg_walberla/boundaries/freeslip.py | 8 +- src/sfg_walberla/boundaries/hbb.py | 5 +- src/sfg_walberla/reflection.py | 9 +-- src/sfg_walberla/sweep.py | 43 +++++------ tests/FreeSlip/CMakeLists.txt | 2 +- .../ForceDrivenChannel/CMakeLists.txt | 2 +- .../examples/FreeSlipBubble/CMakeLists.txt | 2 +- .../examples/SparseSpiral/CMakeLists.txt | 2 +- 11 files changed, 79 insertions(+), 84 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e7057..5a7a53f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,19 +7,20 @@ list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ) include( PrepareSFG ) -add_library( sfg_walberla INTERFACE ) +add_library( walberla_codegen INTERFACE ) +add_library( walberla::codegen ALIAS walberla_codegen ) -target_sources( sfg_walberla +target_sources( walberla_codegen INTERFACE include/sfg/SparseIteration.hpp include/sfg/GenericHbbBoundary.hpp include/sfg/IrregularFreeSlip.hpp ) -target_include_directories( sfg_walberla INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include ) +target_include_directories( walberla_codegen INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries( - sfg_walberla + walberla_codegen INTERFACE - core stencil domain_decomposition blockforest field + walberla::core walberla::stencil walberla::domain_decomposition walberla::blockforest walberla::field ) diff --git a/cmake/codegen-requirements.txt b/cmake/codegen-requirements.txt index 70dd9bb..d123706 100644 --- a/cmake/codegen-requirements.txt +++ b/cmake/codegen-requirements.txt @@ -4,5 +4,5 @@ git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev # lbmpy: feature branch for pystencils-2.0 compatibility git+https://i10git.cs.fau.de/pycodegen/lbmpy.git@fhennig/pystencils2.0-compat -# pystencils-sfg: (development branch with updated CMake modules and cpptypes) -git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@e467692fe48479ba2867d7a2e753e6be7dea4132 +# pystencils-sfg: latest supported revision +git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@8949bedba3a8704dff520580202fc273fb0202de diff --git a/src/sfg_walberla/api.py b/src/sfg_walberla/api.py index 207c433..0120b23 100644 --- a/src/sfg_walberla/api.py +++ b/src/sfg_walberla/api.py @@ -12,10 +12,9 @@ from pystencils.types import ( PsStructType, ) from pystencilssfg.lang import ( - IFieldExtraction, AugExpr, - SrcField, - SrcVector, + SupportsFieldExtraction, + SupportsVectorExtraction, Ref, ExprLike, cpptype, @@ -38,7 +37,7 @@ class _PlainCppClass(AugExpr): super().__init__(dtype) -class Vector2(SrcVector): +class Vector2(AugExpr, SupportsVectorExtraction): _template = cpptype("walberla::Vector2< {element_type} >", "core/math/Vector2.h") def __init__( @@ -48,14 +47,14 @@ class Vector2(SrcVector): dtype = self._template(element_type=element_type, const=const, ref=ref) super().__init__(dtype) - def extract_component(self, coordinate: int) -> AugExpr: + def _extract_component(self, coordinate: int) -> AugExpr: if coordinate > 1: raise ValueError(f"Cannot extract component {coordinate} from Vector2") return AugExpr(self._element_type).bind("{}[{}]", self, coordinate) -class Vector3(SrcVector): +class Vector3(AugExpr, SupportsVectorExtraction): _template = cpptype("walberla::Vector3< {element_type} >", "core/math/Vector3.h") def __init__( @@ -65,7 +64,7 @@ class Vector3(SrcVector): dtype = self._template(element_type=element_type, const=const, ref=ref) super().__init__(dtype) - def extract_component(self, coordinate: int) -> AugExpr: + def _extract_component(self, coordinate: int) -> AugExpr: if coordinate > 2: raise ValueError(f"Cannot extract component {coordinate} from Vector3") @@ -184,7 +183,7 @@ class StructuredBlockForest(AugExpr): return AugExpr(uint_t).bind("{}.getLevel({})", self, block) -class GenericWalberlaField(SrcField): +class GenericWalberlaField(AugExpr, SupportsFieldExtraction): """Common base class for GhostLayerField and GpuField defining their shared interface.""" def __init__( @@ -209,6 +208,8 @@ class GenericWalberlaField(SrcField): super().__init__(obj_type) + self._extraction = GhostLayerFieldExtraction(self, None) + @property def _a(self) -> AugExpr: """Member access""" @@ -221,10 +222,16 @@ class GenericWalberlaField(SrcField): def field_type(self) -> PsCustomType: return self._field_type - def get_extraction(self) -> IFieldExtraction: - return GhostLayerFieldExtraction(self, None) + def _extract_ptr(self) -> AugExpr: + return self._extraction._extract_ptr() + + def _extract_size(self, coordinate: int) -> AugExpr | None: + return self._extraction._extract_size(coordinate) - def with_cell_interval(self, ci: CellInterval | None): + def _extract_stride(self, coordinate: int) -> AugExpr | None: + return self._extraction._extract_stride(coordinate) + + def with_cell_interval(self, ci: CellInterval | None) -> GhostLayerFieldExtraction: return GhostLayerFieldExtraction(self, ci) def cloneUninitialized(self) -> AugExpr: @@ -292,7 +299,7 @@ class GpuFieldPtr(GenericWalberlaField): super().__init__(element_type, field_type, ptr=True) -class GhostLayerFieldExtraction(IFieldExtraction): +class GhostLayerFieldExtraction(SupportsFieldExtraction): def __init__( self, field_ptr: AugExpr, @@ -301,7 +308,7 @@ class GhostLayerFieldExtraction(IFieldExtraction): self._field_ptr = field_ptr self._ci = cell_interval - def ptr(self) -> AugExpr: + def _extract_ptr(self) -> AugExpr: data_at: AugExpr | str if self._ci is not None: ci = self._ci @@ -311,7 +318,7 @@ class GhostLayerFieldExtraction(IFieldExtraction): return AugExpr.format("{}->dataAt({})", self._field_ptr, data_at) - def size(self, coordinate: int) -> AugExpr | None: + def _extract_size(self, coordinate: int) -> AugExpr | None: size_call = ["xSize()", "ySize()", "zSize()", "fSize()"][coordinate] if self._ci is not None and coordinate < 3: @@ -319,7 +326,7 @@ class GhostLayerFieldExtraction(IFieldExtraction): else: return AugExpr.format("{}->{}", self._field_ptr, size_call) - def stride(self, coordinate: int) -> AugExpr | None: + def _extract_stride(self, coordinate: int) -> AugExpr | None: stride_call = ("xStride()", "yStride()", "zStride()", "fStride()")[coordinate] return AugExpr.format("{}->{}", self._field_ptr, stride_call) @@ -352,7 +359,7 @@ class SparseIndexList(AugExpr): return BlockDataID().bind("{}.bufferId()", self) -class IndexListBufferPtr(SrcField): +class IndexListBufferPtr(AugExpr, SupportsFieldExtraction): _template = cpptype( "walberla::sfg::internal::IndexListBuffer< {IndexStruct} >", "sfg/SparseIteration.hpp", @@ -374,26 +381,22 @@ class IndexListBufferPtr(SrcField): def vector(self) -> AugExpr: return AugExpr().format("{}->vector()", self) - def get_extraction(self) -> IFieldExtraction: - class IdxVectorExtraction(IFieldExtraction): - def ptr(_) -> AugExpr: - return self.pointerCpu() - - def size(_, coordinate: int) -> AugExpr | None: - if coordinate == 0: - return AugExpr.format("{}.size()", self.vector()) - elif coordinate == 1: - return AugExpr.format("1") - else: - raise ValueError() - - def stride(_, coordinate: int) -> AugExpr | None: - if coordinate <= 1: - return AugExpr.format("1") - else: - raise ValueError() - - return IdxVectorExtraction() + def _extract_ptr(self) -> AugExpr: + return self.pointerCpu() + + def _extract_size(self, coordinate: int) -> AugExpr | None: + if coordinate == 0: + return AugExpr.format("{}.size()", self.vector()) + elif coordinate == 1: + return AugExpr.format("1") + else: + raise ValueError() + + def _extract_stride(self, coordinate: int) -> AugExpr | None: + if coordinate <= 1: + return AugExpr.format("1") + else: + raise ValueError() CellIdx = PsStructType( diff --git a/src/sfg_walberla/boundaries/freeslip.py b/src/sfg_walberla/boundaries/freeslip.py index 863d49e..cfdc946 100644 --- a/src/sfg_walberla/boundaries/freeslip.py +++ b/src/sfg_walberla/boundaries/freeslip.py @@ -91,9 +91,11 @@ class FreeSlip(CustomGenerator): sfg.private( sfg.method( "irregularFromIndexVector", - returns=sweep_type.get_dtype(), - inline=True, - )(sfg.expr("return {};", sweep_type.ctor(**sweep_ctor_args))), + ) + .returns(sweep_type.get_dtype()) + .inline()( + sfg.expr("return {};", sweep_type.ctor(**sweep_ctor_args)) + ), ), ) diff --git a/src/sfg_walberla/boundaries/hbb.py b/src/sfg_walberla/boundaries/hbb.py index d041f1b..bce5c1d 100644 --- a/src/sfg_walberla/boundaries/hbb.py +++ b/src/sfg_walberla/boundaries/hbb.py @@ -1,15 +1,12 @@ """Code generation for half-way bounce-back LBM boundary conditions in waLBerla""" -from pystencils import Field, FieldType, TypedSymbol, Target, AssignmentCollection, DynamicType - -from pystencils.types import PsStructType, create_type +from pystencils import Field, FieldType, TypedSymbol, Target, AssignmentCollection from pystencilssfg import SfgComposer from pystencilssfg.composer.class_composer import SfgClassComposer from pystencilssfg.composer.custom import CustomGenerator from pystencilssfg.lang import AugExpr -from lbmpy import LBStencil from lbmpy.methods import AbstractLbMethod from lbmpy.boundaries.boundaryconditions import LbBoundary from lbmpy.advanced_streaming.indexing import Timestep diff --git a/src/sfg_walberla/reflection.py b/src/sfg_walberla/reflection.py index 13e422d..1b8d202 100644 --- a/src/sfg_walberla/reflection.py +++ b/src/sfg_walberla/reflection.py @@ -5,14 +5,9 @@ from pystencilssfg.ir import SfgClass class GeneratedClassWrapperBase(CppClass): _class: SfgClass - _namespace: str | None def __init_subclass__(cls) -> None: - typename = ( - f"{cls._namespace}::{cls._class.class_name}" - if cls._namespace is not None - else cls._class.class_name - ) + typename = cls._class.fqname cls.template = cpptype(typename) def ctor(self, **kwargs) -> AugExpr: @@ -22,7 +17,7 @@ class GeneratedClassWrapperBase(CppClass): break else: raise Exception( - f"No constructor of class {self._class.class_name} matches the argument names {kwargs.keys()}" + f"No constructor of class {self._class.fqname} matches the argument names {kwargs.keys()}" ) ctor_args = [kwargs[name] for name in ctor_argnames] diff --git a/src/sfg_walberla/sweep.py b/src/sfg_walberla/sweep.py index a79d133..07d037d 100644 --- a/src/sfg_walberla/sweep.py +++ b/src/sfg_walberla/sweep.py @@ -28,10 +28,9 @@ from pystencilssfg.lang import ( SfgVar, AugExpr, Ref, - SrcVector, strip_ptr_ref, + SupportsVectorExtraction, ) -from pystencilssfg.lang.types import CppTypeFactory, cpptype from .reflection import GeneratedClassWrapperBase from .api import ( StructuredBlockForest, @@ -74,22 +73,19 @@ class SweepClassProperties: if self.getter: methods.append( - sfg.method( - f"{self.name}", - returns=Ref(constify(self.dtype)), - const=True, - inline=True, - )(f"return {self.name}_;") + sfg.method(f"{self.name}") + .returns(Ref(constify(self.dtype))) + .const() + .inline()(f"return {self.name}_;") ) if self.setter: methods.append( - sfg.method( - f"{self.name}", - returns=Ref(self.dtype), - const=False, - inline=True, - )(f"return {self.name}_;") + sfg.method(f"{self.name}") + .returns(Ref(self.dtype)) + .inline()( + f"return {self.name}_;" + ) ) return methods @@ -325,11 +321,9 @@ class ShadowFieldCache: cache_ptrs.append(sfg.var(cache_ptr_name, unique_ptr_type)) getters.append( - sfg.method( - self._getter(orig_name), - returns=orig.wlb_field_ptr.get_dtype(), - inline=True, - )( + sfg.method(self._getter(orig_name)) + .returns(orig.wlb_field_ptr.get_dtype()) + .inline()( sfg.branch(f"{cache_ptr_name} == nullptr")( AugExpr.format( "{}.reset({});", @@ -350,7 +344,9 @@ class ShadowFieldCache: return f"shadow_{str(orig)}_" -def combine_vectors(scalars: set[SfgVar]) -> dict[SrcVector, tuple[SfgVar, ...]]: +def combine_vectors( + scalars: set[SfgVar], +) -> dict[SupportsVectorExtraction, tuple[SfgVar, ...]]: """Attempt to combine vector component symbols into vectors. This function modifies the `scalars` parameter in-place by removing grouped scalar @@ -367,7 +363,7 @@ def combine_vectors(scalars: set[SfgVar]) -> dict[SrcVector, tuple[SfgVar, ...]] except ValueError: pass - all_vectors: dict[SrcVector, tuple[SfgVar, ...]] = dict() + all_vectors: dict[SupportsVectorExtraction, tuple[SfgVar, ...]] = dict() for name, entries in potential_vectors.items(): entries = sorted(entries, key=lambda t: t[0]) @@ -618,12 +614,13 @@ class Sweep(CustomGenerator): *shadows_cache.render(sfg), ) - gen_class = sfg.context.get_class(self._name) + gen_class = sfg._cursor.get_entity(self._name) assert gen_class is not None + from pystencilssfg.ir.entities import SfgClass + assert isinstance(gen_class, SfgClass) class GenClassWrapper(GeneratedClassWrapperBase): _class = gen_class - _namespace = sfg.context.fully_qualified_namespace self._generated_class = GenClassWrapper diff --git a/tests/FreeSlip/CMakeLists.txt b/tests/FreeSlip/CMakeLists.txt index e47cae2..8401480 100644 --- a/tests/FreeSlip/CMakeLists.txt +++ b/tests/FreeSlip/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable( TestIrregularFreeSlip TestIrregularFreeSlip.cpp ) walberla_generate_sources( TestIrregularFreeSlip SCRIPTS IrregularFreeSlip.py ) -target_link_libraries( TestIrregularFreeSlip core blockforest field geometry sfg_walberla ) +target_link_libraries( TestIrregularFreeSlip PRIVATE walberla::core walberla::blockforest walberla::field walberla::geometry walberla::codegen ) add_test( NAME TestIrregularFreeSlip COMMAND TestIrregularFreeSlip ) add_dependencies( SfgTests TestIrregularFreeSlip ) diff --git a/user_manual/examples/ForceDrivenChannel/CMakeLists.txt b/user_manual/examples/ForceDrivenChannel/CMakeLists.txt index 3e21d3e..dc8b929 100644 --- a/user_manual/examples/ForceDrivenChannel/CMakeLists.txt +++ b/user_manual/examples/ForceDrivenChannel/CMakeLists.txt @@ -10,5 +10,5 @@ walberla_generate_sources( Ex_ForceDrivenChannel target_link_libraries( Ex_ForceDrivenChannel PRIVATE - core stencil blockforest geometry vtk sfg_walberla + walberla::core walberla::stencil walberla::blockforest walberla::geometry walberla::vtk walberla::codegen ) diff --git a/user_manual/examples/FreeSlipBubble/CMakeLists.txt b/user_manual/examples/FreeSlipBubble/CMakeLists.txt index cd3e7af..a47e511 100644 --- a/user_manual/examples/FreeSlipBubble/CMakeLists.txt +++ b/user_manual/examples/FreeSlipBubble/CMakeLists.txt @@ -3,4 +3,4 @@ walberla_link_files_to_builddir( *.prm ) add_executable( FreeSlipBubble FreeSlipBubble.cpp ) walberla_generate_sources( FreeSlipBubble SCRIPTS LbmAlgorithms.py ) -target_link_libraries( FreeSlipBubble core blockforest field geometry stencil sfg_walberla ) +target_link_libraries( FreeSlipBubble walberla::core walberla::blockforest walberla::field walberla::geometry walberla::stencil walberla::codegen ) diff --git a/user_manual/examples/SparseSpiral/CMakeLists.txt b/user_manual/examples/SparseSpiral/CMakeLists.txt index 6ec9191..d973f8a 100644 --- a/user_manual/examples/SparseSpiral/CMakeLists.txt +++ b/user_manual/examples/SparseSpiral/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable( SparseSpiral SparseSpiral.cpp ) walberla_generate_sources( SparseSpiral SCRIPTS SpiralSweep.py ) -target_link_libraries( SparseSpiral PRIVATE core blockforest field vtk sfg_walberla ) +target_link_libraries( SparseSpiral PRIVATE walberla::core walberla::blockforest walberla::field walberla::vtk walberla::codegen ) -- GitLab