2 from __future__
import print_function
3 from builtins
import range
4 from itertools
import groupby
5 from operator
import attrgetter,itemgetter
7 from collections
import defaultdict
11 To Use: Add the StallMonitor Service to the cmsRun job you want to check for 12 stream stalls. Use something like this in the configuration: 14 process.add_(cms.Service("StallMonitor", fileName = cms.untracked.string("stallMonitor.log"))) 16 After running the job, execute this script and pass the name of the 17 StallMonitor log file to the script. 19 By default, the script will then print an 'ASCII art' stall graph 20 which consists of a line of text for each time a module or the 21 source stops or starts. Each line contains the name of the module 22 which either started or stopped running, and the number of modules 23 running on each stream at that moment in time. After that will be 24 the time and stream number. Then if a module just started, you 25 will also see the amount of time the module spent between finishing 26 its prefetching and starting. The state of a module is represented 29 plus ("+") the stream has just finished waiting and is starting a module 30 minus ("-") the stream just finished running a module 32 If a module had to wait more than 0.1 seconds, the end of the line 33 will have "STALLED". Startup actions, e.g. reading conditions, 34 may affect results for the first few events. 36 Using the command line arguments described above you can make the 37 program create a PDF file with actual graphs instead of the 'ASCII art' 40 Once the graph is completed, the program outputs the list of modules 41 which had the greatest total stall times. The list is sorted by 42 total stall time and written in descending order. In addition, the 43 list of all stall times for the module is given. 45 There is an inferior alternative (an old obsolete way). 46 Instead of using the StallMonitor Service, you can use the 47 Tracer Service. Make sure to use the 'printTimestamps' option 48 cms.Service("Tracer", printTimestamps = cms.untracked.bool(True)) 49 There are problems associated with this and it is not recommended.''' 52 kStallThreshold=100000
63 kStartedSourceDelayedRead=7
64 kFinishedSourceDelayedRead=8
67 kSourceFindEvent =
"sourceFindEvent" 68 kSourceDelayedRead =
"sourceDelayedRead" 76 if not l
or l[0] ==
'#':
78 (step,payload) =
tuple(l.split(
None,1))
79 payload=payload.split()
82 if step ==
'E' or step ==
'e' or step ==
'F' or step ==
'f':
87 stream =
int(payload[0])
88 time =
int(payload[-1])
95 if step ==
'S' or step ==
's':
96 name = kSourceFindEvent
97 trans = kStartedSource
100 trans = kFinishedSource
103 moduleID = payload[1]
108 if step ==
'p' or step ==
'M' or step ==
'm':
114 if step ==
'm' or step ==
'M':
115 isEvent = (
int(payload[2]) == 0)
116 name = moduleNames[moduleID]
121 if step ==
'q' or step ==
'N' or step ==
'n':
127 if step ==
'n' or step ==
'N':
128 isEvent = (
int(payload[2]) == 0)
129 name = esModuleNames[moduleID]
133 elif step ==
'A' or step ==
'a':
134 trans = kStartedAcquire
136 trans = kFinishedAcquire
137 name = moduleNames[moduleID]
142 elif step ==
'R' or step == 'r': 143 trans = kStartedSourceDelayedRead 145 trans = kFinishedSourceDelayedRead 146 name = kSourceDelayedRead 148 if trans
is not None:
149 yield (name,trans,stream,time, isEvent)
156 numStreamsFromSource = 0
159 frameworkTransitions =
False 162 if l
and l[0] ==
'M':
166 numStreams =
int(i[1])+1
168 if numStreams == 0
and l
and l[0] ==
'S':
169 s =
int(l.split(
' ')[1])
170 if s > numStreamsFromSource:
171 numStreamsFromSource = s
172 if len(l) > 5
and l[0:2] ==
"#M":
174 moduleNames[id] = name
176 if len(l) > 5
and l[0:2] ==
"#N":
178 esModuleNames[id] = name
180 if len(l) > 40
and l[0:24] ==
"# preFrameworkTransition":
181 frameworkTransitions =
True 185 numStreams = numStreamsFromSource +2
190 for n
in moduleNames.items():
192 for n
in esModuleNames.items():
195 if frameworkTransitions:
199 """Create a generator which can step through the file and return each processing step. 200 Using a generator reduces the memory overhead when parsing a large file. 208 time = line.split(
" ")[1]
209 time = time.split(
":")
210 time =
int(time[0])*60*60+
int(time[1])*60+
float(time[2])
211 time =
int(1000000*time)
242 streamsThatSawFirstEvent = set()
250 if l.find(
"processing event :") != -1:
251 name = kSourceFindEvent
252 trans = kStartedSource
254 if l.find(
"starting:") != -1:
255 trans = kFinishedSource
256 elif l.find(
"processing event for module") != -1:
258 if l.find(
"finished:") != -1:
259 if l.find(
"prefetching") != -1:
264 if l.find(
"prefetching") != -1:
267 name = l.split(
"'")[1]
268 elif l.find(
"processing event acquire for module:") != -1:
269 trans = kStartedAcquire
270 if l.find(
"finished:") != -1:
271 trans = kFinishedAcquire
272 name = l.split(
"'")[1]
273 elif l.find(
"event delayed read from source") != -1:
274 trans = kStartedSourceDelayedRead
275 if l.find(
"finished:") != -1:
276 trans = kFinishedSourceDelayedRead
277 name = kSourceDelayedRead
278 if trans
is not None:
282 time = time - startTime
283 streamIndex = l.find(
"stream = ")
284 stream =
int(l[streamIndex+9:l.find(
" ",streamIndex+10)])
285 maxNameSize =
max(maxNameSize, len(name))
287 if trans == kFinishedSource
and not stream
in streamsThatSawFirstEvent:
290 processingSteps.append((name,kStartedSource,stream,time,
True))
291 streamsThatSawFirstEvent.add(stream)
293 processingSteps.append((name,trans,stream,time,
True))
294 numStreams =
max(numStreams, stream+1)
297 return (processingSteps,numStreams,maxNameSize)
303 return self._processingSteps
308 firstLine = inputFile.readline().
rstrip()
312 fifthLine = inputFile.readline().
rstrip()
314 if (firstLine.find(
"# Transition") != -1)
or (firstLine.find(
"# Step") != -1):
315 print(
"> ... Parsing StallMonitor output.")
316 return StallMonitorParser
318 if firstLine.find(
"++") != -1
or fifthLine.find(
"++") != -1:
321 print(
"> ... Parsing Tracer output.")
325 print(
"Unknown input format.")
331 return parseInput(inputFile)
345 streamTime = [0]*numStreams
346 streamState = [0]*numStreams
348 modulesActiveOnStream = [{}
for x
in range(numStreams)]
349 for n,trans,s,time,isEvent
in processingSteps:
352 modulesOnStream = modulesActiveOnStream[s]
353 if trans == kPrefetchEnd:
354 modulesOnStream[n] = time
355 elif trans == kStarted
or trans == kStartedAcquire:
356 if n
in modulesOnStream:
357 waitTime = time - modulesOnStream[n]
358 modulesOnStream.pop(n,
None)
360 elif trans == kFinished
or trans == kFinishedAcquire:
363 elif trans == kStartedSourceDelayedRead:
364 if streamState[s] == 0:
365 waitTime = time - streamTime[s]
366 elif trans == kStartedSource:
367 modulesOnStream.clear()
368 elif trans == kFinishedSource
or trans == kFinishedSourceDelayedRead:
370 if waitTime
is not None:
371 if waitTime > kStallThreshold:
372 t = stalledModules.setdefault(n,[])
374 return stalledModules
379 streamTime = [0]*numStreams
380 streamState = [0]*numStreams
381 moduleTimings = defaultdict(list)
382 modulesActiveOnStream = [defaultdict(int)
for x
in range(numStreams)]
383 for n,trans,s,time,isEvent
in processingSteps:
385 modulesOnStream = modulesActiveOnStream[s]
387 if trans == kStarted:
389 modulesOnStream[n]=time
390 elif trans == kFinished:
391 waitTime = time - modulesOnStream[n]
392 modulesOnStream.pop(n,
None)
396 with open(
'module-timings.json',
'w')
as outfile:
397 outfile.write(json.dumps(moduleTimings, indent=4))
401 streamTime = [0]*numStreams
402 streamState = [0]*numStreams
403 modulesActiveOnStreams = [{}
for x
in range(numStreams)]
404 for n,trans,s,time,isEvent
in processingSteps:
406 modulesActiveOnStream = modulesActiveOnStreams[s]
407 if trans == kPrefetchEnd:
408 modulesActiveOnStream[n] = time
410 elif trans == kStartedAcquire
or trans == kStarted:
411 if n
in modulesActiveOnStream:
412 waitTime = time - modulesActiveOnStream[n]
413 modulesActiveOnStream.pop(n,
None)
415 elif trans == kFinishedAcquire
or trans == kFinished:
418 elif trans == kStartedSourceDelayedRead:
419 if streamState[s] == 0:
420 waitTime = time - streamTime[s]
421 elif trans == kStartedSource:
422 modulesActiveOnStream.clear()
423 elif trans == kFinishedSource
or trans == kFinishedSourceDelayedRead:
425 states =
"%-*s: " % (maxNameSize,n)
426 if trans == kStartedAcquire
or trans == kStarted
or trans == kStartedSourceDelayedRead
or trans == kStartedSource:
430 for index, state
in enumerate(streamState):
431 if n==kSourceFindEvent
and index == s:
434 states +=
str(state)+
" " 435 states +=
" -- " +
str(time/1000.) +
" " +
str(s) +
" " 436 if waitTime
is not None:
437 states +=
" %.2f"% (waitTime/1000.)
438 if waitTime > kStallThreshold:
447 for name,t
in stalledModules.items():
448 maxNameSize =
max(maxNameSize, len(name))
450 priorities.append((name,sum(t),t))
452 priorities.sort(key=
lambda a: a[1], reverse=
True)
454 nameColumn =
"Stalled Module" 455 maxNameSize =
max(maxNameSize, len(nameColumn))
457 stallColumn =
"Tot Stall Time" 458 stallColumnLength = len(stallColumn)
460 print(
"%-*s" % (maxNameSize, nameColumn),
"%-*s"%(stallColumnLength,stallColumn),
" Stall Times")
461 for n,s,t
in priorities:
462 paddedName =
"%-*s:" % (maxNameSize,n)
463 print(paddedName,
"%-*.2f"%(stallColumnLength,s/1000.),
", ".
join([
"%.2f"%(x/1000.)
for x
in t]))
472 return "(x: {}, y: {})".
format(self.
x,self.
y)
482 tmp =
Point(ps[0].x, ps[0].y)
484 if abs(tmp.x -p.x)<kTimeFuzz:
487 reducedPoints.append(tmp)
488 tmp =
Point(p.x, p.y)
489 reducedPoints.append(tmp)
490 reducedPoints = [p
for p
in reducedPoints
if p.y != 0]
496 for pairList
in pairLists:
497 points += [
Point(x[0], 1)
for x
in pairList
if x[1] != 0]
498 points += [
Point(sum(x),-1)
for x
in pairList
if x[1] != 0]
499 points.sort(key=attrgetter(
'x'))
511 if len(self.
data) != 0:
512 tmp += self.
data[-1][1]
514 tmp.sort(key=attrgetter(
'x'))
533 oldStreamInfo = streamInfo
534 streamInfo = [[]
for x
in range(numStreams)]
536 for s
in range(numStreams):
538 lastStartTime,lastTimeLength,lastColor = oldStreamInfo[s][0].
unpack()
539 for info
in oldStreamInfo[s][1:]:
540 start,length,color = info.unpack()
541 if color == lastColor
and lastStartTime+lastTimeLength == start:
542 lastTimeLength += length
545 lastStartTime = start
546 lastTimeLength = length
563 lastStartTime,lastTimeLength,lastHeight = oldBlocks[0]
564 for start,length,height
in oldBlocks[1:]:
565 if height == lastHeight
and abs(lastStartTime+lastTimeLength - start) < kTimeFuzz:
566 lastTimeLength += length
568 blocks.append((lastStartTime,lastTimeLength,lastHeight))
569 lastStartTime = start
570 lastTimeLength = length
572 blocks.append((lastStartTime,lastTimeLength,lastHeight))
578 points = sorted(points, key=attrgetter(
'x'))
582 for t1,t2
in zip(points, points[1:]):
590 if streamHeight < streamHeightCut:
592 preparedTimes.append((t1.x,t2.x-t1.x, streamHeight))
593 preparedTimes.sort(key=itemgetter(2))
596 for nthreads, ts
in groupby(preparedTimes, itemgetter(2)):
597 theTS = [(t[0],t[1])
for t
in ts]
599 theTimes = [(t[0]/1000000.,t[1]/1000000.)
for t
in theTS]
600 yspan = (stream-0.4+height,height*(nthreads-1))
601 ax.broken_barh(theTimes, yspan, facecolors=color, edgecolors=color, linewidth=0)
603 allStackTimes[color].extend(theTS*(nthreads-threadOffset))
615 return super().
add(item)
625 def createPDFImage(pdfFile, shownStacks, showStreams, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder, setXAxis, xLower, xUpper):
627 stalledModuleNames = set([x
for x
in iter(stalledModuleInfo)])
628 streamLowestRow = [[]
for x
in range(numStreams)]
630 acquireActiveOnStreams = [set()
for x
in range(numStreams)]
631 externalWorkOnStreams = [set()
for x
in range(numStreams)]
632 previousFinishTime = [
None for x
in range(numStreams)]
633 streamRunningTimes = [[]
for x
in range(numStreams)]
634 streamExternalWorkRunningTimes = [[]
for x
in range(numStreams)]
635 maxNumberOfConcurrentModulesOnAStream = 1
636 externalWorkModulesInJob =
False 637 previousTime = [0
for x
in range(numStreams)]
640 finishBeforeStart = [set()
for x
in range(numStreams)]
641 finishAcquireBeforeStart = [set()
for x
in range(numStreams)]
642 countSource = [0
for x
in range(numStreams)]
643 countDelayedSource = [0
for x
in range(numStreams)]
644 countExternalWork = [defaultdict(int)
for x
in range(numStreams)]
647 for n,trans,s,time,isEvent
in processingSteps:
648 if timeOffset
is None:
653 if time < previousTime[s]:
654 time = previousTime[s]
655 previousTime[s] = time
657 activeModules = modulesActiveOnStreams[s]
658 acquireModules = acquireActiveOnStreams[s]
659 externalWorkModules = externalWorkOnStreams[s]
661 if trans == kStarted
or trans == kStartedSourceDelayedRead
or trans == kStartedAcquire
or trans == kStartedSource :
668 if trans == kStarted:
669 countExternalWork[s][n] -= 1
670 if n
in finishBeforeStart[s]:
671 finishBeforeStart[s].
remove(n)
673 elif trans == kStartedAcquire:
674 if n
in finishAcquireBeforeStart[s]:
675 finishAcquireBeforeStart[s].
remove(n)
678 if trans == kStartedSourceDelayedRead:
679 countDelayedSource[s] += 1
680 if countDelayedSource[s] < 1:
682 elif trans == kStartedSource:
684 if countSource[s] < 1:
687 moduleNames = activeModules.copy()
688 moduleNames.update(acquireModules)
689 if trans == kStartedAcquire:
690 acquireModules.add(n)
694 if moduleNames
or externalWorkModules:
695 startTime = previousFinishTime[s]
696 previousFinishTime[s] = time
698 if trans == kStarted
and n
in externalWorkModules:
699 externalWorkModules.remove(n)
700 streamExternalWorkRunningTimes[s].
append(
Point(time, -1))
702 nTotalModules = len(activeModules) + len(acquireModules) + len(externalWorkModules)
703 maxNumberOfConcurrentModulesOnAStream =
max(maxNumberOfConcurrentModulesOnAStream, nTotalModules)
704 elif trans == kFinished
or trans == kFinishedSourceDelayedRead
or trans == kFinishedAcquire
or trans == kFinishedSource :
706 if trans == kFinished:
707 if n
not in activeModules:
708 finishBeforeStart[s].
add(n)
711 if trans == kFinishedSourceDelayedRead:
712 countDelayedSource[s] -= 1
713 if countDelayedSource[s] < 0:
715 elif trans == kFinishedSource:
717 if countSource[s] < 0:
720 if trans == kFinishedAcquire:
722 countExternalWork[s][n] += 1
723 if displayExternalWork:
724 externalWorkModulesInJob =
True 725 if (
not checkOrder)
or countExternalWork[s][n] > 0:
726 externalWorkModules.add(n)
727 streamExternalWorkRunningTimes[s].
append(
Point(time,+1))
728 if checkOrder
and n
not in acquireModules:
729 finishAcquireBeforeStart[s].
add(n)
732 startTime = previousFinishTime[s]
733 previousFinishTime[s] = time
734 moduleNames = activeModules.copy()
735 moduleNames.update(acquireModules)
737 if trans == kFinishedAcquire:
738 acquireModules.remove(n)
739 elif trans == kFinishedSourceDelayedRead:
740 if countDelayedSource[s] == 0:
741 activeModules.remove(n)
742 elif trans == kFinishedSource:
743 if countSource[s] == 0:
744 activeModules.remove(n)
746 activeModules.remove(n)
748 if startTime
is not None:
754 elif (kSourceDelayedRead
in moduleNames)
or (kSourceFindEvent
in moduleNames):
757 for n
in moduleNames:
758 if n
in stalledModuleNames:
765 if shownStacks
and showStreams:
767 fig, ax = plt.subplots(nrows=nr, squeeze=
True)
769 if shownStacks
and showStreams:
770 [xH,yH] = fig.get_size_inches()
771 fig.set_size_inches(xH,yH*4/3)
772 ax = plt.subplot2grid((4,1),(0,0), rowspan=3)
773 axStack = plt.subplot2grid((4,1),(3,0))
774 if shownStacks
and not showStreams:
777 ax.set_xlabel(
"Time (sec)")
778 ax.set_ylabel(
"Stream ID")
779 ax.set_ylim(-0.5,numStreams-0.5)
780 ax.yaxis.set_ticks(
range(numStreams))
782 ax.set_xlim((xLower, xUpper))
784 height = 0.8/maxNumberOfConcurrentModulesOnAStream
785 allStackTimes={
'green': [],
'limegreen':[],
'red': [],
'blue': [],
'orange': [],
'darkviolet': []}
786 for iStream,lowestRow
in enumerate(streamLowestRow):
787 times=[(x.begin/1000000., x.delta/1000000.)
for x
in lowestRow]
788 colors=[x.color
for x
in lowestRow]
791 ax.broken_barh(times,(iStream-0.4,height),facecolors=colors,edgecolors=colors,linewidth=0)
794 for info
in lowestRow:
795 if not info.color ==
'darkviolet':
796 allStackTimes[info.color].
append((info.begin, info.delta))
799 if maxNumberOfConcurrentModulesOnAStream > 1
or externalWorkModulesInJob:
801 for i,perStreamRunningTimes
in enumerate(streamRunningTimes):
803 perStreamTimesWithExtendedWork = list(perStreamRunningTimes)
804 perStreamTimesWithExtendedWork.extend(streamExternalWorkRunningTimes[i])
807 allStackTimes, ax, i, height,
810 addToStackTimes=
False,
815 allStackTimes, ax, i, height,
818 addToStackTimes=
True,
823 allStackTimes, ax, i, height,
826 addToStackTimes=
True,
831 print(
"> ... Generating stack")
833 for color
in [
'green',
'limegreen',
'blue',
'red',
'orange',
'darkviolet']:
834 tmp = allStackTimes[color]
836 stack.update(color, tmp)
838 for stk
in reversed(stack.data):
844 for p1,p2
in zip(stk[1], stk[1][1:]):
846 xs.append((p1.x, p2.x-p1.x, height))
847 xs.sort(key = itemgetter(2))
850 for height, xpairs
in groupby(xs, itemgetter(2)):
851 finalxs = [(e[0]/1000000.,e[1]/1000000.)
for e
in xpairs]
853 axStack.broken_barh(finalxs, (0, height), facecolors=color, edgecolors=color, linewidth=0)
855 axStack.set_xlabel(
"Time (sec)");
856 axStack.set_ylabel(
"# modules");
857 axStack.set_xlim(ax.get_xlim())
858 axStack.tick_params(top=
'off')
860 fig.text(0.1, 0.95,
"modules running event", color =
"green", horizontalalignment =
'left')
861 fig.text(0.1, 0.92,
"modules running other", color =
"limegreen", horizontalalignment =
'left')
862 fig.text(0.5, 0.95,
"stalled module running", color =
"red", horizontalalignment =
'center')
863 fig.text(0.9, 0.95,
"read from input", color =
"orange", horizontalalignment =
'right')
864 fig.text(0.5, 0.92,
"multiple modules running", color =
"blue", horizontalalignment =
'center')
865 if displayExternalWork:
866 fig.text(0.9, 0.92,
"external work", color =
"darkviolet", horizontalalignment =
'right')
867 print(
"> ... Saving to file: '{}'".
format(pdfFile))
871 if __name__==
"__main__":
877 parser = argparse.ArgumentParser(description=
'Convert a text file created by cmsRun into a stream stall graph.',
878 formatter_class=argparse.RawDescriptionHelpFormatter,
880 parser.add_argument(
'filename',
881 type=argparse.FileType(
'r'), # open file 882 help='file to process')
883 parser.add_argument(
'-g',
'--graph',
885 metavar=
"'stall.pdf'",
888 help=
'''Create pdf file of stream stall graph. If -g is specified 889 by itself, the default file name is \'stall.pdf\'. Otherwise, the 890 argument to the -g option is the filename.''')
891 parser.add_argument(
'-s',
'--stack',
893 help=
'''Create stack plot, combining all stream-specific info. 894 Can be used only when -g is specified.''')
895 parser.add_argument(
'--no_streams', action=
'store_true',
896 help=
'''Do not show per stream plots. 897 Can be used only when -g and -s are specified.''')
898 parser.add_argument(
'-e',
'--external',
899 action=
'store_false',
900 help=
'''Suppress display of external work in graphs.''')
901 parser.add_argument(
'-o',
'--order',
903 help=
'''Enable checks for and repair of transitions in the input that are in the wrong order (for example a finish transition before a corresponding start). This is always enabled for Tracer input, but is usually an unnecessary waste of CPU time and memory with StallMonitor input and by default not enabled.''')
904 parser.add_argument(
'-t',
'--timings',
906 help=
'''Create a dictionary of module labels and their timings from the stall monitor log. Write the dictionary filea as a json file modules-timings.json.''')
907 parser.add_argument(
'-l',
'--lowerxaxis',
910 help=
'''Lower limit of x axis, default 0, not used if upper limit not set''')
911 parser.add_argument(
'-u',
'--upperxaxis',
913 help=
'''Upper limit of x axis, if not set then x axis limits are set automatically''')
914 args = parser.parse_args()
917 inputFile = args.filename
919 shownStacks = args.stack
920 showStreams =
not args.no_streams
921 displayExternalWork = args.external
922 checkOrder = args.order
923 doModuleTimings =
False 925 doModuleTimings =
True 929 if args.upperxaxis
is not None:
931 xUpper = args.upperxaxis
932 xLower = args.lowerxaxis
935 if pdfFile
is not None:
939 matplotlib.use(
"PDF")
940 import matplotlib.pyplot
as plt
941 if not re.match(
r'^[\w\.]+$', pdfFile):
942 print(
"Malformed file name '{}' supplied with the '-g' option.".
format(pdfFile))
943 print(
"Only characters 0-9, a-z, A-Z, '_', and '.' are allowed.")
947 extension = pdfFile.split(
'.')[-1]
948 supported_filetypes = plt.figure().canvas.get_supported_filetypes()
949 if not extension
in supported_filetypes:
950 print(
"A graph cannot be saved to a filename with extension '{}'.".
format(extension))
951 print(
"The allowed extensions are:")
952 for filetype
in supported_filetypes:
956 if pdfFile
is None and shownStacks:
957 print(
"The -s (--stack) option can be used only when the -g (--graph) option is specified.")
959 if pdfFile
and (
not shownStacks
and not showStreams):
960 print(
"When using -g, one must either specify -s OR do not specify --no_streams")
963 sys.stderr.write(
">reading file: '{}'\n".
format(inputFile.name))
967 sys.stderr.write(
">processing data\n")
972 sys.stderr.write(
">preparing ASCII art\n")
973 createAsciiImage(reader.processingSteps(), reader.numStreams, reader.maxNameSize)
975 sys.stderr.write(
">creating PDF\n")
976 createPDFImage(pdfFile, shownStacks, showStreams, reader.processingSteps(), reader.numStreams, stalledModules, displayExternalWork, checkOrder, setXAxis, xLower, xUpper)
979 sys.stderr.write(
">creating module-timings.json\n")
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float zip(ConstView const &tracks, int32_t i)
void rstrip(TString &in, TString separator="#")
def update(self, graphType, points)
def findStalledModules(processingSteps, numStreams)
def mergeContiguousBlocks(blocks)
def consolidateContiguousBlocks(numStreams, streamInfo)
def __init__(self, begin_, delta_, color_)
def createPDFImage(pdfFile, shownStacks, showStreams, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder, setXAxis, xLower, xUpper)
std::pair< unsigned int, unsigned int > unpack(cond::Time_t since)
def chooseParser(inputFile)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Abs< T >::type abs(const T &t)
def createModuleTiming(processingSteps, numStreams)
def processingStepsFromStallMonitorOutput(f, moduleNames, esModuleNames)
def printStalledModulesInOrder(stalledModules)
def createAsciiImage(processingSteps, numStreams, maxNameSize)
def reduceSortedPoints(ps)
def split(sequence, size)
static std::string join(char **cmd)
def processingSteps(self)
def processingSteps(self)
def remove(d, key, TELL=False)
def readLogFile(inputFile)
def __init__(self, x_, y_)
void add(std::map< std::string, TH1 *> &h, TH1 *hist)
def adjacentDiff(pairLists)
def plotPerStreamAboveFirstAndPrepareStack(points, allStackTimes, ax, stream, height, streamHeightCut, doPlot, addToStackTimes, color, threadOffset)