def printLocalVarDecls(self, ir): tempSize = 0 for var in ir.varDecls.keys(): if forFloat() and var not in self.internalVars: typ_str = IR.DataType.getFloatStr() else: typ_str = IR.DataType.getIntStr() if config.vbwEnabled: if hasattr(self, 'varsForBitwidth'): typ_str = ("int%d_t" % (self.varsForBitwidth[var])) if var in self.varsForBitwidth else typ_str else: assert False, "VBW enabled but bitwidth info missing" idf_str = var type = ir.varDecls[var] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) self.out.printf('%s %s%s;\n', typ_str, idf_str, shape_str, indent=True) if forArduino(): if Type.isTensor(type): bw = self.varsForBitwidth[var] if var in self.varsForBitwidth else config.wordLength size = np.prod(type.shape) * bw // 8 tempSize += (size if var not in self.scratchSubs else 0) if forArduino(): self.currentRAMestimate += tempSize self.maxRAMestimate = max(self.maxRAMestimate, self.currentRAMestimate)
def printSuffix(self, expr: IR.Expr): self.out.printf('\n') type = self.decls[expr.idf] if Type.isInt(type): self.out.printf('return ', indent=True) self.print(expr) self.out.printf(';\n') elif Type.isTensor(type): idfr = expr.idf exponent = self.scales[expr.idf] num = 2**exponent if type.dim == 0: self.out.printf('cout << ', indent=True) self.out.printf('float(' + idfr + ')*' + str(num)) self.out.printf(' << endl;\n') else: iters = [] for i in range(type.dim): s = chr(ord('i') + i) tempVar = IR.Var(s) iters.append(tempVar) expr_1 = IRUtil.addIndex(expr, iters) cmds = IRUtil.loop(type.shape, iters, [IR.PrintAsFloat(expr_1, exponent)]) self.print(IR.Prog(cmds)) else: assert False self.out.decreaseIndent() self.out.printf('}\n', indent=True) self.out.close()
def printVarDecls(self): for decl in self.decls: if decl in self.globalVars: continue if forFloat() and decl not in self.internalVars: typ_str = IR.DataType.getFloatStr() else: typ_str = IR.DataType.getIntStr() if config.vbwEnabled: if hasattr(self, 'varsForBitwidth'): typ_str = ( "int%d_t" % (self.varsForBitwidth[decl]) ) if decl in self.varsForBitwidth else typ_str else: assert False, "VBW enabled but bitwidth info missing" idf_str = decl type = self.decls[decl] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) self.out.printf('%s %s%s;\n', typ_str, idf_str, shape_str, indent=True) self.out.printf('\n')
def visitBopMul(self, node: AST.Bop1): type_in_A = node.expr1.type type_in_B = node.expr2.type type_out = node.type if Type.isInt(type_out): return self.visitBopMulInt(node) elif type_in_A.dim == 0: return self.visitBopMul1DTensor(node) elif type_in_B.dim == 0: return self.visitBopMul1DTensor(node) else: return self.visitBopMul2DTensor(node)
def printVarDecls(self): varsFilePath = os.path.join(self.outputDir, "vars_" + getVersion() + ".h") varsFile = Writer(varsFilePath) varsFile.printf("#pragma once\n\n") varsFile.printf("#include \"datatypes.h\"\n\n") varsFile.printf("namespace vars_%s {\n" % (getVersion())) varsFile.increaseIndent() for decl in self.decls: if decl in self.globalVars: continue if forFloat() and decl not in self.internalVars: typ_str = IR.DataType.getFloatStr() else: typ_str = IR.DataType.getIntStr() idf_str = decl type = self.decls[decl] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) self.out.printf('%s vars_%s::%s%s;\n', typ_str, getVersion(), idf_str, shape_str, indent=True) varsFile.printf('extern %s %s%s;\n', typ_str, idf_str, shape_str, indent=True) self.out.printf('\n') varsFile.decreaseIndent() varsFile.printf("}\n") varsFile.close() self.generateDebugProgram()
def printVarDecls(self): for decl in self.decls: if decl in self.globalVars: continue typ_str = IR.DataType.getIntStr() idf_str = decl type = self.decls[decl] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) self.out.printf('%s %s%s;\n', typ_str, idf_str, shape_str, indent=True) self.out.printf('\n')
def visitUop(self, node: AST.Uop): (prog_in, expr_in) = self.visit(node.expr) op = node.op if op == SeeDotParser.ADD: return (prog_in, expr_in) assert op == SeeDotParser.SUB type_out = node.type # e : Int if Type.isInt(type_out): prog_out = prog_in expr_out = IRUtil.negate(expr_in) # e: Tensor(), or Tensor(..) else: expr_out = self.getTempVar() iters = self.getTempIterators(type_out.dim) scale_out = self.scales[expr_in.idf] (m, M) = self.intvs[expr_in.idf] intv_out = (-M, -m) expr_in_idx = IRUtil.addIndex(expr_in, iters) expr_out_idx = IRUtil.addIndex(expr_out, iters) rhs = IRUtil.negate(expr_in_idx) loop = IRUtil.loop(type_out.shape, iters, [IR.Assn(expr_out_idx, rhs)]) prog_uop = IR.Prog(loop) prog_out = IRUtil.concatPrograms(prog_in, prog_uop) self.decls[expr_out.idf] = type_out self.scales[expr_out.idf] = scale_out self.intvs[expr_out.idf] = intv_out return (prog_out, expr_out)
def visitLet(self, node: AST.Let): (prog_decl, expr_decl) = self.visit(node.decl) type_decl = node.decl.type idf = node.name # e1 : Int if Type.isInt(type_decl): self.decls[idf] = Type.Int() (prog_in, expr_in) = self.visit(node.expr) cmd = IR.Assn(IR.Var(idf), expr_decl) prog_let = IR.Prog([cmd]) prog_out = IRUtil.concatPrograms(prog_decl, prog_let, prog_in) return (prog_out, expr_in) # e1 : Tensor{(),(..)} else: self.scales[idf] = self.scales[expr_decl.idf] self.intvs[idf] = self.intvs[expr_decl.idf] if isinstance(node.decl, AST.Decl): self.globalVars.append(idf) self.decls[idf] = node.decl.type expr_decl.idf = idf expr_decl.inputVar = True (prog_in, expr_in) = self.visit(node.expr) prog_in = prog_in.subst(idf, expr_decl) expr_in = expr_in.subst(idf, expr_decl) prog_out = IRUtil.concatPrograms(prog_decl, prog_in) return (prog_out, expr_in)
def printSuffix(self, expr: IR.Expr): self.out.printf('\n') type = self.decls[expr.idf] if Type.isInt(type): self.out.printf('return ', indent=True) self.print(expr) self.out.printf(';\n') elif Type.isTensor(type): idfr = expr.idf exponent = self.scales[expr.idf] num = 2**exponent if type.dim == 0: self.out.printf('Serial.println(', indent=True) self.out.printf('float(' + idfr + ')*' + str(num)) self.out.printf(', 6);\n') else: iters = [] for i in range(type.dim): s = chr(ord('i') + i) tempVar = IR.Var(s) iters.append(tempVar) expr_1 = IRUtil.addIndex(expr, iters) cmds = IRUtil.loop(type.shape, iters, [IR.PrintAsFloat(expr_1, exponent)]) self.print(IR.Prog(cmds)) else: assert False self.out.decreaseIndent() self.out.printf('}\n', indent=True) self.out.close() with open(os.path.join(self.outputDir, "ram.usage"), "w") as f: f.write("Estimate RAM usage :: %d bytes" % (self.maxRAMestimate))
def printLocalVarDecls(self, ir): for var in ir.varDecls.keys(): if forFloat() and var not in self.internalVars: typ_str = IR.DataType.getFloatStr() else: typ_str = IR.DataType.getIntStr() if config.vbwEnabled: if hasattr(self, 'varsForBitwidth'): typ_str = ( "int%d_t" % (self.varsForBitwidth[var]) ) if var in self.varsForBitwidth else typ_str else: assert False, "VBW enabled but bitwidth info missing" idf_str = var type = ir.varDecls[var] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) self.out.printf('%s %s%s;\n', typ_str, idf_str, shape_str, indent=True)
def printSuffix(self, expr: IR.Expr): self.out.printf('\n') if config.vbwEnabled and forFixed(): bw = self.varsForBitwidth['X'] typ_str = "int%d_t" % bw size = self.decls['X'].shape sizestr = ''.join([("[%d]" % i) for i in size]) Xindexstr = '' Xintstar = ''.join(["*" for i in size]) for i in range(len(size)): Xindexstr += (("[i%d]" % (i - 1)) if i > 0 else "") self.out.printf("for (int i%d = 0; i%d < %d; i%d ++ ){\n" % (i, i, size[i], i), indent=True) self.out.increaseIndent() for i in range(len(size) - 1, -1, -1): self.out.decreaseIndent() self.out.printf("}\n", indent=True) self.out.printf("delete[] X%s;\n" % (Xindexstr), indent=True) Xindexstr = Xindexstr[:-4] if len(Xindexstr) > 0 else Xindexstr assert len( size ) < 10, "Too simple logic for printing indices used, cannot handle 10+ Dim Tensors" type = self.decls[expr.idf] if Type.isInt(type): self.out.printf('return ', indent=True) self.print(expr) self.out.printf(';\n') elif Type.isTensor(type): idfr = expr.idf exponent = self.scales[expr.idf] num = 2**exponent if type.dim == 0: self.out.printf('cout << ', indent=True) self.out.printf('float(' + idfr + ')*' + str(num)) self.out.printf(' << endl;\n') else: iters = [] for i in range(type.dim): s = chr(ord('i') + i) tempVar = IR.Var(s) iters.append(tempVar) expr_1 = IRUtil.addIndex(expr, iters) cmds = IRUtil.loop(type.shape, iters, [IR.PrintAsFloat(expr_1, exponent)]) self.print(IR.Prog(cmds)) else: assert False self.out.decreaseIndent() self.out.printf('}\n', indent=True) def isInt(a): try: int(a) return True except: return False if forFixed(): if (int(self.printSwitch) if isInt(self.printSwitch) else -2) > -1: self.out.printf("const int switches = %d;\n" % (int(self.printSwitch)), indent=True) self.out.printf( 'void seedotFixedSwitch(int i, MYINT **X_temp, int& res) {\n', indent=True) self.out.increaseIndent() self.out.printf('switch(i) {\n', indent=True) self.out.increaseIndent() for i in range(int(self.printSwitch)): self.out.printf( 'case %d: res = seedotFixed%d(X_temp); return;\n' % (i, i + 1), indent=True) self.out.printf('default: res = -1; return;\n', indent=True) self.out.decreaseIndent() self.out.printf('}\n', indent=True) self.out.decreaseIndent() self.out.printf('}\n', indent=True) if debugCompiler(): print("Closing File after outputting cpp code: ID " + self.idStr) self.out.close()
def printVarDecls(self, globalVarDecl=True): if self.generateAllFiles: varsFilePath = os.path.join(self.outputDir, "vars_" + getVersion() + ".h") varsFile = Writer(varsFilePath) varsFile.printf("#pragma once\n\n") varsFile.printf("#include \"datatypes.h\"\n\n") varsFile.printf("namespace vars_%s {\n" % (getVersion())) varsFile.increaseIndent() for decl in self.decls: if decl in self.globalVars: continue if forFloat() and decl not in self.internalVars: typ_str = IR.DataType.getFloatStr() elif forFixed() and decl not in self.internalVars: if config.vbwEnabled and decl not in self.internalVars: bw = self.varsForBitwidth.get(decl, config.wordLength) typ_str = "int%d_t" % bw else: typ_str = IR.DataType.getIntStr() else: typ_str = IR.DataType.getIntStr() idf_str = decl type = self.decls[decl] if Type.isInt(type): shape_str = '' elif Type.isTensor(type): shape_str = ''.join(['[' + str(n) + ']' for n in type.shape]) if not config.vbwEnabled: self.out.printf('%s vars_%s::%s%s;\n', typ_str, getVersion(), idf_str, shape_str, indent=True) if self.generateAllFiles: varsFile.printf('extern %s %s%s;\n', typ_str, idf_str, shape_str, indent=True) else: if forFixed( ) and idf_str in self.varsForBitwidth and idf_str[:3] == "tmp": if globalVarDecl: for bw in config.availableBitwidths: self.out.printf("int%d_t vars_%s::%s_%d%s;\n", bw, getVersion(), idf_str, bw, shape_str, indent=True) else: self.out.printf("int%d_t %s_%d%s;\n", self.varsForBitwidth[idf_str], idf_str, bw, shape_str, indent=True) else: if globalVarDecl: self.out.printf("%s vars_%s::%s%s;\n", typ_str, getVersion(), idf_str, shape_str, indent=True) else: self.out.printf("%s %s%s;\n", typ_str, idf_str, shape_str, indent=True) if self.generateAllFiles: if forFixed( ) and idf_str in self.varsForBitwidth and idf_str[: 3] == "tmp": for bw in config.availableBitwidths: varsFile.printf("extern int%d_t %s_%d%s;\n", bw, idf_str, bw, shape_str, indent=True) else: varsFile.printf("extern %s %s%s;\n", typ_str, idf_str, shape_str, indent=True) self.out.printf('\n') if self.generateAllFiles: varsFile.decreaseIndent() varsFile.printf("}\n") varsFile.close() self.generateDebugProgram()
def visitBop2(self, node: AST.Bop2): (prog_in_A, expr_in_A) = self.visit(node.expr1) (prog_in_B, expr_in_B) = self.visit(node.expr2) op = node.op if op == SeeDotParser.ADD: (op_ir, op_fn) = (IR.Op.Op['+'], operator.add) funcName = "MatAdd" elif op == SeeDotParser.SUB: (op_ir, op_fn) = (IR.Op.Op['-'], operator.sub) funcName = "MatSub" type_out = node.type # e : Int if Type.isInt(type_out): prog_out = IRUtil.concatPrograms(prog_in_A, prog_in_B) expr_out = IR.IntBop(expr_in_A, op_ir, expr_in_B) # e : Tensor(), or Tensor(..) else: expr_out = self.getTempVar() scale_in_A, scale_in_B = self.scales[expr_in_A.idf], self.scales[ expr_in_B.idf] intv_in_A, intv_in_B = self.intvs[expr_in_A.idf], self.intvs[ expr_in_B.idf] (scale_out, intv_out, [shr_A, shr_B, shr_out ]) = self.getScaleAndIntervalForAdd(scale_in_A, scale_in_B, intv_in_A, intv_in_B, op_fn) assert type_out.dim == 2 [I, J] = type_out.shape shr_A = self.formatShr(shr_A) shr_B = self.formatShr(shr_B) shr_out = self.formatShr(shr_out) expr_in_A.inputVar = False expr_in_B.inputVar = False expr_out.inputVar = False cmd0 = IR.Comment(expr_in_A.idf + ' ' + op_ir.name + ' ' + expr_in_B.idf) funcCall = IR.FuncCall( funcName, { expr_in_A: "A", expr_in_B: "B", expr_out: "C", IR.Int(I): "I", IR.Int(J): "J", shr_A: "shrA", shr_B: "shrB", shr_out: "shrC" }) prog_bop = IR.Prog([cmd0, funcCall]) prog_out = IRUtil.concatPrograms(prog_in_A, prog_in_B, prog_bop) self.decls[expr_out.idf] = type_out self.scales[expr_out.idf] = scale_out self.intvs[expr_out.idf] = intv_out return (prog_out, expr_out)
def visitCond(self, node: AST.Cond): (prog_in_cond, expr_in_cond) = self.visit(node.expr) (prog_in_A, expr_in_A) = self.visit(node.trueBlock) (prog_in_B, expr_in_B) = self.visit(node.falseBlock) type_in_cond = node.expr.type type_in_A = node.trueBlock.type if Type.isInt(type_in_cond): expr_in_cond_idx = expr_in_cond else: expr_in_cond_idx = IRUtil.addIndex(expr_in_cond, [IRUtil.zero] * type_in_cond.dim) # e2,e3 : Int if Type.isInt(type_in_A): # TODO: Update the scale and intv of expr_out based on in_A and # in_B prog_out = IRUtil.concatPrograms(prog_in_cond, prog_in_A, prog_in_B) expr_out = IRUtil.cond_zero(expr_in_cond_idx, expr_in_A, expr_in_B) # e2,e3 : Tensor(), or Tensor(..) else: expr_out = self.getTempVar() iters = self.getTempIterators(type_in_A.dim) scale_in_A, scale_in_B = self.scales[expr_in_A.idf], self.scales[ expr_in_B.idf] intv_in_A, intv_in_B = self.intvs[expr_in_A.idf], self.intvs[ expr_in_B.idf] m_2, M_2 = intv_in_A m_3, M_3 = intv_in_B if scale_in_A >= scale_in_B: shr_n_2, shr_n_3 = 0, scale_in_A - scale_in_B else: shr_n_2, shr_n_3 = scale_in_B - scale_in_A, 0 scale_out = max(scale_in_A, scale_in_B) intv_out = (min(m_2 >> shr_n_2, m_3 >> shr_n_3), max(M_2 >> shr_n_2, M_3 >> shr_n_3)) # prog_assn expr_in_A_idx = IRUtil.addIndex(expr_in_A, iters) expr_in_B_idx = IRUtil.addIndex(expr_in_B, iters) expr_out_idx = IRUtil.addIndex(expr_out, iters) rhs = IRUtil.cond_zero(expr_in_cond_idx, IRUtil.shr(expr_in_A_idx, shr_n_2), IRUtil.shr(expr_in_B_idx, shr_n_3)) cmdl_assn = IRUtil.loop(type_in_A.shape, iters, [IR.Assn(expr_out_idx, rhs)]) prog_cond = IR.Prog(cmdl_assn) prog_out = IRUtil.concatPrograms(prog_in_cond, prog_in_A, prog_in_B, prog_cond) self.decls[expr_out.idf] = type_in_A self.scales[expr_out.idf] = scale_out self.intvs[expr_out.idf] = intv_out return (prog_out, expr_out)