diff --git a/loopy/kernel/function_interface.py b/loopy/kernel/function_interface.py index a87c1670aab6ae3ee2ce95a695b3b6bcaa12a38c..bc5d178b13bdd66f37f5f0b59238d6ba248512bd 100644 --- a/loopy/kernel/function_interface.py +++ b/loopy/kernel/function_interface.py @@ -134,19 +134,24 @@ class InKernelCallable(ImmutableRecord): """ + fields = set(["name", "arg_id_to_dtype", "arg_id_to_descr"]) + init_arg_names = ("name", "arg_id_to_dtype", "arg_id_to_descr") + def __init__(self, name, arg_id_to_dtype=None, arg_id_to_descr=None): - # {{{ sanity checks + # sanity checks if not isinstance(name, str): raise LoopyError("name of an InKernelCallable should be a string") - # }}} - super(InKernelCallable, self).__init__(name=name, arg_id_to_dtype=arg_id_to_dtype, arg_id_to_descr=arg_id_to_descr) + def __getinitargs__(self): + return (self.name, self.arg_id_to_dtype, self.arg_id_to_descr, + self.name_in_target) + def with_types(self, arg_id_to_dtype, target): """ :arg arg_id_to_type: a mapping from argument identifiers @@ -207,10 +212,7 @@ class InKernelCallable(ImmutableRecord): def is_ready_for_code_gen(self): return (self.arg_id_to_dtype is not None and - self.arg_id_to_descr is not None and - self.name_in_target is not None) - - # {{{ code generation + self.arg_id_to_descr is not None) def generate_preambles(self, target): """ This would generate the target specific preamble. @@ -225,7 +227,9 @@ class InKernelCallable(ImmutableRecord): raise NotImplementedError() - # }}} + def __hash__(self): + + return hash(tuple(self.fields)) # }}} @@ -405,6 +409,8 @@ class CallableKernel(InKernelCallable): super(InKernelCallable, self).__init__(name=name, arg_id_to_dtype=arg_id_to_dtype, arg_id_to_descr=arg_id_to_descr) + if name_in_target is not None: + subkernel = subkernel.copy(name=name_in_target) self.name_in_target = name_in_target self.subkernel = subkernel @@ -496,12 +502,10 @@ class CallableKernel(InKernelCallable): self.arg_id_to_descr is not None and self.name_in_target is not None) - # {{{ code generation - def generate_preambles(self, target): """ This would generate the target specific preamble. """ - # Transfer the preambel of the subkernel over here + # TODO: Transfer the preamble of the subkernel over here raise NotImplementedError() def emit_call_insn(self, insn, target, expression_to_code_mapper): @@ -545,81 +549,9 @@ class CallableKernel(InKernelCallable): from pymbolic import var return var(self.name_in_target)(*c_parameters) - # }}} - # }}} - - - - -class ReductionCallable(InKernelCallable): - - fields = set(["name", "operation", "arg_id_to_dtype", "arg_id_to_descr"]) - init_arg_names = ("name", "operation", "arg_id_to_dtype", "arg_id_to_descr") - - def __init__(self, name, operation, arg_id_to_dtype=None, - arg_id_to_descr=None, name_in_target=None): - - super(InKernelCallable, self).__init__(name=name, - arg_id_to_dtype=arg_id_to_dtype, - arg_id_to_descr=arg_id_to_descr) - - self.operation = operation - - def with_types(self, arg_id_to_dtype, target): - if self.arg_id_to_dtype is not None: - - # specializing an already specialized function. - - for id, dtype in arg_id_to_dtype.items(): - # only checking for the ones which have been provided - if self.arg_id_to_dtype[id] != arg_id_to_dtype[id]: - raise LoopyError("Overwriting a specialized" - " function is illegal--maybe start with new instance of" - " CallableScalar?") - - if self.name in target.get_device_ast_builder().function_identifiers(): - new_in_knl_callable = target.get_device_ast_builder().with_types( - self, arg_id_to_dtype) - if new_in_knl_callable is None: - new_in_knl_callable = self.copy() - return new_in_knl_callable - - # did not find a scalar function and function prototype does not - # even have subkernel registered => no match found - raise LoopyError("Function %s not present within" - " the %s namespace" % (self.name, target)) - - def with_descrs(self, arg_id_to_descr): - - # This is a scalar call - # need to assert that the name is in funtion indentifiers - arg_id_to_descr[-1] = ValueArgDescriptor() - return self.copy(arg_id_to_descr=arg_id_to_descr) - - def with_iname_tag_usage(self, unusable, concurrent_shape): - - raise NotImplementedError() - - def is_ready_for_code_gen(self): - - return (self.arg_id_to_dtype is not None and - self.arg_id_to_descr is not None and - self.name_in_target is not None) - - - - - - - - - - - - # {{{ new pymbolic calls to scoped functions def next_indexed_name(name):