From 64122789c5c9b85536e04d61dc10b84b54db181d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Kl=C3=B6ckner?= Date: Tue, 22 Jan 2019 07:39:55 +0100 Subject: [PATCH] Revert "Merge branch 'remove-auto-from-insn-temp-var-type' into 'master'" This reverts merge request !297 --- doc/ref_kernel.rst | 2 -- doc/tutorial.rst | 2 +- loopy/__init__.py | 4 --- loopy/kernel/array.py | 5 ++- loopy/kernel/creation.py | 28 ++++++++------- loopy/kernel/data.py | 5 ++- loopy/kernel/instruction.py | 58 +++++++++++++++--------------- loopy/symbolic.py | 5 ++- loopy/tools.py | 72 ------------------------------------- test/test_misc.py | 40 --------------------- 10 files changed, 51 insertions(+), 170 deletions(-) diff --git a/doc/ref_kernel.rst b/doc/ref_kernel.rst index 460633109..896388d29 100644 --- a/doc/ref_kernel.rst +++ b/doc/ref_kernel.rst @@ -553,8 +553,6 @@ Helper values .. autoclass:: UniqueName -.. autoclass:: Optional - .. }}} Libraries: Extending and Interfacing with External Functionality diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 3c85060da..397f34a98 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -1869,7 +1869,7 @@ Now to make things more interesting, we'll create a kernel with barriers: ... e[i,j,k] = c[i,j,k+1]+c[i,j,k-1] ... """ ... ], [ - ... lp.TemporaryVariable("c", dtype=None, shape=(50, 10, 99)), + ... lp.TemporaryVariable("c", lp.auto, shape=(50, 10, 99)), ... "..." ... ]) >>> knl = lp.add_and_infer_dtypes(knl, dict(a=np.int32)) diff --git a/loopy/__init__.py b/loopy/__init__.py index d69a57bf1..f50ce237c 100644 --- a/loopy/__init__.py +++ b/loopy/__init__.py @@ -149,8 +149,6 @@ from loopy.target.pyopencl import PyOpenCLTarget from loopy.target.ispc import ISPCTarget from loopy.target.numba import NumbaTarget, NumbaCudaTarget -from loopy.tools import Optional - __all__ = [ "TaggedVariable", "Reduction", "LinearSubscript", "TypeCast", @@ -277,8 +275,6 @@ __all__ = [ "NumbaTarget", "NumbaCudaTarget", "ASTBuilderBase", - "Optional", - # {{{ from this file "register_preamble_generators", diff --git a/loopy/kernel/array.py b/loopy/kernel/array.py index 3588f38af..bae9d7d1f 100644 --- a/loopy/kernel/array.py +++ b/loopy/kernel/array.py @@ -693,9 +693,8 @@ class ArrayBase(ImmutableRecord): if dtype is lp.auto: from warnings import warn - warn("Argument/temporary data type for '%s' should be None if " - "unspecified, not auto. This usage will be disallowed in 2018." - % name, + warn("Argument/temporary data type should be None if unspecified, " + "not auto. This usage will be disallowed in 2018.", DeprecationWarning, stacklevel=2) dtype = None diff --git a/loopy/kernel/creation.py b/loopy/kernel/creation.py index 2175b5f36..c42db3482 100644 --- a/loopy/kernel/creation.py +++ b/loopy/kernel/creation.py @@ -28,7 +28,7 @@ THE SOFTWARE. import numpy as np from pymbolic.mapper import CSECachingMapperMixin -from loopy.tools import intern_frozenset_of_ids, Optional +from loopy.tools import intern_frozenset_of_ids from loopy.symbolic import IdentityMapper, WalkMapper from loopy.kernel.data import ( InstructionBase, @@ -454,6 +454,7 @@ def parse_insn(groups, insn_options): and *inames_to_dup* is None or a list of tuples `(old, new)`. """ + import loopy as lp from loopy.symbolic import parse if "lhs" in groups: @@ -485,11 +486,14 @@ def parse_insn(groups, insn_options): for lhs_i in lhs: if isinstance(lhs_i, TypeAnnotation): - assert isinstance(lhs_i.type, Optional) - temp_var_types.append(lhs_i.type) + if lhs_i.type is None: + temp_var_types.append(lp.auto) + else: + temp_var_types.append(lhs_i.type) + lhs_i = lhs_i.child else: - temp_var_types.append(Optional()) + temp_var_types.append(None) inner_lhs_i = lhs_i if isinstance(inner_lhs_i, Lookup): @@ -1134,9 +1138,9 @@ class ArgumentGuesser: def make_new_arg(self, arg_name): arg_name = arg_name.strip() - import loopy as lp from loopy.kernel.data import ValueArg, ArrayArg, AddressSpace + import loopy as lp if arg_name in self.all_params: return ValueArg(arg_name) @@ -1187,7 +1191,7 @@ class ArgumentGuesser: for assignee_var_name, temp_var_type in zip( insn.assignee_var_names(), insn.temp_var_types): - if temp_var_type.has_value: + if temp_var_type is not None: temp_var_names.add(assignee_var_name) # }}} @@ -1427,7 +1431,7 @@ def create_temporaries(knl, default_order): insn.assignee_var_names(), insn.temp_var_types): - if not temp_var_type.has_value: + if temp_var_type is None: continue if assignee_name in new_temp_vars: @@ -1442,17 +1446,17 @@ def create_temporaries(knl, default_order): new_temp_vars[assignee_name] = lp.TemporaryVariable( name=assignee_name, - dtype=temp_var_type.value, + dtype=temp_var_type, address_space=lp.auto, base_indices=lp.auto, shape=lp.auto, order=default_order, target=knl.target) - if isinstance(insn, Assignment): - insn = insn.copy(temp_var_type=Optional()) - else: - insn = insn.copy(temp_var_types=(Optional(),) * len(insn.assignees)) + if isinstance(insn, Assignment): + insn = insn.copy(temp_var_type=None) + else: + insn = insn.copy(temp_var_types=None) new_insns.append(insn) diff --git a/loopy/kernel/data.py b/loopy/kernel/data.py index 8103029dc..7877f8b93 100644 --- a/loopy/kernel/data.py +++ b/loopy/kernel/data.py @@ -330,9 +330,8 @@ class KernelArgument(ImmutableRecord): import loopy as lp if dtype is lp.auto: - warn("Argument/temporary data type for '%s' should be None if " - "unspecified, not auto. This usage will be disallowed in 2018." - % kwargs["name"], + warn("Argument/temporary data type should be None if unspecified, " + "not auto. This usage will be disallowed in 2018.", DeprecationWarning, stacklevel=2) dtype = None diff --git a/loopy/kernel/instruction.py b/loopy/kernel/instruction.py index d7784eabf..e9c7bde9f 100644 --- a/loopy/kernel/instruction.py +++ b/loopy/kernel/instruction.py @@ -25,7 +25,6 @@ THE SOFTWARE. from six.moves import intern from pytools import ImmutableRecord, memoize_method from loopy.diagnostic import LoopyError -from loopy.tools import Optional from warnings import warn @@ -839,9 +838,8 @@ class Assignment(MultiAssignmentBase): .. attribute:: temp_var_type - A :class:`loopy.Optional`. If not empty, contains the type that - will be assigned to the new temporary variable created from the - assignment. + if not *None*, a type that will be assigned to the new temporary variable + created from the assignee .. attribute:: atomicity @@ -895,7 +893,7 @@ class Assignment(MultiAssignmentBase): within_inames_is_final=None, within_inames=None, boostable=None, boostable_into=None, tags=None, - temp_var_type=Optional(), atomicity=(), + temp_var_type=None, atomicity=(), priority=0, predicates=frozenset(), insn_deps=None, insn_deps_is_final=None, forced_iname_deps=None, forced_iname_deps_is_final=None): @@ -1008,9 +1006,8 @@ class CallInstruction(MultiAssignmentBase): .. attribute:: temp_var_types - A tuple of `:class:loopy.Optional`. If an entry is not empty, it - contains the type that will be assigned to the new temporary variable - created from the assigment. + if not *None*, a type that will be assigned to the new temporary variable + created from the assignee .. automethod:: __init__ """ @@ -1082,7 +1079,7 @@ class CallInstruction(MultiAssignmentBase): self.expression = expression if temp_var_types is None: - self.temp_var_types = (Optional(),) * len(self.assignees) + self.temp_var_types = (None,) * len(self.assignees) else: self.temp_var_types = temp_var_types @@ -1130,33 +1127,34 @@ class CallInstruction(MultiAssignmentBase): def make_assignment(assignees, expression, temp_var_types=None, **kwargs): - if temp_var_types is None: - temp_var_types = (Optional(),) * len(assignees) + if len(assignees) > 1 or len(assignees) == 0: + atomicity = kwargs.pop("atomicity", ()) + if atomicity: + raise LoopyError("atomic operations with more than one " + "left-hand side not supported") - if len(assignees) == 1: + from pymbolic.primitives import Call + from loopy.symbolic import Reduction + if not isinstance(expression, (Call, Reduction)): + raise LoopyError("right-hand side in multiple assignment must be " + "function call or reduction, got: '%s'" % expression) + + return CallInstruction( + assignees=assignees, + expression=expression, + temp_var_types=temp_var_types, + **kwargs) + + else: return Assignment( assignee=assignees[0], expression=expression, - temp_var_type=temp_var_types[0], + temp_var_type=( + temp_var_types[0] + if temp_var_types is not None + else None), **kwargs) - atomicity = kwargs.pop("atomicity", ()) - if atomicity: - raise LoopyError("atomic operations with more than one " - "left-hand side not supported") - - from pymbolic.primitives import Call - from loopy.symbolic import Reduction - if not isinstance(expression, (Call, Reduction)): - raise LoopyError("right-hand side in multiple assignment must be " - "function call or reduction, got: '%s'" % expression) - - return CallInstruction( - assignees=assignees, - expression=expression, - temp_var_types=temp_var_types, - **kwargs) - # {{{ c instruction diff --git a/loopy/symbolic.py b/loopy/symbolic.py index ae0c8999e..f4d46854b 100644 --- a/loopy/symbolic.py +++ b/loopy/symbolic.py @@ -1131,15 +1131,14 @@ class LoopyParser(ParserBase): def parse_prefix(self, pstate): from pymbolic.parser import _PREC_UNARY, _less, _greater, _identifier - import loopy as lp if pstate.is_next(_less): pstate.advance() if pstate.is_next(_greater): - typename = lp.Optional(None) + typename = None pstate.advance() else: pstate.expect(_identifier) - typename = lp.Optional(pstate.next_str()) + typename = pstate.next_str() pstate.advance() pstate.expect(_greater) pstate.advance() diff --git a/loopy/tools.py b/loopy/tools.py index 470921e31..7e9a89214 100644 --- a/loopy/tools.py +++ b/loopy/tools.py @@ -587,78 +587,6 @@ class LazilyUnpicklingListWithEqAndPersistentHashing(LazilyUnpicklingList): # }}} -# {{{ optional object - -class _no_value(object): # noqa - pass - - -class Optional(object): - """A wrapper for an optionally present object. - - .. attribute:: has_value - - *True* if and only if this object contains a value. - - .. attribute:: value - - The value, if present. - """ - - __slots__ = ("has_value", "_value") - - def __init__(self, value=_no_value): - self.has_value = value is not _no_value - if self.has_value: - self._value = value - - def __str__(self): - if not self.has_value: - return "Optional()" - return "Optional(%s)" % self._value - - def __repr__(self): - if not self.has_value: - return "Optional()" - return "Optional(%r)" % self._value - - def __getstate__(self): - if not self.has_value: - return _no_value - - return (self._value,) - - def __setstate__(self, state): - if state is _no_value: - self.has_value = False - return - - self.has_value = True - self._value, = state - - def __eq__(self, other): - if not self.has_value: - return not other.has_value - - return self.value == other.value if other.has_value else False - - def __neq__(self, other): - return not self.__eq__(other) - - @property - def value(self): - if not self.has_value: - raise AttributeError("optional value not present") - return self._value - - def update_persistent_hash(self, key_hash, key_builder): - key_builder.rec( - key_hash, - (self._value,) if self.has_value else ()) - -# }}} - - def unpickles_equally(obj): from six.moves.cPickle import loads, dumps return loads(dumps(obj)) == obj diff --git a/test/test_misc.py b/test/test_misc.py index 7a834a6f5..05df0317a 100644 --- a/test/test_misc.py +++ b/test/test_misc.py @@ -287,46 +287,6 @@ def test_LazilyUnpicklingListWithEqAndPersistentHashing(): # }}} -def test_Optional(): # noqa - from loopy import Optional - - # {{{ test API - - opt = Optional() - assert not opt.has_value - with pytest.raises(AttributeError): - opt.value - - opt = Optional(1) - assert opt.has_value - assert 1 == opt.value - - assert Optional(1) == Optional(1) - assert Optional(1) != Optional(2) - assert Optional() == Optional() - assert Optional() != Optional(1) - - # }}} - - # {{{ test pickling - - import pickle - - assert not pickle.loads(pickle.dumps(Optional())).has_value - assert pickle.loads(pickle.dumps(Optional(1))).value == 1 - - # }}} - - # {{{ test key builder - - from loopy.tools import LoopyKeyBuilder - kb = LoopyKeyBuilder() - kb(Optional()) - kb(Optional(None)) - - # }}} - - if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) -- GitLab