Skip to content
Snippets Groups Projects
Commit 68acb242 authored by Michael Kuron's avatar Michael Kuron :mortar_board:
Browse files

introduce field.FieldType.STAGGERED

parent 23de3441
Branches
Tags
1 merge request!86Staggered field access and staggered fields with fluxes to edges/faces
Pipeline #19815 passed
...@@ -3,7 +3,7 @@ from typing import Callable, Dict, Iterable, Optional, Sequence, Tuple, Union ...@@ -3,7 +3,7 @@ from typing import Callable, Dict, Iterable, Optional, Sequence, Tuple, Union
import numpy as np import numpy as np
from pystencils.field import Field from pystencils.field import Field, FieldType
class DataHandling(ABC): class DataHandling(ABC):
...@@ -36,7 +36,7 @@ class DataHandling(ABC): ...@@ -36,7 +36,7 @@ class DataHandling(ABC):
@abstractmethod @abstractmethod
def add_array(self, name: str, values_per_cell, dtype=np.float64, def add_array(self, name: str, values_per_cell, dtype=np.float64,
latex_name: Optional[str] = None, ghost_layers: Optional[int] = None, layout: Optional[str] = None, latex_name: Optional[str] = None, ghost_layers: Optional[int] = None, layout: Optional[str] = None,
cpu: bool = True, gpu: Optional[bool] = None, alignment=False, staggered=False) -> Field: cpu: bool = True, gpu: Optional[bool] = None, alignment=False, field_type=FieldType.GENERIC) -> Field:
"""Adds a (possibly distributed) array to the handling that can be accessed using the given name. """Adds a (possibly distributed) array to the handling that can be accessed using the given name.
For each array a symbolic field is available via the 'fields' dictionary For each array a symbolic field is available via the 'fields' dictionary
......
...@@ -7,7 +7,7 @@ import waLBerla as wlb ...@@ -7,7 +7,7 @@ import waLBerla as wlb
from pystencils.datahandling.blockiteration import block_iteration, sliced_block_iteration from pystencils.datahandling.blockiteration import block_iteration, sliced_block_iteration
from pystencils.datahandling.datahandling_interface import DataHandling from pystencils.datahandling.datahandling_interface import DataHandling
from pystencils.field import Field from pystencils.field import Field, FieldType
from pystencils.kernelparameters import FieldPointerSymbol from pystencils.kernelparameters import FieldPointerSymbol
from pystencils.utils import DotDict from pystencils.utils import DotDict
...@@ -90,7 +90,7 @@ class ParallelDataHandling(DataHandling): ...@@ -90,7 +90,7 @@ class ParallelDataHandling(DataHandling):
self._custom_data_names.append(name) self._custom_data_names.append(name)
def add_array(self, name, values_per_cell=1, dtype=np.float64, latex_name=None, ghost_layers=None, def add_array(self, name, values_per_cell=1, dtype=np.float64, latex_name=None, ghost_layers=None,
layout=None, cpu=True, gpu=None, alignment=False, staggered=False): layout=None, cpu=True, gpu=None, alignment=False, field_type=FieldType.GENERIC):
if ghost_layers is None: if ghost_layers is None:
ghost_layers = self.default_ghost_layers ghost_layers = self.default_ghost_layers
if gpu is None: if gpu is None:
...@@ -141,7 +141,7 @@ class ParallelDataHandling(DataHandling): ...@@ -141,7 +141,7 @@ class ParallelDataHandling(DataHandling):
self.fields[name] = Field.create_generic(name, self.dim, dtype, index_dimensions, layout, self.fields[name] = Field.create_generic(name, self.dim, dtype, index_dimensions, layout,
index_shape=(values_per_cell,) if index_dimensions > 0 else None, index_shape=(values_per_cell,) if index_dimensions > 0 else None,
staggered=staggered) field_type=field_type)
self.fields[name].latex_name = latex_name self.fields[name].latex_name = latex_name
self._field_name_to_cpu_data_name[name] = name self._field_name_to_cpu_data_name[name] = name
if gpu: if gpu:
......
...@@ -7,7 +7,7 @@ import numpy as np ...@@ -7,7 +7,7 @@ import numpy as np
from pystencils.datahandling.blockiteration import SerialBlock from pystencils.datahandling.blockiteration import SerialBlock
from pystencils.datahandling.datahandling_interface import DataHandling from pystencils.datahandling.datahandling_interface import DataHandling
from pystencils.field import ( from pystencils.field import (
Field, create_numpy_array_with_layout, layout_string_to_tuple, spatial_layout_string_to_tuple) Field, FieldType, create_numpy_array_with_layout, layout_string_to_tuple, spatial_layout_string_to_tuple)
from pystencils.slicing import normalize_slice, remove_ghost_layers from pystencils.slicing import normalize_slice, remove_ghost_layers
from pystencils.utils import DotDict from pystencils.utils import DotDict
...@@ -76,7 +76,7 @@ class SerialDataHandling(DataHandling): ...@@ -76,7 +76,7 @@ class SerialDataHandling(DataHandling):
return self._field_information[name]['values_per_cell'] return self._field_information[name]['values_per_cell']
def add_array(self, name, values_per_cell=1, dtype=np.float64, latex_name=None, ghost_layers=None, layout=None, def add_array(self, name, values_per_cell=1, dtype=np.float64, latex_name=None, ghost_layers=None, layout=None,
cpu=True, gpu=None, alignment=False, staggered=False): cpu=True, gpu=None, alignment=False, field_type=FieldType.GENERIC):
if ghost_layers is None: if ghost_layers is None:
ghost_layers = self.default_ghost_layers ghost_layers = self.default_ghost_layers
if layout is None: if layout is None:
...@@ -129,7 +129,7 @@ class SerialDataHandling(DataHandling): ...@@ -129,7 +129,7 @@ class SerialDataHandling(DataHandling):
assert all(f.name != name for f in self.fields.values()), "Symbolic field with this name already exists" assert all(f.name != name for f in self.fields.values()), "Symbolic field with this name already exists"
self.fields[name] = Field.create_from_numpy_array(name, cpu_arr, index_dimensions=index_dimensions, self.fields[name] = Field.create_from_numpy_array(name, cpu_arr, index_dimensions=index_dimensions,
staggered=staggered) field_type=field_type)
self.fields[name].latex_name = latex_name self.fields[name].latex_name = latex_name
return self.fields[name] return self.fields[name]
......
...@@ -21,7 +21,47 @@ from pystencils.sympyextensions import is_integer_sequence ...@@ -21,7 +21,47 @@ from pystencils.sympyextensions import is_integer_sequence
__all__ = ['Field', 'fields', 'FieldType', 'AbstractField'] __all__ = ['Field', 'fields', 'FieldType', 'AbstractField']
def fields(description=None, index_dimensions=0, layout=None, staggered=False, **kwargs): class FieldType(Enum):
# generic fields
GENERIC = 0
# index fields are currently only used for boundary handling
# the coordinates are not the loop counters in that case, but are read from this index field
INDEXED = 1
# communication buffer, used for (un)packing data in communication.
BUFFER = 2
# unsafe fields may be accessed in an absolute fashion - the index depends on the data
# and thus may lead to out-of-bounds accesses
CUSTOM = 3
# staggered field
STAGGERED = 4
@staticmethod
def is_generic(field):
assert isinstance(field, Field)
return field.field_type == FieldType.GENERIC
@staticmethod
def is_indexed(field):
assert isinstance(field, Field)
return field.field_type == FieldType.INDEXED
@staticmethod
def is_buffer(field):
assert isinstance(field, Field)
return field.field_type == FieldType.BUFFER
@staticmethod
def is_custom(field):
assert isinstance(field, Field)
return field.field_type == FieldType.CUSTOM
@staticmethod
def is_staggered(field):
assert isinstance(field, Field)
return field.field_type == FieldType.STAGGERED
def fields(description=None, index_dimensions=0, layout=None, field_type=FieldType.GENERIC, **kwargs):
"""Creates pystencils fields from a string description. """Creates pystencils fields from a string description.
Examples: Examples:
...@@ -62,16 +102,16 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, * ...@@ -62,16 +102,16 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, *
idx_shape_of_arr = () if not len(idx_shape) else arr.shape[-len(idx_shape):] idx_shape_of_arr = () if not len(idx_shape) else arr.shape[-len(idx_shape):]
assert idx_shape_of_arr == idx_shape assert idx_shape_of_arr == idx_shape
f = Field.create_from_numpy_array(field_name, kwargs[field_name], index_dimensions=len(idx_shape), f = Field.create_from_numpy_array(field_name, kwargs[field_name], index_dimensions=len(idx_shape),
staggered=staggered) field_type=field_type)
elif isinstance(shape, tuple): elif isinstance(shape, tuple):
f = Field.create_fixed_size(field_name, shape + idx_shape, dtype=dtype, f = Field.create_fixed_size(field_name, shape + idx_shape, dtype=dtype,
index_dimensions=len(idx_shape), layout=layout, staggered=staggered) index_dimensions=len(idx_shape), layout=layout, field_type=field_type)
elif isinstance(shape, int): elif isinstance(shape, int):
f = Field.create_generic(field_name, spatial_dimensions=shape, dtype=dtype, f = Field.create_generic(field_name, spatial_dimensions=shape, dtype=dtype,
index_shape=idx_shape, layout=layout, staggered=staggered) index_shape=idx_shape, layout=layout, field_type=field_type)
elif shape is None: elif shape is None:
f = Field.create_generic(field_name, spatial_dimensions=2, dtype=dtype, f = Field.create_generic(field_name, spatial_dimensions=2, dtype=dtype,
index_shape=idx_shape, layout=layout, staggered=staggered) index_shape=idx_shape, layout=layout, field_type=field_type)
else: else:
assert False assert False
result.append(f) result.append(f)
...@@ -79,7 +119,7 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, * ...@@ -79,7 +119,7 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, *
assert layout is None, "Layout can not be specified when creating Field from numpy array" assert layout is None, "Layout can not be specified when creating Field from numpy array"
for field_name, arr in kwargs.items(): for field_name, arr in kwargs.items():
result.append(Field.create_from_numpy_array(field_name, arr, index_dimensions=index_dimensions, result.append(Field.create_from_numpy_array(field_name, arr, index_dimensions=index_dimensions,
staggered=staggered)) field_type=field_type))
if len(result) == 0: if len(result) == 0:
return None return None
...@@ -89,39 +129,6 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, * ...@@ -89,39 +129,6 @@ def fields(description=None, index_dimensions=0, layout=None, staggered=False, *
return result return result
class FieldType(Enum):
# generic fields
GENERIC = 0
# index fields are currently only used for boundary handling
# the coordinates are not the loop counters in that case, but are read from this index field
INDEXED = 1
# communication buffer, used for (un)packing data in communication.
BUFFER = 2
# unsafe fields may be accessed in an absolute fashion - the index depends on the data
# and thus may lead to out-of-bounds accesses
CUSTOM = 3
@staticmethod
def is_generic(field):
assert isinstance(field, Field)
return field.field_type == FieldType.GENERIC
@staticmethod
def is_indexed(field):
assert isinstance(field, Field)
return field.field_type == FieldType.INDEXED
@staticmethod
def is_buffer(field):
assert isinstance(field, Field)
return field.field_type == FieldType.BUFFER
@staticmethod
def is_custom(field):
assert isinstance(field, Field)
return field.field_type == FieldType.CUSTOM
class AbstractField: class AbstractField:
class AbstractAccess: class AbstractAccess:
...@@ -182,7 +189,7 @@ class Field(AbstractField): ...@@ -182,7 +189,7 @@ class Field(AbstractField):
@staticmethod @staticmethod
def create_generic(field_name, spatial_dimensions, dtype=np.float64, index_dimensions=0, layout='numpy', def create_generic(field_name, spatial_dimensions, dtype=np.float64, index_dimensions=0, layout='numpy',
index_shape=None, field_type=FieldType.GENERIC, staggered=False) -> 'Field': index_shape=None, field_type=FieldType.GENERIC) -> 'Field':
""" """
Creates a generic field where the field size is not fixed i.e. can be called with arrays of different sizes Creates a generic field where the field size is not fixed i.e. can be called with arrays of different sizes
...@@ -197,9 +204,9 @@ class Field(AbstractField): ...@@ -197,9 +204,9 @@ class Field(AbstractField):
index_shape: optional shape of the index dimensions i.e. maximum values allowed for each index dimension, index_shape: optional shape of the index dimensions i.e. maximum values allowed for each index dimension,
has to be a list or tuple has to be a list or tuple
field_type: besides the normal GENERIC fields, there are INDEXED fields that store indices of the domain field_type: besides the normal GENERIC fields, there are INDEXED fields that store indices of the domain
that should be iterated over, and BUFFER fields that are used to generate that should be iterated over, BUFFER fields that are used to generate communication
communication packing/unpacking kernels packing/unpacking kernels, and STAGGERED fields, which store values half-way to the next
staggered: enables staggered access (with half-integer offsets) and corresponding printing cell
""" """
if index_shape is not None: if index_shape is not None:
assert index_dimensions == 0 or index_dimensions == len(index_shape) assert index_dimensions == 0 or index_dimensions == len(index_shape)
...@@ -221,14 +228,14 @@ class Field(AbstractField): ...@@ -221,14 +228,14 @@ class Field(AbstractField):
raise ValueError("Structured arrays/fields are not allowed to have an index dimension") raise ValueError("Structured arrays/fields are not allowed to have an index dimension")
shape += (1,) shape += (1,)
strides += (1,) strides += (1,)
if staggered and index_dimensions == 0: if field_type == FieldType.STAGGERED and index_dimensions == 0:
raise ValueError("A staggered field needs at least one index dimension") raise ValueError("A staggered field needs at least one index dimension")
return Field(field_name, field_type, dtype, layout, shape, strides, staggered) return Field(field_name, field_type, dtype, layout, shape, strides)
@staticmethod @staticmethod
def create_from_numpy_array(field_name: str, array: np.ndarray, index_dimensions: int = 0, def create_from_numpy_array(field_name: str, array: np.ndarray, index_dimensions: int = 0,
staggered=False) -> 'Field': field_type=FieldType.GENERIC) -> 'Field':
"""Creates a field based on the layout, data type, and shape of a given numpy array. """Creates a field based on the layout, data type, and shape of a given numpy array.
Kernels created for these kind of fields can only be called with arrays of the same layout, shape and type. Kernels created for these kind of fields can only be called with arrays of the same layout, shape and type.
...@@ -237,7 +244,7 @@ class Field(AbstractField): ...@@ -237,7 +244,7 @@ class Field(AbstractField):
field_name: symbolic name for the field field_name: symbolic name for the field
array: numpy array array: numpy array
index_dimensions: see documentation of Field index_dimensions: see documentation of Field
staggered: enables staggered access (with half-integer offsets) and corresponding printing field_type: kind of field
""" """
spatial_dimensions = len(array.shape) - index_dimensions spatial_dimensions = len(array.shape) - index_dimensions
if spatial_dimensions < 1: if spatial_dimensions < 1:
...@@ -256,15 +263,15 @@ class Field(AbstractField): ...@@ -256,15 +263,15 @@ class Field(AbstractField):
raise ValueError("Structured arrays/fields are not allowed to have an index dimension") raise ValueError("Structured arrays/fields are not allowed to have an index dimension")
shape += (1,) shape += (1,)
strides += (1,) strides += (1,)
if staggered and index_dimensions == 0: if field_type == FieldType.STAGGERED and index_dimensions == 0:
raise ValueError("A staggered field needs at least one index dimension") raise ValueError("A staggered field needs at least one index dimension")
return Field(field_name, FieldType.GENERIC, array.dtype, spatial_layout, shape, strides, staggered) return Field(field_name, field_type, array.dtype, spatial_layout, shape, strides)
@staticmethod @staticmethod
def create_fixed_size(field_name: str, shape: Tuple[int, ...], index_dimensions: int = 0, def create_fixed_size(field_name: str, shape: Tuple[int, ...], index_dimensions: int = 0,
dtype=np.float64, layout: str = 'numpy', strides: Optional[Sequence[int]] = None, dtype=np.float64, layout: str = 'numpy', strides: Optional[Sequence[int]] = None,
staggered=False) -> 'Field': field_type=FieldType.GENERIC) -> 'Field':
""" """
Creates a field with fixed sizes i.e. can be called only with arrays of the same size and layout Creates a field with fixed sizes i.e. can be called only with arrays of the same size and layout
...@@ -275,7 +282,7 @@ class Field(AbstractField): ...@@ -275,7 +282,7 @@ class Field(AbstractField):
dtype: numpy data type of the array the kernel is called with later dtype: numpy data type of the array the kernel is called with later
layout: full layout of array, not only spatial dimensions layout: full layout of array, not only spatial dimensions
strides: strides in bytes or None to automatically compute them from shape (assuming no padding) strides: strides in bytes or None to automatically compute them from shape (assuming no padding)
staggered: enables staggered access (with half-integer offsets) and corresponding printing field_type: kind of field
""" """
spatial_dimensions = len(shape) - index_dimensions spatial_dimensions = len(shape) - index_dimensions
assert spatial_dimensions >= 1 assert spatial_dimensions >= 1
...@@ -296,15 +303,15 @@ class Field(AbstractField): ...@@ -296,15 +303,15 @@ class Field(AbstractField):
raise ValueError("Structured arrays/fields are not allowed to have an index dimension") raise ValueError("Structured arrays/fields are not allowed to have an index dimension")
shape += (1,) shape += (1,)
strides += (1,) strides += (1,)
if staggered and index_dimensions == 0: if field_type == FieldType.STAGGERED and index_dimensions == 0:
raise ValueError("A staggered field needs at least one index dimension") raise ValueError("A staggered field needs at least one index dimension")
spatial_layout = list(layout) spatial_layout = list(layout)
for i in range(spatial_dimensions, len(layout)): for i in range(spatial_dimensions, len(layout)):
spatial_layout.remove(i) spatial_layout.remove(i)
return Field(field_name, FieldType.GENERIC, dtype, tuple(spatial_layout), shape, strides, staggered) return Field(field_name, field_type, dtype, tuple(spatial_layout), shape, strides)
def __init__(self, field_name, field_type, dtype, layout, shape, strides, staggered): def __init__(self, field_name, field_type, dtype, layout, shape, strides):
"""Do not use directly. Use static create* methods""" """Do not use directly. Use static create* methods"""
self._field_name = field_name self._field_name = field_name
assert isinstance(field_type, FieldType) assert isinstance(field_type, FieldType)
...@@ -319,7 +326,6 @@ class Field(AbstractField): ...@@ -319,7 +326,6 @@ class Field(AbstractField):
0 for _ in range(self.spatial_dimensions) 0 for _ in range(self.spatial_dimensions)
)) # type: tuple[float,sp.Symbol] )) # type: tuple[float,sp.Symbol]
self.coordinate_transform = sp.eye(self.spatial_dimensions) self.coordinate_transform = sp.eye(self.spatial_dimensions)
self.is_staggered = staggered
def new_field_with_different_name(self, new_name): def new_field_with_different_name(self, new_name):
if self.has_fixed_shape: if self.has_fixed_shape:
...@@ -456,7 +462,7 @@ class Field(AbstractField): ...@@ -456,7 +462,7 @@ class Field(AbstractField):
If the field stores more than one value per staggered point (e.g. a vector or a tensor), the index (integer or If the field stores more than one value per staggered point (e.g. a vector or a tensor), the index (integer or
tuple of integers) refers to which of these values to access. tuple of integers) refers to which of these values to access.
""" """
assert self.is_staggered assert FieldType.is_staggered(self)
if type(offset) is np.ndarray: if type(offset) is np.ndarray:
offset = tuple(offset) offset = tuple(offset)
...@@ -611,7 +617,6 @@ class Field(AbstractField): ...@@ -611,7 +617,6 @@ class Field(AbstractField):
obj._indirect_addressing_fields.update(a.field for a in e.atoms(Field.Access)) obj._indirect_addressing_fields.update(a.field for a in e.atoms(Field.Access))
obj._is_absolute_access = is_absolute_access obj._is_absolute_access = is_absolute_access
obj.is_staggered = field.is_staggered
return obj return obj
def __getnewargs__(self): def __getnewargs__(self):
...@@ -744,7 +749,7 @@ class Field(AbstractField): ...@@ -744,7 +749,7 @@ class Field(AbstractField):
def _latex(self, _): def _latex(self, _):
n = self._field.latex_name if self._field.latex_name else self._field.name n = self._field.latex_name if self._field.latex_name else self._field.name
offset_str = ",".join([sp.latex(o) for o in self.offsets]) offset_str = ",".join([sp.latex(o) for o in self.offsets])
if self.is_staggered: if FieldType.is_staggered(self._field):
offset_str = ",".join([sp.latex(o - sp.Rational(int(i == self.index[0]), 2)) offset_str = ",".join([sp.latex(o - sp.Rational(int(i == self.index[0]), 2))
for i, o in enumerate(self.offsets)]) for i, o in enumerate(self.offsets)])
if self.is_absolute_access: if self.is_absolute_access:
...@@ -752,7 +757,7 @@ class Field(AbstractField): ...@@ -752,7 +757,7 @@ class Field(AbstractField):
elif self.field.spatial_dimensions > 1: elif self.field.spatial_dimensions > 1:
offset_str = "({})".format(offset_str) offset_str = "({})".format(offset_str)
if self.is_staggered: if FieldType.is_staggered(self._field):
if self.index and self.field.index_dimensions > 1: if self.index and self.field.index_dimensions > 1:
return "{{%s}_{%s}^{%s}}" % (n, offset_str, self.index[1:] return "{{%s}_{%s}^{%s}}" % (n, offset_str, self.index[1:]
if len(self.index) > 2 else self.index[1]) if len(self.index) > 2 else self.index[1])
...@@ -767,13 +772,13 @@ class Field(AbstractField): ...@@ -767,13 +772,13 @@ class Field(AbstractField):
def __str__(self): def __str__(self):
n = self._field.latex_name if self._field.latex_name else self._field.name n = self._field.latex_name if self._field.latex_name else self._field.name
offset_str = ",".join([sp.latex(o) for o in self.offsets]) offset_str = ",".join([sp.latex(o) for o in self.offsets])
if self.is_staggered: if FieldType.is_staggered(self._field):
offset_str = ",".join([sp.latex(o - sp.Rational(int(i == self.index[0]), 2)) offset_str = ",".join([sp.latex(o - sp.Rational(int(i == self.index[0]), 2))
for i, o in enumerate(self.offsets)]) for i, o in enumerate(self.offsets)])
if self.is_absolute_access: if self.is_absolute_access:
offset_str = "[abs]{}".format(offset_str) offset_str = "[abs]{}".format(offset_str)
if self.is_staggered: if FieldType.is_staggered(self._field):
if self.index and self.field.index_dimensions > 1: if self.index and self.field.index_dimensions > 1:
return "%s[%s](%s)" % (n, offset_str, self.index[1:] if len(self.index) > 2 else self.index[1]) return "%s[%s](%s)" % (n, offset_str, self.index[1:] if len(self.index) > 2 else self.index[1])
else: else:
......
...@@ -5,7 +5,7 @@ import pystencils as ps ...@@ -5,7 +5,7 @@ import pystencils as ps
def test_blocking_staggered(): def test_blocking_staggered():
f = ps.fields("f: double[3D]") f = ps.fields("f: double[3D]")
stag = ps.fields("stag(3): double[3D]", staggered=True) stag = ps.fields("stag(3): double[3D]", field_type=ps.FieldType.STAGGERED)
terms = [ terms = [
f[0, 0, 0] - f[-1, 0, 0], f[0, 0, 0] - f[-1, 0, 0],
f[0, 0, 0] - f[0, -1, 0], f[0, 0, 0] - f[0, -1, 0],
......
...@@ -131,7 +131,7 @@ def test_itemsize(): ...@@ -131,7 +131,7 @@ def test_itemsize():
def test_staggered(): def test_staggered():
j1, j2, j3 = ps.fields('j1(2), j2(2,2), j3(2,2,2) : double[2D]', staggered=True) j1, j2, j3 = ps.fields('j1(2), j2(2,2), j3(2,2,2) : double[2D]', field_type=FieldType.STAGGERED)
assert j1[0, 1](1) == j1.staggered_access((0, sp.Rational(1, 2))) assert j1[0, 1](1) == j1.staggered_access((0, sp.Rational(1, 2)))
assert j1[0, 1](1) == j1.staggered_access("N") assert j1[0, 1](1) == j1.staggered_access("N")
......
...@@ -3,7 +3,7 @@ import sympy as sp ...@@ -3,7 +3,7 @@ import sympy as sp
import pystencils as ps import pystencils as ps
import pystencils.astnodes as ast import pystencils.astnodes as ast
from pystencils.field import Field from pystencils.field import Field, FieldType
from pystencils.astnodes import Conditional, LoopOverCoordinate, SympyAssignment from pystencils.astnodes import Conditional, LoopOverCoordinate, SympyAssignment
from pystencils.cpu import create_kernel, make_python_function from pystencils.cpu import create_kernel, make_python_function
from pystencils.kernelcreation import create_staggered_kernel from pystencils.kernelcreation import create_staggered_kernel
...@@ -34,9 +34,9 @@ def test_staggered_iteration(): ...@@ -34,9 +34,9 @@ def test_staggered_iteration():
s_arr_ref = s_arr.copy() s_arr_ref = s_arr.copy()
fields_fixed = (Field.create_from_numpy_array('f', f_arr), fields_fixed = (Field.create_from_numpy_array('f', f_arr),
Field.create_from_numpy_array('s', s_arr, index_dimensions=1, staggered=True)) Field.create_from_numpy_array('s', s_arr, index_dimensions=1, field_type=FieldType.STAGGERED))
fields_var = (Field.create_generic('f', 2), fields_var = (Field.create_generic('f', 2),
Field.create_generic('s', 2, index_dimensions=1, staggered=True)) Field.create_generic('s', 2, index_dimensions=1, field_type=FieldType.STAGGERED))
for f, s in [fields_var, fields_fixed]: for f, s in [fields_var, fields_fixed]:
# --- Manual # --- Manual
...@@ -70,7 +70,7 @@ def test_staggered_iteration_manual(): ...@@ -70,7 +70,7 @@ def test_staggered_iteration_manual():
s_arr_ref = s_arr.copy() s_arr_ref = s_arr.copy()
f = Field.create_from_numpy_array('f', f_arr) f = Field.create_from_numpy_array('f', f_arr)
s = Field.create_from_numpy_array('s', s_arr, index_dimensions=1, staggered=True) s = Field.create_from_numpy_array('s', s_arr, index_dimensions=1, field_type=FieldType.STAGGERED)
eqs = [] eqs = []
...@@ -108,7 +108,7 @@ def test_staggered_iteration_manual(): ...@@ -108,7 +108,7 @@ def test_staggered_iteration_manual():
def test_staggered_gpu(): def test_staggered_gpu():
dim = 2 dim = 2
f = ps.fields("f: double[{dim}D]".format(dim=dim)) f = ps.fields("f: double[{dim}D]".format(dim=dim))
s = ps.fields("s({dim}): double[{dim}D]".format(dim=dim), staggered=True) s = ps.fields("s({dim}): double[{dim}D]".format(dim=dim), field_type=FieldType.STAGGERED)
expressions = [(f[0, 0] + f[-1, 0]) / 2, expressions = [(f[0, 0] + f[-1, 0]) / 2,
(f[0, 0] + f[0, -1]) / 2] (f[0, 0] + f[0, -1]) / 2]
kernel_ast = ps.create_staggered_kernel(s, expressions, target='gpu', gpu_exclusive_conditions=True) kernel_ast = ps.create_staggered_kernel(s, expressions, target='gpu', gpu_exclusive_conditions=True)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment