Пример #1
0
    def op_kernel(self, op):
        if op not in self.jitted:
            return op

        uses = self.func.uses[op]

        if all(u in self.trees for u in uses):
            # All our consumers know about us and have us as an argument
            # in their tree! Delete this op, only the root will perform a
            # rewrite.
            self.delete_later.append(op)
        elif any(u in self.trees for u in uses):
            # Some consumers have us as a node, but others don't. This
            # forms a ckernel boundary, so we need to detach ourselves!
            raise NotImplementedError
        else:
            # No consumer has us as an internal node in the kernel tree, we
            # are a kerneltree root
            tree = self.trees[op]
            # out_rank = len(op.type.shape)
            # tree = tree.adapt(out_rank, llvm_array.C_CONTIGUOUS)
            ckernel_deferred = tree.make_ckernel_deferred(op.type)

            # Flatten the tree of args, removing duplicates just
            # as the kernel tree does.
            args = []
            for arg in op.args[1:]: # Skip op.args[0], the kernel string name
                for ir_arg, kt_arg in self.arguments[arg]:
                    if ir_arg not in args:
                        args.append(ir_arg)

            new_op = Op('ckernel', op.type, [ckernel_deferred, args], op.result)
            new_op.add_metadata({'rank': 0,
                                 'parallel': True})
            return new_op
Пример #2
0
def _from_expr(expr, f, builder, values):
    if expr.opcode == 'array':
        result = values[expr]
    else:
        # -------------------------------------------------
        # Construct args

        # This is purely for IR readability
        name = qualified_name(expr.metadata['overload'].func)
        args = [_from_expr(arg, f, builder, values) for arg in expr.args]
        args = [Const(name)] + args

        # -------------------------------------------------
        # Construct Op

        result = Op("kernel", expr.dshape, args)

        # Copy metadata verbatim
        assert 'kernel' in expr.metadata
        assert 'overload' in expr.metadata
        result.add_metadata(expr.metadata)

        # -------------------------------------------------
        # Emit Op in code stream

        builder.emit(result)

    values[expr] = result
    return result
Пример #3
0
    def op_kernel(self, op):
        if op not in self.trees:
            return op

        uses = self.func.uses[op]

        if all(u in self.trees for u in uses):
            # All our consumers know about us and have us as an argument
            # in their tree! Delete this op, only the root will perform a
            # rewrite.
            self.delete_later.append(op)
        elif any(u in self.trees for u in uses):
            # Some consumers have us as a node, but others don't. This
            # forms a ckernel boundary, so we need to detach ourselves!
            raise NotImplementedError
        else:
            # No consumer has us as an internal node in the kernel tree, we
            # are a kerneltree root
            tree = self.trees[op]
            # out_rank = len(op.type.shape)
            # tree = tree.adapt(out_rank, llvm_array.C_CONTIGUOUS)
            unbound_ckernel = tree.make_unbound_ckernel(strided=False)
            # Skip kernel string name, first arg to 'kernel' Operations
            args = [ir_arg for arg in op.args[1:]
                               for ir_arg, kt_arg in self.arguments[arg]]
            new_op = Op('ckernel', op.type, [unbound_ckernel, args], op.result)
            new_op.add_metadata({'rank': 0,
                                 'parallel': True})
            return new_op
Пример #4
0
    def op_kernel(self, op):
        if self.strategies[op] != 'ckernel':
            return

        function = op.metadata['kernel']
        overload = op.metadata['overload']

        func = overload.func
        polysig = overload.sig
        monosig = overload.resolved_sig
        argtypes = datashape.coretypes.Tuple(monosig.argtypes)

        try:
            overload = function.best_match('ckernel', argtypes)
        except datashape.CoercionError:
            return op

        impl = overload.func
        assert monosig == overload.resolved_sig, (monosig,
                                                  overload.resolved_sig)

        new_op = Op('ckernel', op.type, [impl, op.args[1:]], op.result)
        new_op.add_metadata({'rank': 0,
                             'parallel': True})
        return new_op
Пример #5
0
 def _process(self, ty, args=None, result=None, **metadata):
     if args is None:
         args = []
     assert ty is not None
     assert isinstance(args, list), args
     assert not any(arg is None for arg in flatten(args)), args
     result = Op(op, ty, args, result)
     if metadata:
         result.add_metadata(metadata)
     self._insert_op(result)
     return result
Пример #6
0
 def op_kernel(self, op):
     function = op.metadata['kernel']
     overload = op.metadata['overload']
     func = overload.func
     polysig = overload.sig
     monosig = overload.resolved_sig
     impls = function.find_impls(func, polysig, 'ckernel')
     if impls:
         [impl] = impls
         new_op = Op('ckernel', op.type, [impl, op.args[1:]], op.result)
         new_op.add_metadata({'rank': 0,
                              'parallel': True})
         return new_op
     return op
Пример #7
0
    def op_kernel(self, op):
        function = op.metadata['kernel']
        overload = op.metadata['overload']

        func = overload.func
        polysig = overload.sig
        monosig = overload.resolved_sig
        argtypes = monosig.argtypes

        if function.matches('ckernel', argtypes):
            overload = function.best_match('ckernel', argtypes)
            impl = overload.func
            assert monosig == overload.resolved_sig, (monosig,
                                                      overload.resolved_sig)

            new_op = Op('ckernel', op.type, [impl, op.args[1:]], op.result)
            new_op.add_metadata({'rank': 0,
                                 'parallel': True})
            return new_op
        return op
Пример #8
0
def copy_function(func, temper=None, module=None):
    """Copy a Function. `temper` may be given to"""
    temper = temper or make_temper()
    f = Function(func.name, list(func.argnames), func.type, temper=temper)
    valuemap = {}
    lookup = partial(_lookup, module or func.module, f, valuemap)

    ### Construct new Blocks
    for block in func.blocks:
        new_block = Block(temper(block.name), f)
        valuemap[block] = new_block
        f.add_block(new_block)

    ### Construct new Operations
    for block in func.blocks:
        new_block = valuemap[block]
        for op in block.ops:
            if op.opcode == 'phi':
                # Phi nodes may be circular, or may simply precede some of
                # their arguments
                args = []
            else:
                args = nestedmap(lookup, op.args)

            new_op = Op(op.opcode, op.type, args,
                        result=temper(op.result), parent=new_block)

            new_op.add_metadata(op.metadata)
            # assert new_op.result != op.result

            valuemap[op] = new_op
            new_block.append(new_op)

    for old_op in func.ops:
        if old_op.opcode == 'phi':
            new_op = valuemap[old_op]
            new_op.set_args(nestedmap(lookup, old_op.args))

    return f
Пример #9
0
 def insert(self, opcode, *args):
     type = types.Void if ops.is_void(opcode) else types.Opaque
     op = Op(opcode, type, list(args))
     op.add_metadata({'lineno': self.lineno})
     self.builder.emit(op)
     return op