From 81d1c475824aee493393a8231cca775da4f3dd13 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Fri, 8 Sep 2017 15:47:06 +0200 Subject: [PATCH 1/4] Implement an 'aliases_base_storage' property for TemporaryVariable So far, use of the base_storage mechanism was limited to use cases where the pointers into the base storage were not aliased. This allows to set a flag 'aliases_base_storage' to change this behaviour and implements the resulting non-restricted pointers in the CTarget. --- loopy/kernel/data.py | 21 +++++++++++++++++++-- loopy/target/c/__init__.py | 24 +++++++++++++++++------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index 94b31df12..c802216c5 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -346,6 +346,11 @@ class TemporaryVariable(ArrayBase): A :class:`bool` indicating whether the variable may be written during its lifetime. If *True*, *initializer* must be given. + + .. attribute:: aliases_base_storage + + Whether the temporary is used to alias the underlying base storage. + Defaults to False. """ min_target_axes = 0 @@ -358,12 +363,14 @@ class TemporaryVariable(ArrayBase): "base_storage", "initializer", "read_only", + "aliases_base_storage", ] def __init__(self, name, dtype=None, shape=(), scope=auto, dim_tags=None, offset=0, dim_names=None, strides=None, order=None, base_indices=None, storage_shape=None, - base_storage=None, initializer=None, read_only=False, **kwargs): + base_storage=None, initializer=None, read_only=False, + aliases_base_storage=False, **kwargs): """ :arg dtype: :class:`loopy.auto` or a :class:`numpy.dtype` :arg shape: :class:`loopy.auto` or a shape tuple @@ -419,6 +426,13 @@ class TemporaryVariable(ArrayBase): "mutually exclusive" % name) + if base_storage is None and aliases_base_storage: + raise LoopyError( + "temporary variable '%s': " + "aliases_base_storage option, but no " + "base_storage given!" + % name) + ArrayBase.__init__(self, name=intern(name), dtype=dtype, shape=shape, dim_tags=dim_tags, offset=offset, dim_names=dim_names, @@ -428,6 +442,7 @@ class TemporaryVariable(ArrayBase): base_storage=base_storage, initializer=initializer, read_only=read_only, + aliases_base_storage=aliases_base_storage, **kwargs) @property @@ -489,7 +504,9 @@ class TemporaryVariable(ArrayBase): and ( (self.initializer is None and other.initializer is None) or np.array_equal(self.initializer, other.initializer)) - and self.read_only == other.read_only) + and self.read_only == other.read_only + and self.aliases_base_storage == other.aliases_base_storage + ) def update_persistent_hash(self, key_hash, key_builder): """Custom hash computation function for use with diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index a2ad68250..690d80c20 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -307,6 +307,12 @@ class _ConstRestrictPointer(Pointer): return sub_tp, ("*const __restrict__ %s" % sub_decl) +class _ConstPointer(Pointer): + def get_decl_pait(self): + sub_tp, sub_decl = self.subdecl.get_decl_pair() + return sub_tp, ("*const %s" % sub_decl) + + class CASTBuilder(ASTBuilderBase): # {{{ library @@ -462,13 +468,17 @@ class CASTBuilder(ASTBuilderBase): temp_var_decl = self.wrap_temporary_decl( temp_var_decl, tv.scope) - # The 'restrict' part of this is a complete lie--of course - # all these temporaries are aliased. But we're promising to - # not use them to shovel data from one representation to the - # other. That counts, right? - - cast_decl = _ConstRestrictPointer(cast_decl) - temp_var_decl = _ConstRestrictPointer(temp_var_decl) + if tv.aliases_base_storage: + ptrtype = _ConstPointer + else: + # The 'restrict' part of this is a complete lie--of course + # all these temporaries are aliased. But we're promising to + # not use them to shovel data from one representation to the + # other. That counts, right? + ptrtype = _ConstRestrictPointer + + cast_decl = ptrtype(cast_decl) + temp_var_decl = ptrtype(temp_var_decl) cast_tp, cast_d = cast_decl.get_decl_pair() temp_var_decl = Initializer( -- GitLab From cb2a98fdbe7a985cdd36cd00d4a015d9e7a98943 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 20 Sep 2017 12:20:19 +0200 Subject: [PATCH 2/4] Rename aliasing property and document its behaviour furthermore --- loopy/kernel/data.py | 21 +++++++++++++-------- loopy/target/c/__init__.py | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index c802216c5..adae1951b 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -347,10 +347,13 @@ class TemporaryVariable(ArrayBase): A :class:`bool` indicating whether the variable may be written during its lifetime. If *True*, *initializer* must be given. - .. attribute:: aliases_base_storage + .. attribute:: _base_storage_access_may_be_aliasing Whether the temporary is used to alias the underlying base storage. - Defaults to False. + Defaults to *False*. If *False*, C-based code generators will declare + the temporary as a restricted const pointer to the base storage + memory location. If *True*, the restrict part is omitted on this + declaration. """ min_target_axes = 0 @@ -363,14 +366,14 @@ class TemporaryVariable(ArrayBase): "base_storage", "initializer", "read_only", - "aliases_base_storage", + "_base_storage_access_may_be_aliasing", ] def __init__(self, name, dtype=None, shape=(), scope=auto, dim_tags=None, offset=0, dim_names=None, strides=None, order=None, base_indices=None, storage_shape=None, base_storage=None, initializer=None, read_only=False, - aliases_base_storage=False, **kwargs): + _base_storage_access_may_be_aliasing=False, **kwargs): """ :arg dtype: :class:`loopy.auto` or a :class:`numpy.dtype` :arg shape: :class:`loopy.auto` or a shape tuple @@ -426,10 +429,10 @@ class TemporaryVariable(ArrayBase): "mutually exclusive" % name) - if base_storage is None and aliases_base_storage: + if base_storage is None and _base_storage_access_may_be_aliasing: raise LoopyError( "temporary variable '%s': " - "aliases_base_storage option, but no " + "_base_storage_access_may_be_aliasing option, but no " "base_storage given!" % name) @@ -442,7 +445,8 @@ class TemporaryVariable(ArrayBase): base_storage=base_storage, initializer=initializer, read_only=read_only, - aliases_base_storage=aliases_base_storage, + _base_storage_access_may_be_aliasing= + _base_storage_access_may_be_aliasing, **kwargs) @property @@ -505,7 +509,8 @@ class TemporaryVariable(ArrayBase): (self.initializer is None and other.initializer is None) or np.array_equal(self.initializer, other.initializer)) and self.read_only == other.read_only - and self.aliases_base_storage == other.aliases_base_storage + and self._base_storage_access_may_be_aliasing + == other._base_storage_access_may_be_aliasing ) def update_persistent_hash(self, key_hash, key_builder): diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 690d80c20..90f45ed4d 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -468,7 +468,7 @@ class CASTBuilder(ASTBuilderBase): temp_var_decl = self.wrap_temporary_decl( temp_var_decl, tv.scope) - if tv.aliases_base_storage: + if tv._base_storage_access_may_be_aliasing: ptrtype = _ConstPointer else: # The 'restrict' part of this is a complete lie--of course -- GitLab From 58c31e7e65c1f66065ade8d41be812bef186e923 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 20 Sep 2017 18:35:12 +0200 Subject: [PATCH 3/4] Fix flake8 --- loopy/kernel/data.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index adae1951b..4ea8ea740 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -436,6 +436,7 @@ class TemporaryVariable(ArrayBase): "base_storage given!" % name) + alias = _base_storage_access_may_be_aliasing ArrayBase.__init__(self, name=intern(name), dtype=dtype, shape=shape, dim_tags=dim_tags, offset=offset, dim_names=dim_names, @@ -445,8 +446,7 @@ class TemporaryVariable(ArrayBase): base_storage=base_storage, initializer=initializer, read_only=read_only, - _base_storage_access_may_be_aliasing= - _base_storage_access_may_be_aliasing, + _base_storage_access_may_be_aliasing=alias, **kwargs) @property @@ -509,8 +509,8 @@ class TemporaryVariable(ArrayBase): (self.initializer is None and other.initializer is None) or np.array_equal(self.initializer, other.initializer)) and self.read_only == other.read_only - and self._base_storage_access_may_be_aliasing - == other._base_storage_access_may_be_aliasing + and (self._base_storage_access_may_be_aliasing + == other._base_storage_access_may_be_aliasing) ) def update_persistent_hash(self, key_hash, key_builder): -- GitLab From 28aae0f398b80182f574e994bfd6da75acd83f36 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Wed, 4 Oct 2017 09:53:11 +0200 Subject: [PATCH 4/4] Small doc/style fixes --- loopy/kernel/data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index 4ea8ea740..e1941122d 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -351,7 +351,7 @@ class TemporaryVariable(ArrayBase): Whether the temporary is used to alias the underlying base storage. Defaults to *False*. If *False*, C-based code generators will declare - the temporary as a restricted const pointer to the base storage + the temporary as a ``restrict`` const pointer to the base storage memory location. If *True*, the restrict part is omitted on this declaration. """ @@ -436,7 +436,6 @@ class TemporaryVariable(ArrayBase): "base_storage given!" % name) - alias = _base_storage_access_may_be_aliasing ArrayBase.__init__(self, name=intern(name), dtype=dtype, shape=shape, dim_tags=dim_tags, offset=offset, dim_names=dim_names, @@ -446,7 +445,8 @@ class TemporaryVariable(ArrayBase): base_storage=base_storage, initializer=initializer, read_only=read_only, - _base_storage_access_may_be_aliasing=alias, + _base_storage_access_may_be_aliasing=( + _base_storage_access_may_be_aliasing), **kwargs) @property -- GitLab