diff --git a/loopy/library/tuple.py b/loopy/library/tuple.py index dd6b553ebceec216834c0999f9ac914c92c87312..ce2865ff58483ced9bb6ed78bdc171cd83a6d5e5 100644 --- a/loopy/library/tuple.py +++ b/loopy/library/tuple.py @@ -29,40 +29,10 @@ def tuple_function_mangler(kernel, name, arg_dtypes): if name == "make_tuple": from loopy.kernel.data import CallMangleInfo return CallMangleInfo( - target_name=tuple_function_name(*arg_dtypes), + target_name="loopy_make_tuple", result_dtypes=arg_dtypes, arg_dtypes=arg_dtypes) return None - -def tuple_function_name(dtype0, dtype1): - return "loopy_tuple_%s_%s" % ( - dtype0.numpy_dtype.type.__name__, dtype1.numpy_dtype.type.__name__) - - -def get_tuple_preamble(kernel, func_id, arg_dtypes): - name = tuple_function_name(*arg_dtypes) - return (name, """ - inline %(t0)s %(name)s(%(t0)s i0, %(t1)s i1, %(t1)s *o1) - { - *o1 = i1; - return i0; - } - """ % dict(name=name, - t0=kernel.target.dtype_to_typename(arg_dtypes[0]), - t1=kernel.target.dtype_to_typename(arg_dtypes[1]))) - - -def tuple_preamble_generator(preamble_info): - from loopy.target.opencl import OpenCLTarget - - for func in preamble_info.seen_functions: - if func.name == "make_tuple": - if not isinstance(preamble_info.kernel.target, OpenCLTarget): - raise LoopyError("only OpenCL supported for now") - - yield get_tuple_preamble(preamble_info.kernel, func.name, - func.arg_dtypes) - # vim: fdm=marker diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index e4835a3638b43619f9b93f45958382218b701642..ed1ba1ce9147cd7d2244031c5099a840d375ad29 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -648,6 +648,36 @@ class CASTBuilder(ASTBuilderBase): lhs_expr, rhs_expr, lhs_dtype): raise NotImplementedError("atomic updates in %s" % type(self).__name__) + def emit_tuple_assignment(self, codegen_state, insn): + ecm = codegen_state.expression_to_code_mapper + + parameters = insn.expression.parameters + parameter_dtypes = tuple(ecm.infer_type(par) for par in parameters) + + from cgen import Assign, block_if_necessary + assignments = [] + + for i, (assignee, tgt_dtype) in enumerate( + zip(insn.assignees, parameter_dtypes)): + if tgt_dtype != ecm.infer_type(assignee): + raise LoopyError("type mismatch in %d'th (0-based) left-hand " + "side of instruction '%s'" % (i, insn.id)) + + lhs_code = ecm(assignee, prec=PREC_NONE, type_context=None) + assignee_var_name = insn.assignee_var_names()[i] + lhs_var = codegen_state.kernel.get_var_descriptor(assignee_var_name) + lhs_dtype = lhs_var.dtype + + from loopy.expression import dtype_to_type_context + rhs_type_context = dtype_to_type_context( + codegen_state.kernel.target, lhs_dtype) + rhs_code = ecm(parameters[i], prec=PREC_NONE, + type_context=rhs_type_context, needed_dtype=lhs_dtype) + + assignments.append(Assign(lhs_code, rhs_code)) + + return block_if_necessary(assignments) + def emit_multiple_assignment(self, codegen_state, insn): ecm = codegen_state.expression_to_code_mapper @@ -674,6 +704,9 @@ class CASTBuilder(ASTBuilderBase): assert mangle_result.arg_dtypes is not None + if mangle_result.target_name == "loopy_make_tuple": + return self.emit_tuple_assignment(codegen_state, insn) + from loopy.expression import dtype_to_type_context c_parameters = [ ecm(par, PREC_NONE, diff --git a/loopy/target/opencl.py b/loopy/target/opencl.py index e70acfeabbded0e52e69f62155c416c2485dbcd6..a5f7562c41c3ec8eca673904550e078d2a992241 100644 --- a/loopy/target/opencl.py +++ b/loopy/target/opencl.py @@ -390,13 +390,11 @@ class OpenCLCASTBuilder(CASTBuilder): def preamble_generators(self): from loopy.library.reduction import reduction_preamble_generator - from loopy.library.tuple import tuple_preamble_generator return ( super(OpenCLCASTBuilder, self).preamble_generators() + [ opencl_preamble_generator, reduction_preamble_generator, - tuple_preamble_generator ]) # }}}