Example #1
0
def _BinOp(t, symbols, inferred_symbols):
    # Operations that require a function call
    if t.op.__class__.__name__ in cppunparse.CPPUnparser.funcops:
        separator, func = cppunparse.CPPUnparser.funcops[
            t.op.__class__.__name__]

        # get the type of left and right operands for type inference
        type_left = _dispatch(t.left, symbols, inferred_symbols)
        type_right = _dispatch(t.right, symbols, inferred_symbols)
        # infer type and returns
        return dtypes.result_type_of(type_left, type_right)
    # Special case for integer power
    elif t.op.__class__.__name__ == 'Pow':
        if (isinstance(t.right, (ast.Num, ast.Constant))
                and int(t.right.n) == t.right.n and t.right.n >= 0):
            if t.right.n != 0:
                type_left = _dispatch(t.left, symbols, inferred_symbols)
                for i in range(int(t.right.n) - 1):
                    _dispatch(t.left, symbols, inferred_symbols)
            return dtypes.result_type_of(type_left,
                                         dtypes.typeclass(np.uint32))
        else:
            type_left = _dispatch(t.left, symbols, inferred_symbols)
            type_right = _dispatch(t.right, symbols, inferred_symbols)
            return dtypes.result_type_of(type_left, type_right)
    else:

        # get left and right types for type inference
        type_left = _dispatch(t.left, symbols, inferred_symbols)
        type_right = _dispatch(t.right, symbols, inferred_symbols)
        return dtypes.result_type_of(type_left, type_right)
Example #2
0
def _Call(t, symbols, inferred_symbols):
    inf_type = _dispatch(t.func, symbols, inferred_symbols)

    # Dispatch the arguments and determine their types
    arg_types = [_dispatch(e, symbols, inferred_symbols) for e in t.args]

    for e in t.keywords:
        _dispatch(e, symbols, inferred_symbols)

    # If the function symbol is known, always return the defined type
    if inf_type:
        return inf_type

    # In case of a typeless math function, determine the return type based on the arguments
    name = dace.frontend.python.astutils.rname(t)
    module = name[:name.rfind('.')]
    if module == 'math':
        return dtypes.result_type_of(arg_types[0], *arg_types)

    # Reading from an Intel channel returns the channel type
    if name == 'read_channel_intel':
        return arg_types[0]

    if name in ('abs', 'log'):
        return arg_types[0]

    # dtypes (dace.int32, np.float64) can be used as functions
    inf_type = _infer_dtype(t)
    if inf_type:
        return inf_type

    # In any other case simply return None
    return None
Example #3
0
def _Constant(t, symbols, inferred_symbols):
    # String value
    if isinstance(t.value, (str, bytes)):
        return dtypes.pointer(dtypes.int8)

    # Numeric value
    return dtypes.result_type_of(dtypes.typeclass(type(t.value)), dtypes.typeclass(np.min_scalar_type(t.value).name))
Example #4
0
    def _Compare(self, t):
        if len(t.ops) != 1:
            # This includes things like  a < b <= c
            raise NotImplementedError(
                'Multiple comparisons at once not implemented')

        lhs = t.left
        op = t.ops[0]
        rhs = t.comparators[0]

        self.assert_type_compatibility(*self.infer(lhs, rhs))

        if not isinstance(self.infer(t)[0], (dtypes.vector, dtypes.pointer)):
            return super()._Compare(t)

        if op.__class__ not in util.COMPARE_TO_SVE:
            raise NotImplementedError('Comparator not supported')

        self.write('{}({}, '.format(util.COMPARE_TO_SVE[op.__class__],
                                    self.pred_name))

        lhs_type, rhs_type = self.infer(lhs, rhs)
        res_type = dtypes.result_type_of(lhs_type, rhs_type)

        self.dispatch_expect(lhs, res_type)
        self.write(', ')
        self.dispatch_expect(rhs, res_type)
        self.write(')')
Example #5
0
def _IfExp(t, symbols, inferred_symbols):
    type_test = _dispatch(t.test, symbols, inferred_symbols)
    type_body = _dispatch(t.body, symbols, inferred_symbols)
    type_orelse = _dispatch(t.orelse, symbols, inferred_symbols)
    res_type = dtypes.result_type_of(type_body, type_orelse)
    if isinstance(type_test, dtypes.vector) and not isinstance(res_type, (dtypes.vector, dtypes.pointer)):
        # If we test on a vector, the result should be a vector aswell
        # so we can do a selection based on the test predicate
        res_type = dtypes.vector(res_type, type_test.veclen)
    return res_type
Example #6
0
    def _IfExp(self, t):
        if util.only_scalars_involed(self.get_defined_symbols(), t.test,
                                     t.body, t.orelse):
            return super()._IfExp(t)

        if_type, else_type = self.infer(t.body, t.orelse)
        res_type = dtypes.result_type_of(if_type, else_type)
        if not isinstance(res_type, dtypes.vector):
            res_type = dtypes.vector(res_type, -1)

        self.write('svsel(')
        self.dispatch_expect(t.test, dtypes.vector(dace.bool, -1))
        self.write(', ')
        self.dispatch_expect(t.body, res_type)
        self.write(', ')
        self.dispatch_expect(t.orelse, res_type)
        self.write(')')
Example #7
0
    def _BinOp(self, t):
        lhs_type, rhs_type = self.infer(t.left, t.right)
        res_type = dtypes.result_type_of(lhs_type, rhs_type)

        if not isinstance(res_type, (dtypes.vector, dtypes.pointer)):
            return super()._BinOp(t)

        if t.op.__class__ not in util.BIN_OP_TO_SVE:
            raise NotImplementedError(
                f'Binary operation {t.op.__class__.__name__} not implemented')

        op_name = util.BIN_OP_TO_SVE[t.op.__class__]

        self.write('{}_x({}, '.format(op_name, self.pred_name))
        self.dispatch_expect(t.left, res_type)
        self.write(', ')
        self.dispatch_expect(t.right, res_type)
        self.write(')')
Example #8
0
    def new_symbols(self, sdfg, state, symbols) -> Dict[str, dtypes.typeclass]:
        from dace.codegen.tools.type_inference import infer_expr_type

        result = {}
        # Add map params
        for p, rng in zip(self._map.params, self._map.range):
            result[p] = dtypes.result_type_of(infer_expr_type(rng[0], symbols),
                                              infer_expr_type(rng[1], symbols))

        # Add dynamic inputs
        dyn_inputs = set(c for c in self.in_connectors
                         if not c.startswith('IN_'))

        # TODO: Get connector type from connector
        for e in state.in_edges(self):
            if e.dst_conn in dyn_inputs:
                result[e.dst_conn] = sdfg.arrays[e.data.data].dtype

        return result
Example #9
0
def _Call(t, symbols, inferred_symbols):
    inf_type = _dispatch(t.func, symbols, inferred_symbols)

    # Dispatch the arguments and determine their types
    arg_types = [_dispatch(e, symbols, inferred_symbols) for e in t.args]

    for e in t.keywords:
        _dispatch(e, symbols, inferred_symbols)

    # If the function symbol is known, always return the defined type
    if inf_type:
        return inf_type

    # In case of a typeless math function, determine the return type based on the arguments
    name = dace.frontend.python.astutils.rname(t)
    module = name[:name.rfind('.')]
    if module == 'math':
        return dtypes.result_type_of(arg_types[0], *arg_types)

    # In any other case simply return None
    return None
Example #10
0
def _IfExp(t, symbols, inferred_symbols):
    _dispatch(t.test, symbols, inferred_symbols)
    type_body = _dispatch(t.body, symbols, inferred_symbols)
    type_orelse = _dispatch(t.orelse, symbols, inferred_symbols)
    return dtypes.result_type_of(type_body, type_orelse)
Example #11
0
def _Num(t, symbols, inferred_symbols):
    # get the minimum between the minimum type needed to represent this number and the corresponding default data types
    # e.g., if num=1, then it will be represented by using the default integer type (int32 if C data types are used)
    return dtypes.result_type_of(
        dtypes.typeclass(type(t.n)),
        dtypes.typeclass(np.min_scalar_type(t.n).name))
Example #12
0
def _NameConstant(t, symbols, inferred_symbols):
    return dtypes.result_type_of(
        dtypes.typeclass(type(t.value)),
        dtypes.typeclass(np.min_scalar_type(t.value).name))