def test_exercise_code_path_with_lifted_loop(self): """ Ensures that lifted loops are handled correctly in obj mode """ # the functions to jit def bar(x): return x def foo(x): h = 0. for k in range(x): h = h + k if x: h = h - bar(x) return h # compile into an isolated context flags = Flags() flags.set('enable_pyobject') flags.set('enable_looplift') cres = compile_isolated(foo, [types.intp], flags=flags) ta = cres.type_annotation buf = StringIO() ta.html_annotate(buf) output = buf.getvalue() buf.close() self.assertIn("bar", output) self.assertIn("foo", output) self.assertIn("LiftedLoop", output)
def test_html_output_with_lifted_loop(self): """ Test some format and behavior of the html annotation with lifted loop """ @numba.jit def udt(x): object() # to force object mode z = 0 for i in range(x): # this line is tagged z += i return z # Regex pattern to check for the "lifted_tag" in the line of the loop re_lifted_tag = re.compile( r'<td class="lifted_tag">\s*' r'\s*<details>' r'\s*<summary>' r'\s*<code>' r'\s*[0-9]+:' r'\s*[ ]+for i in range\(x\): # this line is tagged\s*', re.MULTILINE) # Compile int64 version sig_i64 = (types.int64, ) udt.compile(sig_i64) # compile with lifted loop cres = udt.overloads[sig_i64] # Make html output buf = StringIO() cres.type_annotation.html_annotate(buf) output = buf.getvalue() buf.close() # There should be only one function output. self.assertEqual(output.count("Function name: udt"), 1) sigfmt = "with signature: {} -> pyobject" self.assertEqual(output.count(sigfmt.format(sig_i64)), 1) # Ensure the loop is tagged self.assertEqual(len(re.findall(re_lifted_tag, output)), 1, msg='%s not found in %s' % (re_lifted_tag, output)) # Compile float64 version sig_f64 = (types.float64, ) udt.compile(sig_f64) cres = udt.overloads[sig_f64] # Make html output buf = StringIO() cres.type_annotation.html_annotate(buf) output = buf.getvalue() buf.close() # There should be two function output self.assertEqual(output.count("Function name: udt"), 2) self.assertEqual(output.count(sigfmt.format(sig_i64)), 1) self.assertEqual(output.count(sigfmt.format(sig_f64)), 1) # Ensure the loop is tagged in both output self.assertEqual(len(re.findall(re_lifted_tag, output)), 2)
def annotate(self): source = SourceLines(self.func) # if not source.avail: # return "Source code unavailable" # Prepare annotations groupedinst = defaultdict(list) for blkid, blk in self.blocks.items(): groupedinst[blk.loc.line].append("label %s" % blkid) for inst in blk.body: lineno = inst.loc.line if isinstance(inst, ir.Assign): if (isinstance(inst.value, ir.Expr) and inst.value.op == 'call'): atype = self.calltypes[inst.value] else: atype = self.typemap[inst.target.name] aline = "%s = %s :: %s" % (inst.target, inst.value, atype) elif isinstance(inst, ir.SetItem): atype = self.calltypes[inst] aline = "%s :: %s" % (inst, atype) else: aline = "%s" % inst groupedinst[lineno].append(" %s" % aline) # Format annotations io = StringIO() with closing(io): if source.avail: print("# File: %s" % self.filename, file=io) for num in source: srcline = source[num] ind = _getindent(srcline) print("%s# --- LINE %d --- " % (ind, num), file=io) for inst in groupedinst[num]: print('%s# %s' % (ind, inst), file=io) print(file=io) print(srcline, file=io) print(file=io) if self.lifted: print("# The function contains lifted loops", file=io) for loop in self.lifted: print("# Loop at line %d" % loop.bytecode.firstlineno, file=io) print("# Has %d overloads" % len(loop.overloads), file=io) for cres in loop._compileinfos.values(): print(cres.type_annotation, file=io) else: print("# Source code unavailable", file=io) for num in groupedinst: for inst in groupedinst[num]: print('%s' % (inst, ), file=io) print(file=io) return io.getvalue()
def annotate(self): source = SourceLines(self.func) # if not source.avail: # return "Source code unavailable" # Prepare annotations groupedinst = defaultdict(list) for blkid, blk in self.blocks.items(): groupedinst[blk.loc.line].append("label %d" % blkid) for inst in blk.body: lineno = inst.loc.line if isinstance(inst, ir.Assign): if (isinstance(inst.value, ir.Expr) and inst.value.op == 'call'): atype = self.calltypes[inst.value] else: atype = self.typemap[inst.target.name] aline = "%s = %s :: %s" % (inst.target, inst.value, atype) elif isinstance(inst, ir.SetItem): atype = self.calltypes[inst] aline = "%s :: %s" % (inst, atype) else: aline = "%s" % inst groupedinst[lineno].append(" %s" % aline) # Format annotations io = StringIO() with closing(io): if source.avail: print("# File: %s" % self.filename, file=io) for num in source: srcline = source[num] ind = _getindent(srcline) print("%s# --- LINE %d --- " % (ind, num), file=io) for inst in groupedinst[num]: print('%s# %s' % (ind, inst), file=io) print(file=io) print(srcline, file=io) print(file=io) if self.lifted: print("# The function contains lifted loops", file=io) for loop in self.lifted: print("# Loop at line %d" % loop.bytecode.firstlineno, file=io) print("# Has %d overloads" % len(loop.overloads), file=io) for cres in loop.overloads.values(): print(cres.type_annotation, file=io) else: print("# Source code unavailable", file=io) for num in groupedinst: for inst in groupedinst[num]: print('%s' % (inst,), file=io) print(file=io) return io.getvalue()
def test_html_output_with_lifted_loop(self): """ Test some format and behavior of the html annotation with lifted loop """ @numba.jit def udt(x): object() # to force object mode z = 0 for i in range(x): # this line is tagged z += i return z # Regex pattern to check for the "lifted_tag" in the line of the loop re_lifted_tag = re.compile( r'<td class="lifted_tag">\s*' r'\s*<details>' r'\s*<summary>' r'\s*<code>' r'\s*[0-9]+:' r'\s*[ ]+for i in range\(x\): # this line is tagged\s*', re.MULTILINE) # Compile int64 version sig_i64 = (types.int64,) udt.compile(sig_i64) # compile with lifted loop cres = udt.overloads[sig_i64] # Make html output buf = StringIO() cres.type_annotation.html_annotate(buf) output = buf.getvalue() buf.close() # There should be only one function output. self.assertEqual(output.count("Function name: udt"), 1) sigfmt = "with signature: {} -> pyobject" self.assertEqual(output.count(sigfmt.format(sig_i64)), 1) # Ensure the loop is tagged self.assertEqual(len(re.findall(re_lifted_tag, output)), 1, msg='%s not found in %s' % (re_lifted_tag, output)) # Compile float64 version sig_f64 = (types.float64,) udt.compile(sig_f64) cres = udt.overloads[sig_f64] # Make html output buf = StringIO() cres.type_annotation.html_annotate(buf) output = buf.getvalue() buf.close() # There should be two function output self.assertEqual(output.count("Function name: udt"), 2) self.assertEqual(output.count(sigfmt.format(sig_i64)), 1) self.assertEqual(output.count(sigfmt.format(sig_f64)), 1) # Ensure the loop is tagged in both output self.assertEqual(len(re.findall(re_lifted_tag, output)), 2)
def annotate(self, interp, typemap, calltypes): source = SourceLines(interp.bytecode.func) # if not source.avail: # return "Source code unavailable" # Prepare annotations groupedinst = defaultdict(list) for blkid, blk in interp.blocks.items(): groupedinst[blk.loc.line].append("label %d" % blkid) for inst in blk.body: lineno = inst.loc.line if isinstance(inst, ir.Assign): if (isinstance(inst.value, ir.Expr) and inst.value.op == 'call'): atype = calltypes[inst.value] else: atype = typemap[inst.target.name] aline = "%s = %s :: %s" % (inst.target, inst.value, atype) elif isinstance(inst, ir.SetItem): atype = calltypes[inst] aline = "%s :: %s" % (inst, atype) else: aline = "%s" % inst groupedinst[lineno].append(" %s" % aline) # Format annotations io = StringIO() with closing(io): if source.avail: for num in source: srcline = source[num] ind = _getindent(srcline) print("%s# --- LINE %d --- " % (ind, num), file=io) for inst in groupedinst[num]: print('%s# %s' % (ind, inst), file=io) print(file=io) print(srcline, file=io) print(file=io) else: print("# Source code unavailable", file=io) for num in groupedinst: for inst in groupedinst[num]: print('%s' % (inst,), file=io) print(file=io) return io.getvalue()
def swap_stdout(): old_stdout = sys.stdout sys.stdout = StringIO() try: yield finally: sys.stdout = old_stdout
def test_exercise_code_path(self): """ Ensures template.html is available """ def foo(n, a): s = a for i in range(n): s += i return s cres = compile_isolated(foo, [types.int32, types.int32]) ta = cres.type_annotation buf = StringIO() ta.html_annotate(buf) output = buf.getvalue() buf.close() self.assertIn("foo", output)
def annotate(self): source = SourceLines(self.func_id.func) # if not source.avail: # return "Source code unavailable" groupedinst = self.prepare_annotations() # Format annotations io = StringIO() with closing(io): if source.avail: print("# File: %s" % self.filename, file=io) for num in source: srcline = source[num] ind = _getindent(srcline) print("%s# --- LINE %d --- " % (ind, num), file=io) for inst in groupedinst[num]: print('%s# %s' % (ind, inst), file=io) print(file=io) print(srcline, file=io) print(file=io) if self.lifted: print("# The function contains lifted loops", file=io) for loop in self.lifted: print("# Loop at line %d" % loop.get_source_location(), file=io) print("# Has %d overloads" % len(loop.overloads), file=io) for cres in loop.overloads.values(): print(cres.type_annotation, file=io) else: print("# Source code unavailable", file=io) for num in groupedinst: for inst in groupedinst[num]: print('%s' % (inst,), file=io) print(file=io) return io.getvalue()
def annotate(self): source = SourceLines(self.func_id.func) # if not source.avail: # return "Source code unavailable" groupedinst = self.prepare_annotations() # Format annotations io = StringIO() with closing(io): if source.avail: print("# File: %s" % self.filename, file=io) for num in source: srcline = source[num] ind = _getindent(srcline) print("%s# --- LINE %d --- " % (ind, num), file=io) for inst in groupedinst[num]: print('%s# %s' % (ind, inst), file=io) print(file=io) print(srcline, file=io) print(file=io) if self.lifted: print("# The function contains lifted loops", file=io) for loop in self.lifted: print("# Loop at line %d" % loop.get_source_location(), file=io) print("# Has %d overloads" % len(loop.overloads), file=io) for cres in loop.overloads.values(): print(cres.type_annotation, file=io) else: print("# Source code unavailable", file=io) for num in groupedinst: for inst in groupedinst[num]: print('%s' % (inst, ), file=io) print(file=io) return io.getvalue()
def swap_stdout(): old_stdout = sys.stdout sys.stdout = StringIO() yield sys.stdout = old_stdout