Пример #1
0
    def visit_For(self, node):
        """restricted, for now, to range as iterator with long-type args"""
        if isinstance(node, ast.For) and \
           isinstance(node.iter, ast.Call) and \
           isinstance(node.iter.func, ast.Name) and \
           node.iter.func.id == 'range':
            Range = node.iter
            nArgs = len(Range.args)
            if nArgs == 1:
                stop = self.visit(Range.args[0])
                start, step = Constant(0), Constant(1)
            elif nArgs == 2:
                start, stop = map(self.visit, Range.args)
                step = Constant(1)
            elif nArgs == 3:
                start, stop, step = map(self.visit, Range.args)
            else:
                raise Exception("Cannot convert a for...range with %d args." % nArgs)

            # TODO allow any expressions castable to Long type
            assert isinstance(stop.get_type(), c_long), "Can only convert range's with stop values of Long type."
            assert isinstance(start.get_type(), c_long), "Can only convert range's with start values of Long type."
            assert isinstance(step.get_type(), c_long), "Can only convert range's with step values of Long type."

            target = SymbolRef(node.target.id, c_long())
            for_loop = For(
                Assign(target, start),
                Lt(target.copy(), stop),
                AddAssign(target.copy(), step),
                [self.visit(stmt) for stmt in node.body],
            )
            return for_loop
        node.body = list(map(self.visit, node.body))
        return node
Пример #2
0
def clEnqueueNDRangeKernel(queue, kernel, work_dim=1, work_offset=0, global_size=0, local_size=0):
    assert isinstance(queue, SymbolRef)
    assert isinstance(kernel, SymbolRef)
    global_size_sym = SymbolRef('global_size', c_size_t())
    local_size_sym = SymbolRef('local_size', c_size_t())
    call = FunctionCall(SymbolRef("clEnqueueNDRangeKernel"), [
        queue, kernel,
        work_dim, work_offset,
        Ref(global_size_sym.copy()), Ref(local_size_sym.copy()),
        0, NULL(), NULL()
    ])

    return Block([
        Assign(global_size_sym, Constant(global_size)),
        Assign(local_size_sym, Constant(local_size)),
        call
    ])
Пример #3
0
    def visit_For(self, node):
        """restricted, for now, to range as iterator with long-type args"""
        if isinstance(node, ast.For) and \
           isinstance(node.iter, ast.Call) and \
           isinstance(node.iter.func, ast.Name) and \
           node.iter.func.id in ('range', 'xrange'):
            Range = node.iter
            nArgs = len(Range.args)
            if nArgs == 1:
                stop = self.visit(Range.args[0])
                start, step = Constant(0), Constant(1)
            elif nArgs == 2:
                start, stop = map(self.visit, Range.args)
                step = Constant(1)
            elif nArgs == 3:
                start, stop, step = map(self.visit, Range.args)
            else:
                raise Exception("Cannot convert a for...range with %d args." %
                                nArgs)

            #  check no-op conditions.
            if all(isinstance(item, Constant) for item in (start, stop, step)):
                if step.value == 0:
                    raise ValueError("range() step argument must not be zero")
                elif start.value == stop.value or \
                        (start.value < stop.value and step.value < 0) or \
                        (start.value > stop.value and step.value > 0):
                    return None

            if not all(
                    isinstance(item, CtreeNode)
                    for item in (start, stop, step)):
                node.body = list(map(self.visit, node.body))
                return node

            # TODO allow any expressions castable to Long type
            target_types = [c_long]
            for el in (stop, start, step):
                #  typed item to try and guess type off of. Imperfect right now.
                if hasattr(el, 'get_type'):
                    # TODO take the proper class instead of the last; if start,
                    # end are doubles, but step is long, target is double
                    t = el.get_type()
                    assert any(
                        isinstance(t, klass)
                        for klass in [c_byte, c_int, c_long, c_short]
                    ), "Can only convert ranges with integer/long \
                         start/stop/step values"

                    target_types.append(type(t))
            target_type = get_common_ctype(target_types)()

            target = SymbolRef(node.target.id, target_type)
            op = Lt
            if hasattr(start, 'value') and hasattr(stop, 'value') and \
                    start.value > stop.value:
                op = Gt
            for_loop = For(
                Assign(target, start),
                op(target.copy(), stop),
                AddAssign(target.copy(), step),
                [self.visit(stmt) for stmt in node.body],
            )
            return for_loop
        node.body = list(map(self.visit, node.body))
        return node
Пример #4
0
    def visit_For(self, node):
        """restricted, for now, to range as iterator with long-type args"""
        if (
            isinstance(node, ast.For)
            and isinstance(node.iter, ast.Call)
            and isinstance(node.iter.func, ast.Name)
            and node.iter.func.id in ("range", "xrange")
        ):
            Range = node.iter
            nArgs = len(Range.args)
            if nArgs == 1:
                stop = self.visit(Range.args[0])
                start, step = Constant(0), Constant(1)
            elif nArgs == 2:
                start, stop = map(self.visit, Range.args)
                step = Constant(1)
            elif nArgs == 3:
                start, stop, step = map(self.visit, Range.args)
            else:
                raise Exception("Cannot convert a for...range with %d args." % nArgs)

            #  check no-op conditions.
            if all(isinstance(item, Constant) for item in (start, stop, step)):
                if step.value == 0:
                    raise ValueError("range() step argument must not be zero")
                elif (
                    start.value == stop.value
                    or (start.value < stop.value and step.value < 0)
                    or (start.value > stop.value and step.value > 0)
                ):
                    return None

            if not all(isinstance(item, CtreeNode) for item in (start, stop, step)):
                node.body = list(map(self.visit, node.body))
                return node

            # TODO allow any expressions castable to Long type
            target_types = [c_long]
            for el in (stop, start, step):
                #  typed item to try and guess type off of. Imperfect right now.
                if hasattr(el, "get_type"):
                    # TODO take the proper class instead of the last; if start,
                    # end are doubles, but step is long, target is double
                    t = el.get_type()
                    assert any(
                        isinstance(t, klass) for klass in [c_byte, c_int, c_long, c_short]
                    ), "Can only convert ranges with integer/long \
                         start/stop/step values"
                    target_types.append(type(t))
            target_type = get_common_ctype(target_types)()

            target = SymbolRef(node.target.id, target_type)
            op = Lt
            if hasattr(start, "value") and hasattr(stop, "value") and start.value > stop.value:
                op = Gt
            for_loop = For(
                Assign(target, start),
                op(target.copy(), stop),
                AddAssign(target.copy(), step),
                [self.visit(stmt) for stmt in node.body],
            )
            return for_loop
        node.body = list(map(self.visit, node.body))
        return node