コード例 #1
0
    def testSimpleAssignement(self):
        # simple assignment tests

        #bool
        code_str = "value=True"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(bool))

        # int
        code_str = "value = 1"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(int))

        # float
        code_str = "value = 1.1"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(float))

        # string: should return a char*
        code_str = "value = 'hello'"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.pointer(dtypes.int8))

        # assignment with previous symbols
        prev_symbols = {"char_num": dtypes.typeclass(np.int8)}
        code_str = "value =  char_num"
        inf_symbols = type_inference.infer_types(code_str, prev_symbols)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(np.int8))

        # aug assignment
        code_str = "value += 1.1"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(float))

        # annotated assignments
        code_str = "value : int  = 1"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(int))

        code_str = "value : str"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.pointer(dtypes.int8))

        # type conversion
        # in this case conversion is stricter (int-> int32)
        code_str = "value = int(1.1)"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(np.int))

        code_str = "value = float(1)"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(np.float))
コード例 #2
0
    def testForLoop(self):
        # for loop
        for_loop_code = """for x in range(6):
            res += 1"""
        inf_symbols = type_inference.infer_types(for_loop_code)
        self.assertEqual(inf_symbols["res"], dtypes.typeclass(int))

        #It is not possible to annotate the type of the variable in the loop guard
        # But it is ok to do so outside of the loop
        # https://stackoverflow.com/questions/41641449/how-do-i-annotate-types-in-a-for-loop/41641489#41641489
        for_loop_code = """i: int
for i in range(5):
    x += i"""
        inf_symbols = type_inference.infer_types(for_loop_code)
        self.assertEqual(inf_symbols["x"], dtypes.typeclass(int))
        self.assertEqual(inf_symbols["i"], dtypes.typeclass(int))
コード例 #3
0
ファイル: nodes.py プロジェクト: targetsm/dace
    def infer_connector_types(self, sdfg, state):
        # If a Python tasklet, use type inference to figure out all None output
        # connectors
        if all(cval.type is not None for cval in self.out_connectors.values()):
            return
        if self.code.language != dtypes.Language.Python:
            return

        if any(cval.type is None for cval in self.in_connectors.values()):
            raise TypeError('Cannot infer output connectors of tasklet "%s", '
                            'not all input connectors have types' % str(self))

        # Avoid import loop
        from dace.codegen.tools.type_inference import infer_types

        # Get symbols defined at beginning of node, and infer all types in
        # tasklet
        syms = state.symbols_defined_at(self)
        syms.update(self.in_connectors)
        new_syms = infer_types(self.code.code, syms)
        for cname, oconn in self.out_connectors.items():
            if oconn.type is None:
                if cname not in new_syms:
                    raise TypeError('Cannot infer type of tasklet %s output '
                                    '"%s", please specify manually.' %
                                    (self.label, cname))
                self.out_connectors[cname] = new_syms[cname]
コード例 #4
0
 def testFunction(self):
     code_str = """def f():
 x = 2
 y = 7.5
     """
     inf_symbols = type_inference.infer_types(code_str)
     self.assertEqual(inf_symbols["x"], dtypes.typeclass(int))
     self.assertEqual(inf_symbols["y"], dtypes.typeclass(float))
コード例 #5
0
 def testInputList(self):
     # infer input parameter is a list of code_string
     code1 = "var1 = x + 1.1"
     code2 = "var2 = var1 + 2"
     defined_symbols = {"x": dtypes.typeclass(int)}
     inf_symbols = type_inference.infer_types([code1, code2], defined_symbols)
     self.assertEqual(inf_symbols["var1"], dtypes.typeclass(float))
     self.assertEqual(inf_symbols["var2"], dtypes.typeclass(float))
コード例 #6
0
    def _Assign(self, t):
        self.fill()

        # Handle the case of a tuple output
        if len(t.targets) > 1:
            self.dispatch_lhs_tuple(t.targets)
        else:
            target = t.targets[0]
            if isinstance(target, ast.Tuple):
                if len(target.elts) > 1:
                    self.dispatch_lhs_tuple(target.elts)
                    target = None
                else:
                    target = target.elts[0]

            if target and not isinstance(
                    target,
                (ast.Subscript, ast.Attribute)) and not self.locals.is_defined(
                    target.id, self._indent):

                # if the target is already defined, do not redefine it
                if self.defined_symbols is None or target.id not in self.defined_symbols:
                    # we should try to infer the type
                    if self.type_inference is True:
                        # Perform type inference
                        # Build dictionary with symbols
                        def_symbols = {}
                        def_symbols.update(
                            self.locals.get_name_type_associations())
                        def_symbols.update(self.defined_symbols)
                        inferred_symbols = type_inference.infer_types(
                            t, def_symbols)
                        inferred_type = inferred_symbols[target.id]

                        self.locals.define(target.id, t.lineno, self._indent,
                                           inferred_type)
                        if self.language == dace.dtypes.Language.OpenCL and (
                                inferred_type is not None
                                and inferred_type.veclen > 1):
                            # if the veclen is greater than one, this should be defined with a vector data type
                            self.write("{}{} ".format(
                                dace.dtypes._OCL_VECTOR_TYPES[
                                    inferred_type.type], inferred_type.veclen))
                        else:
                            self.write(dace.dtypes._CTYPES[inferred_type.type] +
                                       " ")
                    else:
                        self.locals.define(target.id, t.lineno, self._indent)
                        self.write("auto ")

            # dispatch target
            if target:
                self.dispatch(target)

        self.write(" = ")
        self.dispatch(t.value)
        #self.dtype = inferred_type
        self.write(';')
コード例 #7
0
    def testExpressionAssignment(self):

        code_str = "res = 5 + 3.1"
        symbols = type_inference.infer_types(code_str)
        self.assertEqual(symbols["res"], dtypes.typeclass(float))

        code_str = "res = 5 + 1"
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["res"], dtypes.typeclass(int))

        # use already defined symbol
        code_str = "res2 = 1 + res"
        symbols = type_inference.infer_types(code_str, symbols)
        self.assertEqual(symbols["res2"], dtypes.typeclass(float))

        code_str = "res3 = 1 + int(res*res2)"
        symbols = type_inference.infer_types(code_str, symbols)
        self.assertEqual(symbols["res3"], dtypes.typeclass(int))
コード例 #8
0
    def testIf(self):
        code_str = """if cond1:
    a = 1*2
elif cond2:
    b = 1.2*3.4
else:
    c = True"""
        inf_symbols = type_inference.infer_types(code_str)
        self.assertEqual(inf_symbols["a"], dtypes.typeclass(int))
        self.assertEqual(inf_symbols["b"], dtypes.typeclass(float))
        self.assertEqual(inf_symbols["c"], dtypes.typeclass(bool))
コード例 #9
0
    def testVarious(self):
        # code snippets that contains constructs not directly involved in type inference
        # (borrowed by astunparse tests)

        while_code = """def g():
    while True:
        break
    z = 3
"""
        inf_symbols = type_inference.infer_types(while_code)
        self.assertEqual(inf_symbols["z"], dtypes.typeclass(int))

        raise_from_code = """try:
    1 / 0
except ZeroDivisionError as e:
    raise ArithmeticError from e
"""
        inf_symbols = type_inference.infer_types(raise_from_code)

        try_except_finally_code = """try:
    suite1
except ex1:
    suite2
except ex2:
    suite3
else:
    suite4
finally:
    suite5
"""
        inf_symbols = type_inference.infer_types(try_except_finally_code)

        #function def with arguments
        function_def_return_code = """def f(arg : float):
    res = 5 + arg
    return res
        """
        inf_symbols = type_inference.infer_types(function_def_return_code)
        self.assertEqual(inf_symbols["res"], dtypes.typeclass(float))
        self.assertEqual(inf_symbols["arg"], dtypes.typeclass(float))
コード例 #10
0
    def testCCode(self):
        # tests for situations that could arise from C/C++ tasklet codes

        ###############################################################################################
        # Pointer: this is a situation that could happen in FPGA backend due to OpenCL Keyword Remover:
        # if in a tasklet, there is an assignment in which the right hand side is a connector and the
        # corresponding memlet is dynamic, the OpenCL Keyword Remover, will update the code to be "target = *rhs"
        # In a similar situation the type inference should not consider the leading *
        stmt = ast.parse("value = float_var")
        stmt.body[0].value.id = "*float_var"  # effect of OpenCL Keyword Remover
        prev_symbols = {"float_var": dtypes.typeclass(float)}
        inf_symbols = type_inference.infer_types(stmt, prev_symbols)
        self.assertEqual(inf_symbols["value"], dtypes.typeclass(float))
コード例 #11
0
ファイル: cppunparse.py プロジェクト: targetsm/dace
 def _arg(self, t):
     if t.annotation:
         self.dispatch(t.annotation)
         self.write(' ')
     else:
         self.write("auto ")
     self.write(t.arg)
     if self.type_inference:
         # Build dictionary with symbols
         def_symbols = self.defined_symbols.copy()
         def_symbols.update(self.locals.get_name_type_associations())
         inferred_symbols = type_inference.infer_types(t, def_symbols)
         inferred_type = inferred_symbols[t.arg]
         self.locals.define(t.arg, t.lineno, self._indent, inferred_type)
     else:
         self.locals.define(t.arg, t.lineno, self._indent)
コード例 #12
0
ファイル: cppunparse.py プロジェクト: targetsm/dace
    def _Assign(self, t):
        self.fill()

        # Handle the case of a tuple output
        if len(t.targets) > 1:
            self.dispatch_lhs_tuple(t.targets)
        else:
            target = t.targets[0]
            if isinstance(target, ast.Tuple):
                if len(target.elts) > 1:
                    self.dispatch_lhs_tuple(target.elts)
                target = target.elts[0]

            if not isinstance(
                    target,
                (ast.Subscript, ast.Attribute)) and not self.locals.is_defined(
                    target.id, self._indent):

                # the target is not already defined: we should try to infer the type
                if self.type_inference is True:
                    # Perform type inference
                    # Build dictionary with symbols
                    def_symbols = {}
                    def_symbols.update(
                        self.locals.get_name_type_associations())
                    def_symbols.update(self.defined_symbols)
                    inferred_symbols = type_inference.infer_types(
                        t, def_symbols)
                    inferred_type = inferred_symbols[target.id]

                    self.locals.define(target.id, t.lineno, self._indent,
                                       inferred_type)
                    self.write(dace.dtypes._CTYPES[inferred_type.type] + " ")
                else:
                    self.locals.define(target.id, t.lineno, self._indent)
                    self.write("auto ")

            # dispatch target
            self.dispatch(target)
            #if not infer_type:
            #   inferred_type = self.dispatch(target, True)
            #self.dtype = inferred_type

        self.write(" = ")
        self.dispatch(t.value)
        #self.dtype = inferred_type
        self.write(';')
コード例 #13
0
    def testInputAST(self):
        # infer input parameter is an AST

        code_str = """var1 = int(in_x)
var2: int = in_y
var3 = 2.1 if (i>1 and i<10) else 2.1 # A comment
res = var1 + var3 * var2
        """

        #create AST
        tree = ast.parse(code_str)
        defined_symbols = {"in_x": dtypes.typeclass(np.float32), "in_y": dtypes.typeclass(np.float32)}
        inf_symbols = type_inference.infer_types(code_str, defined_symbols)
        self.assertEqual(inf_symbols["var1"], dtypes.typeclass(int))
        self.assertEqual(inf_symbols["var2"], dtypes.typeclass(int))
        self.assertEqual(inf_symbols["var3"], dtypes.typeclass(float))
        self.assertEqual(inf_symbols["res"], dtypes.typeclass(float))
コード例 #14
0
    def testDefaultDataTypes(self):
        # check that configuration about defult data types is enforced
        config_data_types = Config.get('compiler', 'default_data_types')

        code_str = """value1 = 10
value2=3.14
value3=5000000000"""
        inf_symbols = type_inference.infer_types(code_str)
        if config_data_types.lower() == "python":
            self.assertEqual(inf_symbols["value1"], dtypes.typeclass(np.int64))
            self.assertEqual(inf_symbols["value2"], dtypes.typeclass(np.float64))
        elif config_data_types.lower() == "c":
            self.assertEqual(inf_symbols["value1"], dtypes.typeclass(np.int32))
            self.assertEqual(inf_symbols["value2"], dtypes.typeclass(np.float32))

        # in any case, value3 needs uint64
        self.assertEqual(inf_symbols["value3"], dtypes.typeclass(np.uint64))
コード例 #15
0
ファイル: cppunparse.py プロジェクト: targetsm/dace
    def _AnnAssign(self, t):
        self.fill()

        if isinstance(t.target, ast.Tuple):
            if len(t.target.elts) > 1:
                self.dispatch_lhs_tuple(t.target.elts)
            else:
                target = t.target.elts[0]
        else:
            target = t.target

        # Assignment of the form x: int = 0 is converted to int x = (int)0;
        if not self.locals.is_defined(target.id, self._indent):
            if self.type_inference is True:
                # get the type indicated into the annotation
                def_symbols = self.defined_symbols.copy()
                def_symbols.update(self.locals.get_name_type_associations())
                inferred_symbols = type_inference.infer_types(t, def_symbols)
                inferred_type = inferred_symbols[target.id]

                self.locals.define(target.id, t.lineno, self._indent,
                                   inferred_type)
            else:
                self.locals.define(target.id, t.lineno, self._indent)

            self.dispatch(t.annotation)
            self.write(' ')
        if not t.simple:
            self.write("(")
        self.dispatch(t.target)
        if not t.simple:
            self.write(")")
        if t.value:
            self.write(" = (")
            self.dispatch(t.annotation)
            self.write(")")
            self.dispatch(t.value)
        self.write(';')
コード例 #16
0
 def testArrayAccess(self):
     code_str = "tmp = array[i]"
     symbols = type_inference.infer_types(
         code_str, {"array": dtypes.typeclass(float)})
     self.assertEqual(symbols["tmp"], dtypes.typeclass(float))
コード例 #17
0
 def testAssignmentIf(self):
     code_str = "res = 5 if x > 10 else 3.1"
     inf_symbols = type_inference.infer_types(code_str)
     self.assertEqual(inf_symbols["res"], dtypes.typeclass(float))
コード例 #18
0
    def infer_connector_types(self, sdfg, state):
        # If a MLIR tasklet, simply read out the types (it's explicit)
        if self.code.language == dtypes.Language.MLIR:
            # Inline import because mlir.utils depends on pyMLIR which may not be installed
            # Doesn't cause crashes due to missing pyMLIR if a MLIR tasklet is not present
            from dace.codegen.targets.mlir import utils

            mlir_ast = utils.get_ast(self.code.code)
            mlir_is_generic = utils.is_generic(mlir_ast)
            mlir_entry_func = utils.get_entry_func(mlir_ast, mlir_is_generic)

            mlir_result_type = utils.get_entry_result_type(
                mlir_entry_func, mlir_is_generic)
            mlir_out_name = next(iter(self.out_connectors.keys()))

            if self.out_connectors[
                    mlir_out_name] is None or self.out_connectors[
                        mlir_out_name].ctype == "void":
                self.out_connectors[mlir_out_name] = utils.get_dace_type(
                    mlir_result_type)
            elif self.out_connectors[mlir_out_name] != utils.get_dace_type(
                    mlir_result_type):
                warnings.warn(
                    "Type mismatch between MLIR tasklet out connector and MLIR code"
                )

            for mlir_arg in utils.get_entry_args(mlir_entry_func,
                                                 mlir_is_generic):
                if self.in_connectors[
                        mlir_arg[0]] is None or self.in_connectors[
                            mlir_arg[0]].ctype == "void":
                    self.in_connectors[mlir_arg[0]] = utils.get_dace_type(
                        mlir_arg[1])
                elif self.in_connectors[mlir_arg[0]] != utils.get_dace_type(
                        mlir_arg[1]):
                    warnings.warn(
                        "Type mismatch between MLIR tasklet in connector and MLIR code"
                    )

            return

        # If a Python tasklet, use type inference to figure out all None output
        # connectors
        if all(cval.type is not None for cval in self.out_connectors.values()):
            return
        if self.code.language != dtypes.Language.Python:
            return

        if any(cval.type is None for cval in self.in_connectors.values()):
            raise TypeError('Cannot infer output connectors of tasklet "%s", '
                            'not all input connectors have types' % str(self))

        # Avoid import loop
        from dace.codegen.tools.type_inference import infer_types

        # Get symbols defined at beginning of node, and infer all types in
        # tasklet
        syms = state.symbols_defined_at(self)
        syms.update(self.in_connectors)
        new_syms = infer_types(self.code.code, syms)
        for cname, oconn in self.out_connectors.items():
            if oconn.type is None:
                if cname not in new_syms:
                    raise TypeError('Cannot infer type of tasklet %s output '
                                    '"%s", please specify manually.' %
                                    (self.label, cname))
                self.out_connectors[cname] = new_syms[cname]