diff --git a/CMakeLists.txt b/CMakeLists.txt index f9e705726123ca02a17edeab80e8f9ebe52c6ecb..5a7a53f0ee7e5181f346853fdb8e0616a8bc4b54 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 70dd9bb4285bca1dea8f12f657581df8bb1c0379..d123706a2914a702ec849cef4e57ae8da97ea2ad 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 207c433230b72df39c1927664e7878c010cb896f..0120b23a0c5f4a0a4246ccafcc5d3ffa1d930572 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 863d49eb13c812721d96b5541d14654f7247888e..cfdc946bcb889212b36a500a8c46d071ffbeb5da 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 d041f1b19a67df5da2107d4563c5b3b560b2d6f5..bce5c1d136129c8de6d400f5e88e9085c7638834 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 13e422d94cf2329d339a23077a51a13553928652..1b8d2021d8381bf8d5cf8a8430f8e2d33d177779 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 a79d133f4381deea94d06e96ff57c33531e73e26..07d037d7708a7ea94a6b520f02eb6a77a037b329 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 e47cae2e1bef502e62a8b64dd2dea7f9fa396151..8401480e24c54fcabb7a0ddca0762b32c56a74fc 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 3e21d3e157882b198cb7099828e15beade497ac6..dc8b9295f23c3c71d92a6d60bf6c30424d08ba31 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 cd3e7af346973a31ce122c55531821489e74ce14..a47e511dc3dfcd129c09b81c7f1322e0c3e54221 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 6ec9191dc263b3eee1015fa00433cbc1987a71a1..d973f8a173863aa58081f49ac47ab0c23e0c0866 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 )