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':
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
161 if l
and l[0] ==
'M':
165 numStreams =
int(i[1])+1
167 if numStreams == 0
and l
and l[0] ==
'S':
168 s =
int(l.split(
' ')[1])
169 if s > numStreamsFromSource:
170 numStreamsFromSource = s
171 if len(l) > 5
and l[0:2] ==
"#M":
173 moduleNames[id] = name
175 if len(l) > 5
and l[0:2] ==
"#N":
177 esModuleNames[id] = name
182 numStreams = numStreamsFromSource +2
187 for n
in moduleNames.items():
189 for n
in esModuleNames.items():
194 """Create a generator which can step through the file and return each processing step. 195 Using a generator reduces the memory overhead when parsing a large file. 203 time = line.split(
" ")[1]
204 time = time.split(
":")
205 time =
int(time[0])*60*60+
int(time[1])*60+
float(time[2])
206 time =
int(1000000*time)
237 streamsThatSawFirstEvent = set()
245 if l.find(
"processing event :") != -1:
246 name = kSourceFindEvent
247 trans = kStartedSource
249 if l.find(
"starting:") != -1:
250 trans = kFinishedSource
251 elif l.find(
"processing event for module") != -1:
253 if l.find(
"finished:") != -1:
254 if l.find(
"prefetching") != -1:
259 if l.find(
"prefetching") != -1:
262 name = l.split(
"'")[1]
263 elif l.find(
"processing event acquire for module:") != -1:
264 trans = kStartedAcquire
265 if l.find(
"finished:") != -1:
266 trans = kFinishedAcquire
267 name = l.split(
"'")[1]
268 elif l.find(
"event delayed read from source") != -1:
269 trans = kStartedSourceDelayedRead
270 if l.find(
"finished:") != -1:
271 trans = kFinishedSourceDelayedRead
272 name = kSourceDelayedRead
273 if trans
is not None:
277 time = time - startTime
278 streamIndex = l.find(
"stream = ")
279 stream =
int(l[streamIndex+9:l.find(
" ",streamIndex+10)])
280 maxNameSize =
max(maxNameSize, len(name))
282 if trans == kFinishedSource
and not stream
in streamsThatSawFirstEvent:
285 processingSteps.append((name,kStartedSource,stream,time,
True))
286 streamsThatSawFirstEvent.add(stream)
288 processingSteps.append((name,trans,stream,time,
True))
289 numStreams =
max(numStreams, stream+1)
292 return (processingSteps,numStreams,maxNameSize)
298 return self._processingSteps
303 firstLine = inputFile.readline().rstrip()
307 fifthLine = inputFile.readline().rstrip()
309 if (firstLine.find(
"# Transition") != -1)
or (firstLine.find(
"# Step") != -1):
310 print(
"> ... Parsing StallMonitor output.")
311 return StallMonitorParser
313 if firstLine.find(
"++") != -1
or fifthLine.find(
"++") != -1:
316 print(
"> ... Parsing Tracer output.")
320 print(
"Unknown input format.")
326 return parseInput(inputFile)
340 streamTime = [0]*numStreams
341 streamState = [0]*numStreams
343 modulesActiveOnStream = [{}
for x
in range(numStreams)]
344 for n,trans,s,time,isEvent
in processingSteps:
347 modulesOnStream = modulesActiveOnStream[s]
348 if trans == kPrefetchEnd:
349 modulesOnStream[n] = time
350 elif trans == kStarted
or trans == kStartedAcquire:
351 if n
in modulesOnStream:
352 waitTime = time - modulesOnStream[n]
353 modulesOnStream.pop(n,
None)
355 elif trans == kFinished
or trans == kFinishedAcquire:
358 elif trans == kStartedSourceDelayedRead:
359 if streamState[s] == 0:
360 waitTime = time - streamTime[s]
361 elif trans == kStartedSource:
362 modulesOnStream.clear()
363 elif trans == kFinishedSource
or trans == kFinishedSourceDelayedRead:
365 if waitTime
is not None:
366 if waitTime > kStallThreshold:
367 t = stalledModules.setdefault(n,[])
369 return stalledModules
374 streamTime = [0]*numStreams
375 streamState = [0]*numStreams
376 moduleTimings = defaultdict(list)
377 modulesActiveOnStream = [defaultdict(int)
for x
in range(numStreams)]
378 for n,trans,s,time,isEvent
in processingSteps:
380 modulesOnStream = modulesActiveOnStream[s]
382 if trans == kStarted:
384 modulesOnStream[n]=time
385 elif trans == kFinished:
386 waitTime = time - modulesOnStream[n]
387 modulesOnStream.pop(n,
None)
391 with open(
'module-timings.json',
'w')
as outfile:
392 outfile.write(json.dumps(moduleTimings, indent=4))
396 streamTime = [0]*numStreams
397 streamState = [0]*numStreams
398 modulesActiveOnStreams = [{}
for x
in range(numStreams)]
399 for n,trans,s,time,isEvent
in processingSteps:
401 modulesActiveOnStream = modulesActiveOnStreams[s]
402 if trans == kPrefetchEnd:
403 modulesActiveOnStream[n] = time
405 elif trans == kStartedAcquire
or trans == kStarted:
406 if n
in modulesActiveOnStream:
407 waitTime = time - modulesActiveOnStream[n]
408 modulesActiveOnStream.pop(n,
None)
410 elif trans == kFinishedAcquire
or trans == kFinished:
413 elif trans == kStartedSourceDelayedRead:
414 if streamState[s] == 0:
415 waitTime = time - streamTime[s]
416 elif trans == kStartedSource:
417 modulesActiveOnStream.clear()
418 elif trans == kFinishedSource
or trans == kFinishedSourceDelayedRead:
420 states =
"%-*s: " % (maxNameSize,n)
421 if trans == kStartedAcquire
or trans == kStarted
or trans == kStartedSourceDelayedRead
or trans == kStartedSource:
425 for index, state
in enumerate(streamState):
426 if n==kSourceFindEvent
and index == s:
429 states +=
str(state)+
" " 430 states +=
" -- " +
str(time/1000.) +
" " +
str(s) +
" " 431 if waitTime
is not None:
432 states +=
" %.2f"% (waitTime/1000.)
433 if waitTime > kStallThreshold:
442 for name,t
in stalledModules.items():
443 maxNameSize =
max(maxNameSize, len(name))
445 priorities.append((name,sum(t),t))
447 priorities.sort(key=
lambda a: a[1], reverse=
True)
449 nameColumn =
"Stalled Module" 450 maxNameSize =
max(maxNameSize, len(nameColumn))
452 stallColumn =
"Tot Stall Time" 453 stallColumnLength = len(stallColumn)
455 print(
"%-*s" % (maxNameSize, nameColumn),
"%-*s"%(stallColumnLength,stallColumn),
" Stall Times")
456 for n,s,t
in priorities:
457 paddedName =
"%-*s:" % (maxNameSize,n)
458 print(paddedName,
"%-*.2f"%(stallColumnLength,s/1000.),
", ".
join([
"%.2f"%(x/1000.)
for x
in t]))
467 return "(x: {}, y: {})".
format(self.
x,self.
y)
477 tmp =
Point(ps[0].x, ps[0].y)
479 if abs(tmp.x -p.x)<kTimeFuzz:
482 reducedPoints.append(tmp)
483 tmp =
Point(p.x, p.y)
484 reducedPoints.append(tmp)
485 reducedPoints = [p
for p
in reducedPoints
if p.y != 0]
491 for pairList
in pairLists:
492 points += [
Point(x[0], 1)
for x
in pairList
if x[1] != 0]
493 points += [
Point(sum(x),-1)
for x
in pairList
if x[1] != 0]
494 points.sort(key=attrgetter(
'x'))
506 if len(self.
data) != 0:
507 tmp += self.
data[-1][1]
509 tmp.sort(key=attrgetter(
'x'))
528 oldStreamInfo = streamInfo
529 streamInfo = [[]
for x
in range(numStreams)]
531 for s
in range(numStreams):
533 lastStartTime,lastTimeLength,lastColor = oldStreamInfo[s][0].
unpack()
534 for info
in oldStreamInfo[s][1:]:
535 start,length,color = info.unpack()
536 if color == lastColor
and lastStartTime+lastTimeLength == start:
537 lastTimeLength += length
540 lastStartTime = start
541 lastTimeLength = length
558 lastStartTime,lastTimeLength,lastHeight = oldBlocks[0]
559 for start,length,height
in oldBlocks[1:]:
560 if height == lastHeight
and abs(lastStartTime+lastTimeLength - start) < kTimeFuzz:
561 lastTimeLength += length
563 blocks.append((lastStartTime,lastTimeLength,lastHeight))
564 lastStartTime = start
565 lastTimeLength = length
567 blocks.append((lastStartTime,lastTimeLength,lastHeight))
573 points = sorted(points, key=attrgetter(
'x'))
577 for t1,t2
in zip(points, points[1:]):
585 if streamHeight < streamHeightCut:
587 preparedTimes.append((t1.x,t2.x-t1.x, streamHeight))
588 preparedTimes.sort(key=itemgetter(2))
591 for nthreads, ts
in groupby(preparedTimes, itemgetter(2)):
592 theTS = [(t[0],t[1])
for t
in ts]
594 theTimes = [(t[0]/1000000.,t[1]/1000000.)
for t
in theTS]
595 yspan = (stream-0.4+height,height*(nthreads-1))
596 ax.broken_barh(theTimes, yspan, facecolors=color, edgecolors=color, linewidth=0)
598 allStackTimes[color].extend(theTS*(nthreads-threadOffset))
610 return super().
add(item)
620 def createPDFImage(pdfFile, shownStacks, showStreams, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder, setXAxis, xLower, xUpper):
622 stalledModuleNames = set([x
for x
in iter(stalledModuleInfo)])
623 streamLowestRow = [[]
for x
in range(numStreams)]
625 acquireActiveOnStreams = [set()
for x
in range(numStreams)]
626 externalWorkOnStreams = [set()
for x
in range(numStreams)]
627 previousFinishTime = [
None for x
in range(numStreams)]
628 streamRunningTimes = [[]
for x
in range(numStreams)]
629 streamExternalWorkRunningTimes = [[]
for x
in range(numStreams)]
630 maxNumberOfConcurrentModulesOnAStream = 1
631 externalWorkModulesInJob =
False 632 previousTime = [0
for x
in range(numStreams)]
635 finishBeforeStart = [set()
for x
in range(numStreams)]
636 finishAcquireBeforeStart = [set()
for x
in range(numStreams)]
637 countSource = [0
for x
in range(numStreams)]
638 countDelayedSource = [0
for x
in range(numStreams)]
639 countExternalWork = [defaultdict(int)
for x
in range(numStreams)]
642 for n,trans,s,time,isEvent
in processingSteps:
643 if timeOffset
is None:
648 if time < previousTime[s]:
649 time = previousTime[s]
650 previousTime[s] = time
652 activeModules = modulesActiveOnStreams[s]
653 acquireModules = acquireActiveOnStreams[s]
654 externalWorkModules = externalWorkOnStreams[s]
656 if trans == kStarted
or trans == kStartedSourceDelayedRead
or trans == kStartedAcquire
or trans == kStartedSource :
663 if trans == kStarted:
664 countExternalWork[s][n] -= 1
665 if n
in finishBeforeStart[s]:
666 finishBeforeStart[s].
remove(n)
668 elif trans == kStartedAcquire:
669 if n
in finishAcquireBeforeStart[s]:
670 finishAcquireBeforeStart[s].
remove(n)
673 if trans == kStartedSourceDelayedRead:
674 countDelayedSource[s] += 1
675 if countDelayedSource[s] < 1:
677 elif trans == kStartedSource:
679 if countSource[s] < 1:
682 moduleNames = activeModules.copy()
683 moduleNames.update(acquireModules)
684 if trans == kStartedAcquire:
685 acquireModules.add(n)
689 if moduleNames
or externalWorkModules:
690 startTime = previousFinishTime[s]
691 previousFinishTime[s] = time
693 if trans == kStarted
and n
in externalWorkModules:
694 externalWorkModules.remove(n)
695 streamExternalWorkRunningTimes[s].
append(
Point(time, -1))
697 nTotalModules = len(activeModules) + len(acquireModules) + len(externalWorkModules)
698 maxNumberOfConcurrentModulesOnAStream =
max(maxNumberOfConcurrentModulesOnAStream, nTotalModules)
699 elif trans == kFinished
or trans == kFinishedSourceDelayedRead
or trans == kFinishedAcquire
or trans == kFinishedSource :
701 if trans == kFinished:
702 if n
not in activeModules:
703 finishBeforeStart[s].
add(n)
706 if trans == kFinishedSourceDelayedRead:
707 countDelayedSource[s] -= 1
708 if countDelayedSource[s] < 0:
710 elif trans == kFinishedSource:
712 if countSource[s] < 0:
715 if trans == kFinishedAcquire:
717 countExternalWork[s][n] += 1
718 if displayExternalWork:
719 externalWorkModulesInJob =
True 720 if (
not checkOrder)
or countExternalWork[s][n] > 0:
721 externalWorkModules.add(n)
722 streamExternalWorkRunningTimes[s].
append(
Point(time,+1))
723 if checkOrder
and n
not in acquireModules:
724 finishAcquireBeforeStart[s].
add(n)
727 startTime = previousFinishTime[s]
728 previousFinishTime[s] = time
729 moduleNames = activeModules.copy()
730 moduleNames.update(acquireModules)
732 if trans == kFinishedAcquire:
733 acquireModules.remove(n)
734 elif trans == kFinishedSourceDelayedRead:
735 if countDelayedSource[s] == 0:
736 activeModules.remove(n)
737 elif trans == kFinishedSource:
738 if countSource[s] == 0:
739 activeModules.remove(n)
741 activeModules.remove(n)
743 if startTime
is not None:
749 elif (kSourceDelayedRead
in moduleNames)
or (kSourceFindEvent
in moduleNames):
752 for n
in moduleNames:
753 if n
in stalledModuleNames:
760 if shownStacks
and showStreams:
762 fig, ax = plt.subplots(nrows=nr, squeeze=
True)
764 if shownStacks
and showStreams:
765 [xH,yH] = fig.get_size_inches()
766 fig.set_size_inches(xH,yH*4/3)
767 ax = plt.subplot2grid((4,1),(0,0), rowspan=3)
768 axStack = plt.subplot2grid((4,1),(3,0))
769 if shownStacks
and not showStreams:
772 ax.set_xlabel(
"Time (sec)")
773 ax.set_ylabel(
"Stream ID")
774 ax.set_ylim(-0.5,numStreams-0.5)
775 ax.yaxis.set_ticks(
range(numStreams))
777 ax.set_xlim((xLower, xUpper))
779 height = 0.8/maxNumberOfConcurrentModulesOnAStream
780 allStackTimes={
'green': [],
'limegreen':[],
'red': [],
'blue': [],
'orange': [],
'darkviolet': []}
781 for iStream,lowestRow
in enumerate(streamLowestRow):
782 times=[(x.begin/1000000., x.delta/1000000.)
for x
in lowestRow]
783 colors=[x.color
for x
in lowestRow]
786 ax.broken_barh(times,(iStream-0.4,height),facecolors=colors,edgecolors=colors,linewidth=0)
789 for info
in lowestRow:
790 if not info.color ==
'darkviolet':
791 allStackTimes[info.color].
append((info.begin, info.delta))
794 if maxNumberOfConcurrentModulesOnAStream > 1
or externalWorkModulesInJob:
796 for i,perStreamRunningTimes
in enumerate(streamRunningTimes):
798 perStreamTimesWithExtendedWork = list(perStreamRunningTimes)
799 perStreamTimesWithExtendedWork.extend(streamExternalWorkRunningTimes[i])
802 allStackTimes, ax, i, height,
805 addToStackTimes=
False,
810 allStackTimes, ax, i, height,
813 addToStackTimes=
True,
818 allStackTimes, ax, i, height,
821 addToStackTimes=
True,
826 print(
"> ... Generating stack")
828 for color
in [
'green',
'limegreen',
'blue',
'red',
'orange',
'darkviolet']:
829 tmp = allStackTimes[color]
831 stack.update(color, tmp)
833 for stk
in reversed(stack.data):
839 for p1,p2
in zip(stk[1], stk[1][1:]):
841 xs.append((p1.x, p2.x-p1.x, height))
842 xs.sort(key = itemgetter(2))
845 for height, xpairs
in groupby(xs, itemgetter(2)):
846 finalxs = [(e[0]/1000000.,e[1]/1000000.)
for e
in xpairs]
848 axStack.broken_barh(finalxs, (0, height), facecolors=color, edgecolors=color, linewidth=0)
850 axStack.set_xlabel(
"Time (sec)");
851 axStack.set_ylabel(
"# modules");
852 axStack.set_xlim(ax.get_xlim())
853 axStack.tick_params(top=
'off')
855 fig.text(0.1, 0.95,
"modules running event", color =
"green", horizontalalignment =
'left')
856 fig.text(0.1, 0.92,
"modules running other", color =
"limegreen", horizontalalignment =
'left')
857 fig.text(0.5, 0.95,
"stalled module running", color =
"red", horizontalalignment =
'center')
858 fig.text(0.9, 0.95,
"read from input", color =
"orange", horizontalalignment =
'right')
859 fig.text(0.5, 0.92,
"multiple modules running", color =
"blue", horizontalalignment =
'center')
860 if displayExternalWork:
861 fig.text(0.9, 0.92,
"external work", color =
"darkviolet", horizontalalignment =
'right')
862 print(
"> ... Saving to file: '{}'".
format(pdfFile))
866 if __name__==
"__main__":
872 parser = argparse.ArgumentParser(description=
'Convert a text file created by cmsRun into a stream stall graph.',
873 formatter_class=argparse.RawDescriptionHelpFormatter,
875 parser.add_argument(
'filename',
876 type=argparse.FileType(
'r'), # open file 877 help='file to process')
878 parser.add_argument(
'-g',
'--graph',
880 metavar=
"'stall.pdf'",
883 help=
'''Create pdf file of stream stall graph. If -g is specified 884 by itself, the default file name is \'stall.pdf\'. Otherwise, the 885 argument to the -g option is the filename.''')
886 parser.add_argument(
'-s',
'--stack',
888 help=
'''Create stack plot, combining all stream-specific info. 889 Can be used only when -g is specified.''')
890 parser.add_argument(
'--no_streams', action=
'store_true',
891 help=
'''Do not show per stream plots. 892 Can be used only when -g and -s are specified.''')
893 parser.add_argument(
'-e',
'--external',
894 action=
'store_false',
895 help=
'''Suppress display of external work in graphs.''')
896 parser.add_argument(
'-o',
'--order',
898 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.''')
899 parser.add_argument(
'-t',
'--timings',
901 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.''')
902 parser.add_argument(
'-l',
'--lowerxaxis',
905 help=
'''Lower limit of x axis, default 0, not used if upper limit not set''')
906 parser.add_argument(
'-u',
'--upperxaxis',
908 help=
'''Upper limit of x axis, if not set then x axis limits are set automatically''')
909 args = parser.parse_args()
912 inputFile = args.filename
914 shownStacks = args.stack
915 showStreams =
not args.no_streams
916 displayExternalWork = args.external
917 checkOrder = args.order
918 doModuleTimings =
False 920 doModuleTimings =
True 924 if args.upperxaxis
is not None:
926 xUpper = args.upperxaxis
927 xLower = args.lowerxaxis
930 if pdfFile
is not None:
934 matplotlib.use(
"PDF")
935 import matplotlib.pyplot
as plt
936 if not re.match(
r'^[\w\.]+$', pdfFile):
937 print(
"Malformed file name '{}' supplied with the '-g' option.".
format(pdfFile))
938 print(
"Only characters 0-9, a-z, A-Z, '_', and '.' are allowed.")
942 extension = pdfFile.split(
'.')[-1]
943 supported_filetypes = plt.figure().canvas.get_supported_filetypes()
944 if not extension
in supported_filetypes:
945 print(
"A graph cannot be saved to a filename with extension '{}'.".
format(extension))
946 print(
"The allowed extensions are:")
947 for filetype
in supported_filetypes:
951 if pdfFile
is None and shownStacks:
952 print(
"The -s (--stack) option can be used only when the -g (--graph) option is specified.")
954 if pdfFile
and (
not shownStacks
and not showStreams):
955 print(
"When using -g, one must either specify -s OR do not specify --no_streams")
958 sys.stderr.write(
">reading file: '{}'\n".
format(inputFile.name))
962 sys.stderr.write(
">processing data\n")
967 sys.stderr.write(
">preparing ASCII art\n")
968 createAsciiImage(reader.processingSteps(), reader.numStreams, reader.maxNameSize)
970 sys.stderr.write(
">creating PDF\n")
971 createPDFImage(pdfFile, shownStacks, showStreams, reader.processingSteps(), reader.numStreams, stalledModules, displayExternalWork, checkOrder, setXAxis, xLower, xUpper)
974 sys.stderr.write(
">creating module-timings.json\n")
std::pair< unsigned int, unsigned int > unpack(cond::Time_t since)
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)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
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)