def _file_line2qualname(fname): # convert the output file to use qualified names immediately. If we do it later, # we risk having mismatches due to changes in source code somewhere between the time we # generated the file and the time we postprocess it. qual_cache = {} inname = '_temp_' + fname os.rename(fname, inname) with open(inname, "r") as infile: with open(fname, 'w') as outfile: for line in infile: event, fpath, lineno, func, mem, elapsed, klass = line.rstrip().split('|') lineno = int(lineno) if func[0] == '<': qual = '%s:%s%s' % (fpath, lineno, func) else: qual = find_qualified_name(fpath, lineno, qual_cache) qclass = qual.split('.', 1)[0] if klass != '?' and klass != qclass: qual = ':'.join((qual, "(%s)" % klass)) out_parts = (event, fpath, str(lineno), func, mem, elapsed, qual) print('|'.join(out_parts), file=outfile) os.remove(inname)
def _trace_return(frame, arg, stack, context): """ This is called when a matched function returns. This only happens if show_return is True when setup() is called. """ qual_cache, method_counts, class_counts, _ = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" cname = self.__class__.__name__ class_counts[cname].add(id(self)) sname = "%s#%d%s" % (self.__class__.__name__, len( class_counts[cname]), pname) indent = tab * (len(stack) - 1) print("%s<-- %s" % (indent, '.'.join((sname, funcname)))) if arg is not None: s = "%s %s" % (indent, arg) if ' object at ' in s: s = addr_regex.sub('', s) print(s) sys.stdout.flush()
def _trace_call(frame, arg, stack, context): """ This is called after we have matched based on glob pattern and isinstance check. """ qual_cache, method_counts, class_counts, verbose = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" cname = self.__class__.__name__ class_counts[cname].add(id(self)) sname = "%s#%d%s" % (self.__class__.__name__, len( class_counts[cname]), pname) fullname = '.'.join((sname, funcname)) method_counts[fullname] += 1 indent = tab * (len(stack) - 1) if verbose: print("%s%s (%d)" % (indent, fullname, method_counts[fullname])) _indented_print(frame.f_locals, frame.f_locals, len(stack) - 1) else: print("%s%s" % (indent, fullname)) sys.stdout.flush()
def _trace_return(frame, arg, stack, context): """ This is called when a matched function returns. This only happens if show_return is True when setup() is called. """ qual_cache, method_counts, class_counts, _ = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" cname = self.__class__.__name__ class_counts[cname].add(id(self)) sname = "%s#%d%s" % (self.__class__.__name__, len(class_counts[cname]), pname) indent = tab * (len(stack)-1) print("%s<-- %s" % (indent, '.'.join((sname, funcname)))) if arg is not None: s = "%s %s" % (indent, arg) if ' object at ' in s: s = addr_regex.sub('', s) print(s) sys.stdout.flush()
def _trace_call(frame, arg, stack, context): """ This is called after we have matched based on glob pattern and isinstance check. """ qual_cache, method_counts, class_counts, verbose = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" cname = self.__class__.__name__ class_counts[cname].add(id(self)) sname = "%s#%d%s" % (self.__class__.__name__, len(class_counts[cname]), pname) fullname = '.'.join((sname, funcname)) method_counts[fullname] += 1 indent = tab * (len(stack)-1) if verbose: print("%s%s (%d)" % (indent, fullname, method_counts[fullname])) _indented_print(frame.f_locals, frame.f_locals, len(stack)-1) else: print("%s%s" % (indent, fullname)) sys.stdout.flush()
def _trace_return(frame, arg, stack, context): """ This is called when a matched function returns. This only happens if show_return is True when setup() is called. """ global time0 (qual_cache, method_counts, class_counts, id2count, verbose, memory, leaks, stream, show_ptrs) = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" sname = "%s#%d%s" % (self.__class__.__name__, id2count[id(self)], pname) indent = tab * len(stack) if memory is not None: current_mem = mem_usage() last_mem = memory.pop() if current_mem != last_mem: delta = current_mem - last_mem _printer( "%s<-- %s (time: %8.5f) (total: %6.3f MB) (diff: %+.0f KB)" % (indent, '.'.join((sname, funcname)), time.time() - time0, current_mem, delta * 1024.)) # add this delta to all callers so when they calculate their own delta, this # delta won't be included for i in range(len(memory) - 1, -1, -1): memory[i] += delta else: _printer("%s<-- %s (time: %8.5f) (total: %6.3f MB)" % (indent, '.'.join( (sname, funcname)), time.time() - time0, current_mem)) else: _printer("%s<-- %s" % (indent, '.'.join((sname, funcname)))) if verbose: if arg is not None: s = "%s %s" % (indent, arg) if not show_ptrs and ' object at ' in s: s = addr_regex.sub('', s) _printer(s) if leaks is not None: last_objs = leaks.pop() for name, _, delta_objs in objgraph.growth(peak_stats=last_objs): _printer("%s %s %+d" % (indent, name, delta_objs)) stream.flush()
def _trace_call(frame, arg, stack, context): """ This is called after we have matched based on glob pattern and isinstance check. """ global time0 if time0 is None: time0 = time.time() (qual_cache, method_counts, class_counts, id2count, verbose, memory, leaks, stream, show_ptrs) = context funcname = find_qualified_name(frame.f_code.co_filename, frame.f_code.co_firstlineno, qual_cache) self = frame.f_locals['self'] try: pname = "(%s)" % self.pathname except AttributeError: pname = "" cname = self.__class__.__name__ my_id = id(self) if my_id in id2count: id_count = id2count[my_id] else: class_counts[cname] += 1 id2count[my_id] = id_count = class_counts[cname] sname = "%s#%d%s" % (self.__class__.__name__, id_count, pname) fullname = '.'.join((sname, funcname)) method_counts[fullname] += 1 indent = tab * (len(stack) - 1) if verbose: _printer("%s--> %s (%d)" % (indent, fullname, method_counts[fullname])) _indented_print(frame.f_locals, frame.f_locals, len(stack) - 1, show_ptrs=show_ptrs) else: _printer("%s-->%s" % (indent, fullname)) if memory is not None: memory.append(mem_usage()) if leaks is not None: stats = objgraph.typestats() stats['frame'] += 1 stats['cell'] += 1 stats['list'] += 1 leaks.append(stats) stream.flush()
def _finalize_profile(): """ Called at exit to write out the profiling data. """ global _profile_prefix, _profile_total, _inst_data stop() # fix names in _inst_data _obj_map = {} cache = {} idents = defaultdict(dict) # map idents to a smaller number for funcpath, data in _inst_data.items(): _inst_data[funcpath] = data = _prof_node(funcpath, data) parts = funcpath.rsplit('|', 1) fname = parts[-1] if fname == '$total': continue filename, line, ident = fname.split('#') qfile, qclass, qname = find_qualified_name(filename, int(line), cache, full=False) idict = idents[(qfile, qclass)] if ident not in idict: idict[ident] = len(idict) ident = idict[ ident] + 1 # so we'll agree with ident scheme in other tracing/profiling functions try: name = data['obj'].pathname except AttributeError: if qfile is None: _obj_map[fname] = "<%s#%d.%s>" % (qclass, ident, qname) else: _obj_map[fname] = "<%s:%d.%s>" % (qfile, line, qname) else: if name is None: name = '%s#%d' % (qclass, ident) _obj_map[fname] = '.'.join((name, "<%s.%s>" % (qclass, qname))) _obj_map['$total'] = '$total' rank = MPI.COMM_WORLD.rank if MPI else 0 fname = os.path.basename(_profile_prefix) with open("%s.%d" % (fname, rank), 'w') as f: for name, data in _inst_data.items(): new_name = '|'.join([_obj_map[s] for s in name.split('|')]) f.write("%s %d %f\n" % (new_name, data['count'], data['time']))
def _finalize_profile(): """ Called at exit to write out the profiling data. """ global _profile_prefix, _profile_total, _inst_data stop() # fix names in _inst_data _obj_map = {} cache = {} idents = defaultdict(dict) # map idents to a smaller number for funcpath, data in iteritems(_inst_data): _inst_data[funcpath] = data = _prof_node(funcpath, data) parts = funcpath.rsplit('-', 1) fname = parts[-1] if fname == '$total': continue filename, line, ident = fname.split('#') qfile, qclass, qname = find_qualified_name(filename, int(line), cache, full=False) idict = idents[(qfile, qclass)] if ident not in idict: idict[ident] = len(idict) ident = idict[ident] + 1 # so we'll agree with ident scheme in other tracing/profiling functions try: name = data['obj'].pathname except AttributeError: if qfile is None: _obj_map[fname] = "<%s#%d.%s>" % (qclass, ident, qname) else: _obj_map[fname] = "<%s:%d.%s>" % (qfile, line, qname) else: _obj_map[fname] = '.'.join((name, "<%s.%s>" % (qclass, qname))) _obj_map['$total'] = '$total' rank = MPI.COMM_WORLD.rank if MPI else 0 fname = os.path.basename(_profile_prefix) with open("%s.%d" % (fname, rank), 'w') as f: for name, data in iteritems(_inst_data): new_name = '-'.join([_obj_map[s] for s in name.split('-')]) f.write("%s %d %f\n" % (new_name, data['count'], data['time']))