diff --git a/cpu/cpujit.py b/cpu/cpujit.py index cb840d3db2cd78dc90bc0613cf389de7371fb814..536c0a36ed0e19c1f714ca1632ea9118c1fdc231 100644 --- a/cpu/cpujit.py +++ b/cpu/cpujit.py @@ -397,7 +397,7 @@ def build_ctypes_argument_list(parameter_specification, argument_dict): if FieldType.is_indexed(symbolic_field): index_arr_shapes.add(field_arr.shape[:symbolic_field.spatial_dimensions]) - elif not FieldType.is_buffer(symbolic_field): + elif FieldType.is_generic(symbolic_field): array_shapes.add(field_arr.shape[:symbolic_field.spatial_dimensions]) elif arg.is_field_shape_argument: diff --git a/field.py b/field.py index 58f13cb94ded95c0aa779ec0ebd57a45314545d6..632c454be7fee0e4226f36f753300e393108f1ac 100644 --- a/field.py +++ b/field.py @@ -87,6 +87,9 @@ class FieldType(Enum): 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): @@ -103,6 +106,11 @@ class FieldType(Enum): 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 Field: """ @@ -367,6 +375,7 @@ class Field: return Field.Access(self, offset) def absolute_access(self, offset, index): + assert FieldType.is_custom(self) return Field.Access(self, offset, index, is_absolute_access=True) def __call__(self, *args, **kwargs): @@ -582,10 +591,16 @@ class Field: def _latex(self, _): n = self._field.latex_name if self._field.latex_name else self._field.name - if self._superscript: - return "{{%s}_{%s}^{%s}}" % (n, self._offsetName, self._superscript) + offset_str = ",".join([sp.latex(o) for o in self.offsets]) + if self.is_absolute_access: + offset_str = "\\mathbf{}".format(offset_str) + elif self.field.spatial_dimensions > 1: + offset_str = "({})".format(offset_str) + + if self.index and self.index != (0,): + return "{{%s}_{%s}^{%s}}" % (n, offset_str, self.index if len(self.index) > 1 else self.index[0]) else: - return "{{%s}_{%s}}" % (n, self._offsetName) + return "{{%s}_{%s}}" % (n, offset_str) def get_layout_from_strides(strides: Sequence[int], index_dimension_ids: Optional[List[int]] = None): diff --git a/gpucuda/cudajit.py b/gpucuda/cudajit.py index 1127ecadcb1bc744a06037b11b17c3501d26a814..70f757a0578ea582ee38677baa2bed093125c804 100644 --- a/gpucuda/cudajit.py +++ b/gpucuda/cudajit.py @@ -132,7 +132,7 @@ def _check_arguments(parameter_specification, argument_dict): if FieldType.is_indexed(symbolic_field): index_arr_shapes.add(field_arr.shape[:symbolic_field.spatial_dimensions]) - elif not FieldType.is_buffer(symbolic_field): + elif FieldType.is_generic(symbolic_field): array_shapes.add(field_arr.shape[:symbolic_field.spatial_dimensions]) if len(array_shapes) > 1: