def _createFig(ioKey, speedKey, cppTypes, dsNames, figTitle): #print ":"*80,figTitle fig = plt.figure() fig.add_subplot(311).hold(True) fig.add_subplot(312).hold(True) fig.add_subplot(313).hold(True) from App import DataSetMgr color = DataSetMgr.colorIter() # to hold 'cpu' for each dataSet axes = [[], [], []] names = {} for idx, dsName in enumerate(dsNames): table = [] names[dsName] = [] for cppType in cppTypes.keys(): store = cppTypes[cppType][dsName] if not store.has_key(ioKey): continue store = store[ioKey] if len(store['size']) <= 0: continue names[dsName].append(cppType) size = numpy.array(store['size']) cTime = numpy.array([i[0] for i in store[speedKey]]) uTime = numpy.array([i[1] for i in store[speedKey]]) if speedKey == 'r': cTimeR = numpy.array([i[0] for i in store['rr']]) else: cTimeR = cTime cFreq = numpy.array([1. / i for i in cTime]) uFreq = numpy.array([1. / i for i in uTime]) speed = size / cTime #print cppType,store['size'],cTime.mean(),cTime,speed,speed.mean(),cFreq.mean() table.append(( len(names[dsName]) - 1, size.mean(), cTimeR.mean() * ms, cTime.mean() * ms, uTime.mean() * ms, cFreq.mean() / ms, uFreq.mean() / ms, speed.mean() / 1024. * 1e3, )) pass descr = numpy.dtype({ 'names': ( 'name', 'size', speedKey + '/cpuRoot', speedKey + '/cpu', speedKey + '/user', speedKey + '/cpuFreq', speedKey + '/userFreq', 'speed', ), 'formats': ( 'int32', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64', ), }) table = numpy.array(table, dtype=descr) nData = len(table) ## print speedKey,nData,names if nData == 0: return None table.sort(order=('size', )) # linewidth for horizontal bars lw = 0.01 nDsNames = float(len(dsNames)) ## -- processing time ax = fig.axes[0] ax.set_title(figTitle) xlabel = '<Mean> CPU time (user+sys) [ms]' if speedKey == 'r': xlabel = '<Mean> CPU time (user+sys) [green=pure ROOT] [ms]' ax.set_xlabel(xlabel) labels = [names[dsName][i] for i in table['name']] data = table[speedKey + '/cpu'] fc = color.next() pos = numpy.arange(nData) p = ax.barh(bottom=pos + (idx * 1. / nDsNames), width=data, height=1. / nDsNames, color='r', label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') # display 'user' part only data = table[speedKey + '/user'] pos = numpy.arange(nData) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=fc, label=dsName, lw=lw) axes[0] += p # hack to display the ROOT component (only for reading) if speedKey == 'r': data = table[speedKey + '/cpuRoot'] pos = numpy.arange(nData) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color='g', label=dsName, lw=lw) ## -- Speed ax = fig.axes[1] ax.set_xlabel('<Mean> Speed (user+sys) [MB/s]') labels = [names[dsName][i] for i in table['name']] data = table[speedKey + '/cpu'] data = table['speed'] fc = color.next() pos = numpy.arange(nData) p = ax.barh(bottom=pos + (idx * 1. / nDsNames), width=data, height=1. / nDsNames, color='r', label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') # display 'user' part only data = table[speedKey + '/user'] data = table['speed'] pos = numpy.arange(nData) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=fc, label=dsName, lw=lw) axes[1] += p ## -- Frequency ax = fig.axes[2] ax.set_xlabel('<Mean> Frequency (user+sys) [kHz]') labels = [names[dsName][i] for i in table['name']] data = table[speedKey + '/cpuFreq'] fc = color.next() pos = numpy.arange(nData) p = ax.barh(bottom=pos + (idx * 1. / nDsNames), width=data, height=1. / nDsNames, color='r', label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') # display 'user' part only data = table[speedKey + '/userFreq'] pos = numpy.arange(nData) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=fc, label=dsName, lw=lw) axes[2] += p for ix, ax in zip(axes, fig.axes): ax.legend(ix[::nData], DataSetMgr.labels(), loc='lower right') return fig
def _top_consumers(self, dataSetMgr, monCompMgr, compTypes, title, storeName, sliceName, begSlice, endSlice): from App import DataSetMgr ## fill-in the text file _txt = self.txt[sliceName] ## short-hand ms = Units.ms kb = Units.kb Mb = Units.Mb msg = self.msg dsNames = dataSetMgr.keys() dsNames.sort() monComps = [] for monComp in monCompMgr.values(): if not monComp.type in compTypes: continue monCompKeys = monComp.data.keys() monCompKeys.sort() if monCompKeys != dsNames: continue # remove AthMasterSeq and AthAlgSeq if monComp.name in ( 'AthMasterSeq', 'AthAlgSeq', ): continue monComps.append(monComp) if len(monComps) == 0: msg.debug("Could not find any monitored component for" " _top_consumers_ analysis !") return # create figure # -------------- fig = plt.figure() fig.add_subplot(411).hold(True) fig.add_subplot(412).hold(True) fig.add_subplot(413).hold(True) fig.add_subplot(414).hold(True) self.sum[sliceName]['fig'] = fig # to hold 'cpu' for each dataSet axes = [[], [], [], []] color = DataSetMgr.colorIter() timings = {} _monComps = [m for m in monComps] for idx, dsName in enumerate(dsNames): monComps = [] table = [] timings[dsName] = [] for monComp in _monComps: if not storeName in monComp.data[dsName]: continue usrKey = 'cpu/user' sysKey = 'cpu/sys' realKey = 'cpu/real' vm0Key = 'mem/vmem/0' vm1Key = 'mem/vmem/1' malKey = 'mem/malloc/d' store = monComp.data[dsName][storeName] if store is None: ## if storeName == 'evt': ## print "===",dsName,storeName,monComp.name continue if len(store['mem']) == 0: ## if storeName == 'evt': ## print "+++",dsName,storeName,monComp.name continue cpu = store['cpu'] cpu_u = cpu['user'][:, 2] cpu_s = cpu['sys'][:, 2] cpu_c = cpu['cpu'][:, 2] cpu_r = cpu['real'][:, 2] mem = store['mem'] vmem = mem['vmem'] mall = mem['mall'] dvmem = vmem[:, 2] dmall = mall[:, 2] monComps.append(monComp) timings[dsName].append(monComp.name) table.append(( len(timings[dsName]) - 1, cpu_u[begSlice:endSlice].mean() * ms, cpu_s[begSlice:endSlice].mean() * ms, (cpu_c[begSlice:endSlice] * ms).mean(), (cpu_r[begSlice:endSlice] * ms).mean(), (dvmem[begSlice:endSlice] * kb).mean(), dmall[begSlice:endSlice].mean() * kb, mem['nmall'][begSlice:endSlice, 2].mean(), mem['nfree'][begSlice:endSlice, 2].mean(), )) has_nan = False new_value = list(table[-1]) for ii, _vv in enumerate(new_value): if numpy.isnan(_vv): has_nan = True new_value[ii] = 0 pass pass if has_nan: msg.warn("NaN in [%s]", monComp.name) msg.warn(" -%s", table[-1]) table[-1] = tuple(new_value) msg.warn(" +%s", table[-1]) pass pass # loop over components descr = numpy.dtype({ 'names': ('name', 'cpu/user', 'cpu/sys', 'cpu/cpuTime', 'cpu/real', 'mem', 'malloc', 'nmall', 'nfree'), 'formats': ('int32', 'float64', 'float64', 'float64', 'float64', 'float64', 'float64', 'int64', 'int64') }) try: table = numpy.array(table, dtype=descr) nData = min(self.max, len([m for m in monComps if m.type in compTypes])) except Exception, err: #msg.error("table: %s", table) msg.error("caught: %s", err) msg.error("context: title=%s store=%s slice=%s beg=%s end=%s", title, storeName, sliceName, begSlice, endSlice) nData = 0 continue if nData == 0: _warn = msg.warning _warn("in top_consumers: no data to plot for [%s]!", title) _warn( "** this may mean you'd have to re-run perfmon with more details enabled..." ) _warn("dsname=[%s] storename=[%s]", dsName, storeName) _warn("no component found with type %s", compTypes) continue # linewidth for horizontal bars lw = 0.01 names = timings[dsName] nDsNames = float(len(dsNames)) ## CPU table.sort(order=('cpu/cpuTime', )) ax = fig.axes[0] ax.set_title('Top consumers during [%s]' % title) ax.set_xlabel('<Mean> CPU time (user+sys) [ms]') labels = [names[i] for i in table['name'][-nData:]] data = table['cpu/cpuTime'][-nData:] fc = color.next() pos = numpy.arange(nData) p = ax.barh(bottom=pos + (idx * 1. / nDsNames), width=data, height=1. / nDsNames, align='edge', color='r', label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') # display 'user' part only data = table['cpu/user'][-nData:] pos = numpy.arange(nData) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=fc, label=dsName, lw=lw) axes[0] += p ## ==> fill ASCII if dsName == '000': _c = _txt['cpu']['comps'] for _i in zip(table['cpu/cpuTime'], table['cpu/sys'], [names[i] for i in table['name']]): if not numpy.isnan(_i[0]): _c += ["[cpu/sys] %10.3f %10.3f (ms) | %s" % _i] else: self.msg.error("%s contains weird data !!", _i[-1]) _c.reverse() ## real-time table.sort(order=('cpu/real', )) labels = [names[i] for i in table['name'][-nData:]] ax = fig.axes[1] ax.set_xlabel('<Mean> real time [ms]') data = table['cpu/real'][-nData:] pos = numpy.arange(len(data)) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=color.next(), label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') axes[1] += p ## virtual memory table.sort(order=('mem', )) labels = [names[i] for i in table['name'][-nData:]] ax = fig.axes[2] #ax.set_xlabel( '$\Delta \rm{VMem}\ [kB]$' ) ax.set_xlabel('delta VMem [kB]') data = table['mem'][-nData:] pos = numpy.arange(len(data)) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=color.next(), label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') axes[2] += p ## ==> fill ASCII if dsName == '000': _c = _txt['mem']['comps'] for _i in zip(table['mem'], table['malloc'], [names[i] for i in table['name']]): if not numpy.isnan(_i[0]): _c += ["dVmem|dMalloc %10.3f %10.3f kB | %s" % _i] else: self.msg.error("%s contains weird data !!", _i[-1]) _c.reverse() ## malloc table.sort(order=('malloc', )) labels = [names[i] for i in table['name'][-nData:]] ax = fig.axes[3] #ax.set_xlabel( '$\Delta \rm{Malloc}\ [kB]$' ) ax.set_xlabel('delta Malloc [kB]') data = table['malloc'][-nData:] pos = numpy.arange(len(data)) p = ax.barh(pos + (idx * 1. / nDsNames), data, 1. / nDsNames, align='edge', color=color.next(), label=dsName, lw=lw) ax.grid(True) ax.set_yticks(pos + 0.5) ax.set_yticklabels(labels, fontsize=6, horizontalalignment='right') axes[3] += p ## n-allocs table.sort(order=('nmall', )) labels = [names[i] for i in table['name'][-nData:]] ## ==> fill ASCII if dsName == '000': _c = _txt['allocs']['comps'] for _i in zip(table['nmall'], table['nfree'], [names[i] for i in table['name']]): if not numpy.isnan(_i[0]): _c += ["alloc|free %10i %10i | %s" % _i] else: self.msg.error("%s contains weird data !!", _i[-1]) _c.reverse() pass # loop over data sets
def processEvt(self, dataSetMgr, monCompMgr): from App import DataSetMgr from PyRootLib import importRoot ROOT = importRoot(batch=True) ## RootFct = ROOT.TF1 ## dummyCanvas = ROOT.TCanvas("dummyFitCanvas") ## import PyRootLib as prl ## self.sum['evt']['histos'] = [] ## self.sum['evt']['fig'] = [] ## short-hand ms = Units.ms kb = Units.kb Mb = Units.Mb Mb2Kb = 1000. msg = self.msg ## get top-20 consumers dsNames = DataSetMgr.names() color = DataSetMgr.colorIter() _txt = self.txt['evt'] monComp = monCompMgr['PerfMonSlice'] yMinCpu = [] yMaxCpu = [] yMinIo = [] yMaxIo = [] for dsName in dsNames: data = monComp.data[dsName] histos = data['histos'] = {} if not 'evt' in data: continue data = data['evt'] if data is None: continue cpu = data['cpu'] cpu_u = cpu['user'] cpu_s = cpu['sys'] cpu_r = cpu['real'] cpu_c = cpu['cpu'] dcpu_u = cpu_u[:, 2] dcpu_s = cpu_s[:, 2] dcpu_r = cpu_r[:, 2] dcpu_c = cpu_c[:, 2] mem = data['mem'] vmem = mem['vmem'] dvmem = vmem[:, 2] rss = mem['rss'] drss = rss[:, 2] mall = mem['mall'] dmall = mall[:, 2] nallocs = mem['nmall'][:, 2] nfrees = mem['nfree'][:, 2] yMinCpu.append(dcpu_c[self.minEvt:].min() * ms) yMaxCpu.append(dcpu_c[self.minEvt:].max() * ms) io = monComp.data[dsName]['io'] io_c = io['w']['cpu'] yMinIo.append(io_c[self.minEvt:].min() * ms) yMaxIo.append(io_c[self.minEvt:].max() * ms) ## data['mem/vmem/d'] = data['mem/vmem/1'] - data['mem/vmem/0'] ## data['mem/rss/d' ] = data['mem/rss/1' ] - data['mem/rss/0' ] ## fill-in some data for ASCII summary if dsName == '000': _txt['cpu']['slice'] += [ "%-20s %10.3f %10.3f %10.3f ms" % ( "[u/s/r]", dcpu_u[self.minEvt:].mean() * ms, dcpu_s[self.minEvt:].mean() * ms, dcpu_r[self.minEvt:].mean() * ms, ), ] _txt['mem']['slice'] += [ "%-20s %10.3f %10.3f %10.3f kB" % ( "[dVmem/dRss/dMalloc]", dvmem[self.minEvt:].mean() * kb, drss[self.minEvt:].mean() * kb, dmall[self.minEvt:].mean() * kb, ), ] _txt['allocs']['slice'] += [ "%-20s %10i %10i" % ( "[nallocs/nfrees]", nallocs[self.minEvt:].mean(), nfrees[self.minEvt:].mean(), ), ] ## book ROOT histos nEntries = len(dataSetMgr[dsName].bins) - 1 minEvt = dataSetMgr[dsName].bins[self.minEvt] maxEvt = dataSetMgr[dsName].bins[-1] hId = 'cpu_%s.%s' % (monComp.name, dsName) hName = 'cpu_%s' % dsName histos[hName] = ROOT.TH1F( hId, "[%s] CPU usage [%s];%s;%s" % (monComp.name, dsName, "event nbr", "Timing [ms]"), nEntries, minEvt, maxEvt) hId = 'vmem_%s.%s' % (monComp.name, dsName) hName = 'vmem_%s' % dsName histos[hName] = ROOT.TH1F( hId, "[%s] VMem usage [%s];%s;%s" % (monComp.name, dsName, "event nbr", "V-Mem [MB]"), nEntries, minEvt, maxEvt) hId = 'rss_%s.%s' % (monComp.name, dsName) hName = 'rss_%s' % dsName histos[hName] = ROOT.TH1F( hId, "[%s] RSS usage [%s];%s;%s" % (monComp.name, dsName, "event nbr", "RSS [MB]"), nEntries, minEvt, maxEvt) hId = 'io_%s.%s' % (monComp.name, dsName) hName = 'io_%s' % dsName histos[hName] = ROOT.TH1F( hId, "[%s] I/O time [%s];%s;%s" % (monComp.name, dsName, "event nbr", "I/O time [ms]"), nEntries, minEvt, maxEvt) pass yMinIo = min(yMinIo) yMaxIo = max(yMaxIo) yMinCpu = min(yMinCpu) yMaxCpu = max(yMaxCpu) def markForLegend(p): setattr(p, '_markedForLegend', True) def isMarked(p): return hasattr(p, '_markedForLegend') memLeak = [] for dsName in dsNames: if not 'evt' in monComp.data[dsName]: continue data = monComp.data[dsName] cpu = data['evt']['cpu'] cpu_c = cpu['cpu'] dcpu_c = cpu_c[:, 2] ## CPU bins = dataSetMgr[dsName].bins xbins = bins[self.minEvt:] if not 'evt/cpu' in monComp.figs: monComp.figs['evt/cpu'] = plt.figure() monComp.figs['evt/cpu'].add_subplot(211).hold(True) monComp.figs['evt/cpu'].add_subplot(212).hold(True) fig = monComp.figs['evt/cpu'] ax = fig.axes[0] pl = ax.plot(xbins, dcpu_c[self.minEvt:] * ms, linestyle='steps', label=dsName) ax.grid(True) ax.set_title("CPU time [Begin/End-Event]") ax.set_ylabel('CPU time [ms]') ax.set_xlabel('Event number') ax.set_ylim((ax.get_ylim()[0] * 0.9, ax.get_ylim()[1] * 1.1)) markForLegend(pl[0]) h, b = numpy.histogram(dcpu_c[self.minEvt:] * ms, bins=20, range=(yMinCpu * 0.90, yMaxCpu * 1.10)) ax = fig.axes[1] pl = ax.plot(b[:-1], h, label=dsName, ls='steps') ax.grid(True) ax.set_xlabel('CPU time [ms]') ax.set_ylim((ax.get_ylim()[0], ax.get_ylim()[1] * 1.1)) markForLegend(pl[0]) h = data['histos']['cpu_%s' % dsName] hAvg = bookAvgHist(h, dcpu_c * ms) data['histos'][h.GetName()] = hAvg for i in range(len(bins)): cpuTime = dcpu_c[i] * ms h.Fill(float(bins[i]), cpuTime) hAvg.Fill(cpuTime) ## Mem mem = data['evt']['mem'] vmem = mem['vmem'] dvmem = vmem[:, 2] dmall = mem['mall'][:, 2] if not 'evt/mem' in monComp.figs: monComp.figs['evt/mem'] = plt.figure() monComp.figs['evt/mem'].add_subplot(311).hold(True) monComp.figs['evt/mem'].add_subplot(312).hold(True) monComp.figs['evt/mem'].add_subplot(313).hold(True) fig = monComp.figs['evt/mem'] ax = fig.axes[0] pl = ax.plot( xbins, vmem[self.minEvt:, 1] * Mb, linestyle='steps', #'o', label=dsName) ax.set_title("Memory usage [Begin/End-Event]") ax.set_ylabel('VMem [MB]') ax.set_xlabel('Event number') ax.set_ylim((ax.get_ylim()[0] * 0.9, ax.get_ylim()[1] * 1.1)) ax.grid(True) markForLegend(pl[0]) ## fit #nFit = int(len(bins)/2.) #x = bins[-nFit:] #y = data['evt']['mem/vmem/1'][-nFit:] * Mb begFit = self._fitSlice[0] endFit = self._fitSlice[1] x = bins[begFit:endFit] y = vmem[begFit:endFit, 1] * Mb coeffs = numpy.lib.polyfit(x, y, deg=1) memLeak += [coeffs[0] * kb] ax.plot(x, numpy.lib.polyval(coeffs, x), '-', color='y', lw=2.) if dsName == '000': _txt['mem']['slice'] += [ "%-20s p[0] = %8.3f MB \tp[1] = %8.3f kB" % ( "vmem fit:", coeffs[1] * Mb, coeffs[0] * kb, # ) ] ax = fig.axes[1] pl = ax.plot(xbins, mem['rss'][self.minEvt:, 1] * Mb, linestyle='steps', label=dsName) ax.set_ylabel('RSS [MB]') ax.set_xlabel('Event number') ax.set_ylim((ax.get_ylim()[0] * 0.9, ax.get_ylim()[1] * 1.1)) ax.grid(True) markForLegend(pl[0]) ax = fig.axes[2] pl = ax.plot(xbins, dmall[self.minEvt:] * Mb, linestyle='steps', label=dsName) ax.set_ylabel('Delta Malloc [MB]') ax.set_xlabel('Event number') ax.set_ylim((ax.get_ylim()[0] * 0.9, ax.get_ylim()[1] * 1.1)) ax.grid(True) markForLegend(pl[0]) h = data['histos']['vmem_%s' % dsName] hAvg = bookAvgHist(h, mem['vmem'][:, 1] * Mb) data['histos'][h.GetName()] = hAvg for i in range(len(bins)): vmem = mem['vmem'][i, 1] * Mb h.Fill(float(bins[i]), vmem) hAvg.Fill(vmem) h = data['histos']['rss_%s' % dsName] hAvg = bookAvgHist(h, mem['rss'][:, 1] * Mb) data['histos'][h.GetName()] = hAvg for i in range(len(bins)): rss = mem['rss'][i, 1] * Mb h.Fill(float(bins[i]), rss) hAvg.Fill(rss) ## I/O if not 'evt/io' in monComp.figs: monComp.figs['evt/io'] = plt.figure() monComp.figs['evt/io'].add_subplot(211).hold(True) monComp.figs['evt/io'].add_subplot(212).hold(True) fig = monComp.figs['evt/io'] ax = fig.axes[0] io_c = data['io']['w']['cpu'] pl = ax.plot(xbins, io_c[self.minEvt:] * ms, linestyle='steps', label=dsName) ax.set_title("I/O time [CommitOutput]") ax.set_ylabel('I/O time [ms]') ax.set_xlabel('Event number') ax.set_ylim((ax.get_ylim()[0], ax.get_ylim()[1] * 1.1)) ax.grid(True) markForLegend(pl[0]) yMinIo *= 0.9 yMaxIo *= 1.1 yMinIo, yMaxIo = min(yMinIo, yMaxIo), max(yMinIo, yMaxIo) h, b = numpy.histogram(io_c[self.minEvt:] * ms, bins=20, range=(yMinIo, yMaxIo)) ax = fig.axes[1] pl = ax.plot(b[:-1], h, label=dsName, ls='steps') ax.set_xlabel('I/O time [ms]') ax.set_ylim((ax.get_ylim()[0], ax.get_ylim()[1] * 1.1)) ax.grid(True) markForLegend(pl[0]) h = data['histos']['io_%s' % dsName] hAvg = bookAvgHist(h, io_c * ms) data['histos'][h.GetName()] = hAvg for i in range(len(bins)): cpuTime = io_c[i] * ms h.Fill(float(bins[i]), cpuTime) hAvg.Fill(cpuTime) pass # loop over data sets ## handle mem-leak text ax = monComp.figs['evt/mem'].axes[0] ax.text( 0.025, 0.97, "\n".join("[%s] Leak: %8.3f kB" % (n, leak) for n, leak in zip(DataSetMgr.labels(), memLeak)), bbox=dict(facecolor='w'), #color = '', fontweight='bold', #fontsize = 'x-larger', verticalalignment='top', transform=ax.transAxes) for figName, fig in monComp.figs.items(): loc = 'best' if figName == 'evt/mem': loc = 'lower right' for ax in fig.axes: objs = [l for l in ax.lines if isMarked(l)] ax.legend( objs, DataSetMgr.labels(), #loc='lower right' #loc='best' loc=loc) ## get top-20 consumers self._top_consumers(dataSetMgr, monCompMgr, compTypes=('alg', ), title='Event loop', storeName='evt', sliceName='evt', begSlice=self.minEvt, endSlice=None) return