예제 #1
0
 def visit_If(self, node):
     cond = self.visit(node.cond)
     if (not issubclass(cond.type, BoolType)):
         raise exceptions.LambdaPackTypeException("cond of if statement must be BoolType")
     body = [self.visit(x) for x in node.body]
     else_body = [self.visit(x) for x in node.elseBody]
     return If(cond, body, else_body)
예제 #2
0
    def visit_IndexExpr(self, node):
        if (isinstance(node.indices, list)):
            idxs = [self.visit(x) for x in node.indices]
        else:
            idxs = [self.visit(node.indices)]

        out_type = unify([x.type for x in idxs])
        if (not issubclass(out_type, IntType)):
            print("out_type", out_type)
            raise exceptions.LambdaPackTypeException("Indices in IndexExprs must all of type LinearIntType {0}[{1}]".format(node.matrix_name, [str(x) for x in node.indices]))
        return IndexExpr(node.matrix_name, idxs)
예제 #3
0
 def visit_Assign(self, node):
     rhs = self.visit(node.rhs)
     lhs = node.lhs
     if (lhs.name in self.decl_types):
         is_subclass = issubclass(rhs.type, self.decl_types[lhs.name])
         is_superclass  = issubclass(self.decl_types[lhs.name], rhs.type)
         if ((not is_subclass) and (not is_superclass)):
             raise exceptions.LambdaPackTypeException("Variables must be of unifiable type, {0} is type {1} but was assigned {2}".format(lhs.name, self.decl_types[lhs.name], rhs.type))
     else:
         self.decl_types[lhs.name] = rhs.type
     lhs = self.visit(node.lhs)
     return Assign(lhs, rhs)
예제 #4
0
    def visit_For(self, node):
        self.decl_types[node.var] = LinearIntType
        min_idx = self.visit(node.min)
        max_idx = self.visit(node.max)
        linear_max = issubclass(min_idx.type, LinearIntType)
        linear_min = issubclass(min_idx.type, LinearIntType)
        if ((not linear_max) or (not linear_min)):
            raise exceptions.LambdaPackTypeException(
                "Loop bounds must be LinearIntType")

        step = self.visit(node.step)
        body = [self.visit(x) for x in node.body]
        return For(node.var, min_idx, max_idx, step, body)
예제 #5
0
def unify(type_list):
    if (len(type_list) == 1): return type_list[0]
    if (len(type_list) < 3):
        t0 = type_list[0]
        t1 = type_list[0]
        if (issubclass(t0, t1)):
            return t1
        elif (issubclass(t1, t0)):
            return t0
        else:
            raise exceptions.LambdaPackTypeException("Non unifiable types {0} vs {1}".format(type_list))
    else:
        t0,t1 = type_list[0], type_list[1]
        t01 = unify([t0, t1])
        return unify([t01] + type_list[2:])
예제 #6
0
 def visit_Reduction(self, node):
     self.decl_types[node.var] = LinearIntType
     min_idx = self.visit(node.min)
     max_idx = self.visit(node.max)
     if (isinstance(node.expr, list)):
         expr = [self.visit(x) for x in node.expr]
     else:
         expr = [self.visit(node.expr)]
     for expr_i in expr:
         if (not isinstance(expr_i, IndexExpr)):
             raise exceptions.LambdaPackTypeException(
                 "Reduction Exprs must be of IndexExpr type")
     b_fac = self.visit(node.b_fac)
     remote_call = self.visit(node.remote_call)
     recursion = [self.visit(x) for x in node.recursion]
     return Reduction(node.var, min_idx, max_idx, expr, b_fac, remote_call,
                      recursion)
예제 #7
0
def python_type_to_lp_type(p_type, const=False):
    if (p_type is None):
        return NullType
    if (issubclass(p_type, int)):
        if (const):
            return ConstIntType
        else:
            return IntType
    elif (issubclass(p_type, float)):
        if (const):
            return ConstFloatType
        else:
            return FloatType
    elif (issubclass(p_type, bool)):
        return BoolType
    elif (issubclass(p_type, BigMatrix)):
        return BigMatrixType
    else:
        raise exceptions.LambdaPackTypeException("Unsupported Python type: {0}".format(p_type))
예제 #8
0
 def visit_BinOp(self, node):
     right = self.visit(node.right)
     left = self.visit(node.left)
     r_type = right.type
     l_type = left.type
     op = node.op
     if (op == "Or" or op == "And"):
         assert(issubclass(left.type, BoolType))
         assert(issubclass(right.type, BoolType))
         out_type = BoolType
     else:
         if ((r_type is None) or (l_type is None)):
             raise LambdaPackTypeException("BinOp arguments must be typed")
         type_set = set([r_type, l_type])
         for t in type_set:
             if (not issubclass(t, NumericalType)):
                 raise LambdaPackTypeException("BinOp arguments must be Numerical")
         if (op == "Add" or op == "Sub"):
             # arith type algebra
             if (issubclass(r_type, ConstIntType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstIntType
             elif (issubclass(r_type, LinearIntType) and issubclass(l_type, LinearIntType)):
                 out_type = LinearIntType
             elif (issubclass(r_type, IntType) and issubclass(l_type, IntType)):
                 out_type = IntType
             elif (issubclass(r_type, ConstFloatType) and issubclass(l_type, ConstFloatType)):
                 out_type = ConstFloatType
             elif (issubclass(r_type, ConstFloatType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstFloatType
             elif (issubclass(l_type, ConstFloatType) and issubclass(r_type, ConstIntType)):
                 out_type = ConstFloatType
             elif (issubclass(r_type, FloatType) or issubclass(l_type, FloatType)):
                 out_type = FloatType
             else:
                 raise exceptions.LambdaPackTypeException("Unsupported type combination for add/sub")
         elif (op =="Mult"):
             # mul type algebra
             if (issubclass(r_type, LinearIntType) and issubclass(l_type, ConstIntType)):
                 out_type = LinearIntType
             if (issubclass(r_type, LinearIntType) and issubclass(l_type, LinearIntType)):
                 out_type = IntType
             elif (issubclass(r_type, IntType) and issubclass(l_type, IntType)):
                 out_type = IntType
             elif (issubclass(r_type, ConstFloatType) and issubclass(l_type, ConstFloatType)):
                 out_type = ConstFloatType
             elif (issubclass(r_type, ConstFloatType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstFloatType
             elif (issubclass(r_type, FloatType) or issubclass(l_type, FloatType)):
                 out_type = FloatType
             else:
                 raise exceptions.LambdaPackTypeException("Unsupported type combination for mul")
         elif (op =="Div"):
             # div type algebra
             if (issubclass(r_type, LinearIntType) and issubclass(l_type, ConstIntType)):
                 out_type = LinearIntType
             elif (issubclass(r_type, Const) and issubclass(l_type, Const)):
                 out_type = ConstFloatType
             else:
                 out_type = FloatType
         elif (op == "Mod"):
             if (issubclass(r_type, ConstIntType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstIntType
             elif (issubclass(r_type, IntType) and issubclass(l_type, IntType)):
                 out_type = IntType
             else:
                 out_type = FloatType
         elif (op == "Pow"):
             if (issubclass(r_type, ConstIntType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstIntType
             elif (issubclass(r_type, IntType) and issubclass(l_type, IntType)):
                 out_type = IntType
             elif (issubclass(r_type, Const) and issubclass(l_type, Const)):
                 out_type = ConstFloatType
             else:
                 out_type = FloatType
         elif (op == "FloorDiv"):
             if (issubclass(r_type, ConstIntType) and issubclass(l_type, ConstIntType)):
                 out_type = ConstIntType
             else:
                 out_type = IntType
     return BinOp(node.op, left, right, out_type)
예제 #9
0
 def visit_Ref(self, node):
     decl_type = self.decl_types[node.name]
     if (decl_type is None):
         raise exceptions.LambdaPackTypeException("Refs must be typed")
     return Ref(node.name, decl_type)