CMS 3D CMS Logo

Classes | Functions
edmStreamStallGrapher Namespace Reference

Classes

class  Point
 
class  Stack
 
class  StallMonitorParser
 
class  StreamInfoElement
 
class  TracerParser
 

Functions

def adjacentDiff (pairLists)
 
def chooseParser (inputFile)
 
def consolidateContiguousBlocks (numStreams, streamInfo)
 
def createAsciiImage (processingSteps, numStreams, maxNameSize)
 
def createPDFImage (pdfFile, shownStacks, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder)
 
def findStalledModules (processingSteps, numStreams)
 
def getTime (line)
 
def mergeContiguousBlocks (blocks)
 
def parseTracerOutput (f)
 
def plotPerStreamAboveFirstAndPrepareStack (points, allStackTimes, ax, stream, height, streamHeightCut, doPlot, addToStackTimes, color, threadOffset)
 
def printHelp ()
 
def printStalledModulesInOrder (stalledModules)
 
def processingStepsFromStallMonitorOutput (f, moduleNames)
 
def readLogFile (inputFile)
 
def reduceSortedPoints (ps)
 

Function Documentation

def edmStreamStallGrapher.adjacentDiff (   pairLists)

Definition at line 445 of file edmStreamStallGrapher.py.

Referenced by createPDFImage().

445 def adjacentDiff(*pairLists):
446  points = []
447  for pairList in pairLists:
448  points += [Point(x[0], 1) for x in pairList if x[1] != 0]
449  points += [Point(sum(x),-1) for x in pairList if x[1] != 0]
450  points.sort(key=attrgetter('x'))
451  return points
452 
def edmStreamStallGrapher.chooseParser (   inputFile)

Definition at line 278 of file edmStreamStallGrapher.py.

References cmsRelvalreport.exit, and edm.print().

Referenced by readLogFile().

278 def chooseParser(inputFile):
279 
280  firstLine = inputFile.readline().rstrip()
281  for i in range(3):
282  inputFile.readline()
283  # Often the Tracer log file starts with 4 lines not from the Tracer
284  fifthLine = inputFile.readline().rstrip()
285  inputFile.seek(0) # Rewind back to beginning
286  if (firstLine.find("# Transition") != -1) or (firstLine.find("# Step") != -1):
287  print("> ... Parsing StallMonitor output.")
288  return StallMonitorParser
289 
290  if firstLine.find("++") != -1 or fifthLine.find("++") != -1:
291  global kTracerInput
292  kTracerInput = True
293  print("> ... Parsing Tracer output.")
294  return TracerParser
295  else:
296  inputFile.close()
297  print("Unknown input format.")
298  exit(1)
299 
300 #----------------------------------------------
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
def edmStreamStallGrapher.consolidateContiguousBlocks (   numStreams,
  streamInfo 
)

Definition at line 483 of file edmStreamStallGrapher.py.

References mps_setup.append, and timeUnitHelper.unpack().

Referenced by createPDFImage().

483 def consolidateContiguousBlocks(numStreams, streamInfo):
484  oldStreamInfo = streamInfo
485  streamInfo = [[] for x in xrange(numStreams)]
486 
487  for s in xrange(numStreams):
488  if oldStreamInfo[s]:
489  lastStartTime,lastTimeLength,lastColor = oldStreamInfo[s][0].unpack()
490  for info in oldStreamInfo[s][1:]:
491  start,length,color = info.unpack()
492  if color == lastColor and lastStartTime+lastTimeLength == start:
493  lastTimeLength += length
494  else:
495  streamInfo[s].append(StreamInfoElement(lastStartTime,lastTimeLength,lastColor))
496  lastStartTime = start
497  lastTimeLength = length
498  lastColor = color
499  streamInfo[s].append(StreamInfoElement(lastStartTime,lastTimeLength,lastColor))
500 
501  return streamInfo
502 
503 #----------------------------------------------
504 # Consolidating contiguous blocks with the same color drastically
505 # reduces the size of the pdf file. Same functionality as the
506 # previous function, but with slightly different implementation.
def consolidateContiguousBlocks(numStreams, streamInfo)
def edmStreamStallGrapher.createAsciiImage (   processingSteps,
  numStreams,
  maxNameSize 
)

Definition at line 349 of file edmStreamStallGrapher.py.

References edm.print(), and str.

Referenced by createPDFImage().

349 def createAsciiImage(processingSteps, numStreams, maxNameSize):
350  streamTime = [0]*numStreams
351  streamState = [0]*numStreams
352  modulesActiveOnStreams = [{} for x in xrange(numStreams)]
353  for n,trans,s,time,isEvent in processingSteps:
354  waitTime = None
355  modulesActiveOnStream = modulesActiveOnStreams[s]
356  if trans == kPrefetchEnd:
357  modulesActiveOnStream[n] = time
358  continue
359  elif trans == kStartedAcquire or trans == kStarted:
360  if n in modulesActiveOnStream:
361  waitTime = time - modulesActiveOnStream[n]
362  modulesActiveOnStream.pop(n, None)
363  streamState[s] +=1
364  elif trans == kFinishedAcquire or trans == kFinished:
365  streamState[s] -=1
366  streamTime[s] = time
367  elif trans == kStartedSourceDelayedRead:
368  if streamState[s] == 0:
369  waitTime = time - streamTime[s]
370  elif trans == kStartedSource:
371  modulesActiveOnStream.clear()
372  elif trans == kFinishedSource or trans == kFinishedSourceDelayedRead:
373  streamTime[s] = time
374  states = "%-*s: " % (maxNameSize,n)
375  if trans == kStartedAcquire or trans == kStarted or trans == kStartedSourceDelayedRead or trans == kStartedSource:
376  states +="+ "
377  else:
378  states +="- "
379  for index, state in enumerate(streamState):
380  if n==kSourceFindEvent and index == s:
381  states +="* "
382  else:
383  states +=str(state)+" "
384  states += " -- " + str(time/1000.) + " " + str(s) + " "
385  if waitTime is not None:
386  states += " %.2f"% (waitTime/1000.)
387  if waitTime > kStallThreshold:
388  states += " STALLED"
389 
390  print(states)
391 
392 #----------------------------------------------
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
def createAsciiImage(processingSteps, numStreams, maxNameSize)
#define str(s)
def edmStreamStallGrapher.createPDFImage (   pdfFile,
  shownStacks,
  processingSteps,
  numStreams,
  stalledModuleInfo,
  displayExternalWork,
  checkOrder 
)

Definition at line 557 of file edmStreamStallGrapher.py.

References PVValHelper.add(), adjacentDiff(), mps_setup.append, consolidateContiguousBlocks(), createAsciiImage(), cmsRelvalreport.exit, findStalledModules(), list(), SiStripPI.max, mergeContiguousBlocks(), plotPerStreamAboveFirstAndPrepareStack(), edm.print(), printHelp(), printStalledModulesInOrder(), readLogFile(), reduceSortedPoints(), MatrixUtil.remove(), and ComparisonHelper.zip().

557 def createPDFImage(pdfFile, shownStacks, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder):
558 
559  stalledModuleNames = set([x for x in stalledModuleInfo.iterkeys()])
560  streamLowestRow = [[] for x in xrange(numStreams)]
561  modulesActiveOnStreams = [set() for x in xrange(numStreams)]
562  acquireActiveOnStreams = [set() for x in xrange(numStreams)]
563  externalWorkOnStreams = [set() for x in xrange(numStreams)]
564  previousFinishTime = [None for x in xrange(numStreams)]
565  streamRunningTimes = [[] for x in xrange(numStreams)]
566  streamExternalWorkRunningTimes = [[] for x in xrange(numStreams)]
567  maxNumberOfConcurrentModulesOnAStream = 1
568  externalWorkModulesInJob = False
569  previousTime = [0 for x in xrange(numStreams)]
570 
571  # The next five variables are only used to check for out of order transitions
572  finishBeforeStart = [set() for x in xrange(numStreams)]
573  finishAcquireBeforeStart = [set() for x in xrange(numStreams)]
574  countSource = [0 for x in xrange(numStreams)]
575  countDelayedSource = [0 for x in xrange(numStreams)]
576  countExternalWork = [defaultdict(int) for x in xrange(numStreams)]
577 
578  timeOffset = None
579  for n,trans,s,time,isEvent in processingSteps:
580  if timeOffset is None:
581  timeOffset = time
582  startTime = None
583  time -=timeOffset
584  # force the time to monotonically increase on each stream
585  if time < previousTime[s]:
586  time = previousTime[s]
587  previousTime[s] = time
588 
589  activeModules = modulesActiveOnStreams[s]
590  acquireModules = acquireActiveOnStreams[s]
591  externalWorkModules = externalWorkOnStreams[s]
592 
593  if trans == kStarted or trans == kStartedSourceDelayedRead or trans == kStartedAcquire or trans == kStartedSource :
594  if checkOrder:
595  # Note that the code which checks the order of transitions assumes that
596  # all the transitions exist in the input. It is checking only for order
597  # problems, usually a start before a finish. Problems are fixed and
598  # silently ignored. Nothing gets plotted for transitions that are
599  # in the wrong order.
600  if trans == kStarted:
601  countExternalWork[s][n] -= 1
602  if n in finishBeforeStart[s]:
603  finishBeforeStart[s].remove(n)
604  continue
605  elif trans == kStartedAcquire:
606  if n in finishAcquireBeforeStart[s]:
607  finishAcquireBeforeStart[s].remove(n)
608  continue
609 
610  if trans == kStartedSourceDelayedRead:
611  countDelayedSource[s] += 1
612  if countDelayedSource[s] < 1:
613  continue
614  elif trans == kStartedSource:
615  countSource[s] += 1
616  if countSource[s] < 1:
617  continue
618 
619  moduleNames = activeModules.copy()
620  moduleNames.update(acquireModules)
621  if trans == kStartedAcquire:
622  acquireModules.add(n)
623  else:
624  activeModules.add(n)
625  streamRunningTimes[s].append(Point(time,1))
626  if moduleNames or externalWorkModules:
627  startTime = previousFinishTime[s]
628  previousFinishTime[s] = time
629 
630  if trans == kStarted and n in externalWorkModules:
631  externalWorkModules.remove(n)
632  streamExternalWorkRunningTimes[s].append(Point(time, -1))
633  else:
634  nTotalModules = len(activeModules) + len(acquireModules) + len(externalWorkModules)
635  maxNumberOfConcurrentModulesOnAStream = max(maxNumberOfConcurrentModulesOnAStream, nTotalModules)
636  elif trans == kFinished or trans == kFinishedSourceDelayedRead or trans == kFinishedAcquire or trans == kFinishedSource :
637  if checkOrder:
638  if trans == kFinished:
639  if n not in activeModules:
640  finishBeforeStart[s].add(n)
641  continue
642 
643  if trans == kFinishedSourceDelayedRead:
644  countDelayedSource[s] -= 1
645  if countDelayedSource[s] < 0:
646  continue
647  elif trans == kFinishedSource:
648  countSource[s] -= 1
649  if countSource[s] < 0:
650  continue
651 
652  if trans == kFinishedAcquire:
653  if checkOrder:
654  countExternalWork[s][n] += 1
655  if displayExternalWork:
656  externalWorkModulesInJob = True
657  if (not checkOrder) or countExternalWork[s][n] > 0:
658  externalWorkModules.add(n)
659  streamExternalWorkRunningTimes[s].append(Point(time,+1))
660  if checkOrder and n not in acquireModules:
661  finishAcquireBeforeStart[s].add(n)
662  continue
663  streamRunningTimes[s].append(Point(time,-1))
664  startTime = previousFinishTime[s]
665  previousFinishTime[s] = time
666  moduleNames = activeModules.copy()
667  moduleNames.update(acquireModules)
668 
669  if trans == kFinishedAcquire:
670  acquireModules.remove(n)
671  elif trans == kFinishedSourceDelayedRead:
672  if countDelayedSource[s] == 0:
673  activeModules.remove(n)
674  elif trans == kFinishedSource:
675  if countSource[s] == 0:
676  activeModules.remove(n)
677  else:
678  activeModules.remove(n)
679 
680  if startTime is not None:
681  c="green"
682  if not isEvent:
683  c="limegreen"
684  if not moduleNames:
685  c = "darkviolet"
686  elif (kSourceDelayedRead in moduleNames) or (kSourceFindEvent in moduleNames):
687  c = "orange"
688  else:
689  for n in moduleNames:
690  if n in stalledModuleNames:
691  c="red"
692  break
693  streamLowestRow[s].append(StreamInfoElement(startTime, time-startTime, c))
694  streamLowestRow = consolidateContiguousBlocks(numStreams, streamLowestRow)
695 
696  nr = 1
697  if shownStacks:
698  nr += 1
699  fig, ax = plt.subplots(nrows=nr, squeeze=True)
700  axStack = None
701  if shownStacks:
702  [xH,yH] = fig.get_size_inches()
703  fig.set_size_inches(xH,yH*4/3)
704  ax = plt.subplot2grid((4,1),(0,0), rowspan=3)
705  axStack = plt.subplot2grid((4,1),(3,0))
706 
707  ax.set_xlabel("Time (sec)")
708  ax.set_ylabel("Stream ID")
709  ax.set_ylim(-0.5,numStreams-0.5)
710  ax.yaxis.set_ticks(xrange(numStreams))
711 
712  height = 0.8/maxNumberOfConcurrentModulesOnAStream
713  allStackTimes={'green': [],'limegreen':[], 'red': [], 'blue': [], 'orange': [], 'darkviolet': []}
714  for iStream,lowestRow in enumerate(streamLowestRow):
715  times=[(x.begin/1000., x.delta/1000.) for x in lowestRow] # Scale from msec to sec.
716  colors=[x.color for x in lowestRow]
717  # for each stream, plot the lowest row
718  ax.broken_barh(times,(iStream-0.4,height),facecolors=colors,edgecolors=colors,linewidth=0)
719  # record them also for inclusion in the stack plot
720  # the darkviolet ones get counted later so do not count them here
721  for info in lowestRow:
722  if not info.color == 'darkviolet':
723  allStackTimes[info.color].append((info.begin, info.delta))
724 
725  # Now superimpose the number of concurrently running modules on to the graph.
726  if maxNumberOfConcurrentModulesOnAStream > 1 or externalWorkModulesInJob:
727 
728  for i,perStreamRunningTimes in enumerate(streamRunningTimes):
729 
730  perStreamTimesWithExtendedWork = list(perStreamRunningTimes)
731  perStreamTimesWithExtendedWork.extend(streamExternalWorkRunningTimes[i])
732 
733  plotPerStreamAboveFirstAndPrepareStack(perStreamTimesWithExtendedWork,
734  allStackTimes, ax, i, height,
735  streamHeightCut=2,
736  doPlot=True,
737  addToStackTimes=False,
738  color='darkviolet',
739  threadOffset=1)
740 
741  plotPerStreamAboveFirstAndPrepareStack(perStreamRunningTimes,
742  allStackTimes, ax, i, height,
743  streamHeightCut=2,
744  doPlot=True,
745  addToStackTimes=True,
746  color='blue',
747  threadOffset=1)
748 
749  plotPerStreamAboveFirstAndPrepareStack(streamExternalWorkRunningTimes[i],
750  allStackTimes, ax, i, height,
751  streamHeightCut=1,
752  doPlot=False,
753  addToStackTimes=True,
754  color='darkviolet',
755  threadOffset=0)
756 
757  if shownStacks:
758  print("> ... Generating stack")
759  stack = Stack()
760  for color in ['green','limegreen','blue','red','orange','darkviolet']:
761  tmp = allStackTimes[color]
762  tmp = reduceSortedPoints(adjacentDiff(tmp))
763  stack.update(color, tmp)
764 
765  for stk in reversed(stack.data):
766  color = stk[0]
767 
768  # Now arrange list in a manner that it can be grouped by the height of the block
769  height = 0
770  xs = []
771  for p1,p2 in zip(stk[1], stk[1][1:]):
772  height += p1.y
773  xs.append((p1.x, p2.x-p1.x, height))
774  xs.sort(key = itemgetter(2))
775  xs = mergeContiguousBlocks(xs)
776 
777  for height, xpairs in groupby(xs, itemgetter(2)):
778  finalxs = [(e[0]/1000.,e[1]/1000.) for e in xpairs]
779  # plot the stacked plot, one color and one height on each call to broken_barh
780  axStack.broken_barh(finalxs, (0, height), facecolors=color, edgecolors=color, linewidth=0)
781 
782  axStack.set_xlabel("Time (sec)");
783  axStack.set_ylabel("# modules");
784  axStack.set_xlim(ax.get_xlim())
785  axStack.tick_params(top='off')
786 
787  fig.text(0.1, 0.95, "modules running event", color = "green", horizontalalignment = 'left')
788  fig.text(0.1, 0.92, "modules running other", color = "limegreen", horizontalalignment = 'left')
789  fig.text(0.5, 0.95, "stalled module running", color = "red", horizontalalignment = 'center')
790  fig.text(0.9, 0.95, "read from input", color = "orange", horizontalalignment = 'right')
791  fig.text(0.5, 0.92, "multiple modules running", color = "blue", horizontalalignment = 'center')
792  if displayExternalWork:
793  fig.text(0.9, 0.92, "external work", color = "darkviolet", horizontalalignment = 'right')
794  print("> ... Saving to file: '{}'".format(pdfFile))
795  plt.savefig(pdfFile)
796 
797 #=======================================
def createPDFImage(pdfFile, shownStacks, processingSteps, numStreams, stalledModuleInfo, displayExternalWork, checkOrder)
def consolidateContiguousBlocks(numStreams, streamInfo)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
def remove(d, key, TELL=False)
Definition: MatrixUtil.py:212
def plotPerStreamAboveFirstAndPrepareStack(points, allStackTimes, ax, stream, height, streamHeightCut, doPlot, addToStackTimes, color, threadOffset)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def edmStreamStallGrapher.findStalledModules (   processingSteps,
  numStreams 
)

Definition at line 316 of file edmStreamStallGrapher.py.

Referenced by createPDFImage().

316 def findStalledModules(processingSteps, numStreams):
317  streamTime = [0]*numStreams
318  streamState = [0]*numStreams
319  stalledModules = {}
320  modulesActiveOnStream = [{} for x in xrange(numStreams)]
321  for n,trans,s,time,isEvent in processingSteps:
322 
323  waitTime = None
324  modulesOnStream = modulesActiveOnStream[s]
325  if trans == kPrefetchEnd:
326  modulesOnStream[n] = time
327  elif trans == kStarted or trans == kStartedAcquire:
328  if n in modulesOnStream:
329  waitTime = time - modulesOnStream[n]
330  modulesOnStream.pop(n, None)
331  streamState[s] +=1
332  elif trans == kFinished or trans == kFinishedAcquire:
333  streamState[s] -=1
334  streamTime[s] = time
335  elif trans == kStartedSourceDelayedRead:
336  if streamState[s] == 0:
337  waitTime = time - streamTime[s]
338  elif trans == kStartedSource:
339  modulesOnStream.clear()
340  elif trans == kFinishedSource or trans == kFinishedSourceDelayedRead:
341  streamTime[s] = time
342  if waitTime is not None:
343  if waitTime > kStallThreshold:
344  t = stalledModules.setdefault(n,[])
345  t.append(waitTime)
346  return stalledModules
347 
348 #----------------------------------------------
def findStalledModules(processingSteps, numStreams)
def edmStreamStallGrapher.getTime (   line)

Definition at line 179 of file edmStreamStallGrapher.py.

References objects.autophobj.float, and createfilelist.int.

Referenced by EcalPerEvtLaserAnalyzer.endJob(), EcalLaserAnalyzer2.endJob(), EcalLaserAnalyzer.endJob(), parseTracerOutput(), and pos::PixelFEDTestDAC.writeXMLHeader().

179 def getTime(line):
180  time = line.split(" ")[1]
181  time = time.split(":")
182  time = int(time[0])*60*60+int(time[1])*60+float(time[2])
183  time = int(1000*time) # convert to milliseconds
184  return time
185 
186 #----------------------------------------------
187 # The next function parses the Tracer output.
188 # Here are some differences to consider if you use Tracer output
189 # instead of the StallMonitor output.
190 # - The time in the text of the Tracer output is not as precise
191 # as the StallMonitor (.01 s vs .001 s)
192 # - The MessageLogger bases the time on when the message printed
193 # and not when it was initially queued up to print which smears
194 # the accuracy of the times.
195 # - Both of the previous things can produce some strange effects
196 # in the output plots.
197 # - The file size of the Tracer text file is much larger.
198 # - The CPU work needed to parse the Tracer files is larger.
199 # - The Tracer log file is expected to have "++" in the first
200 # or fifth line. If there are extraneous lines at the beginning
201 # you have to remove them.
202 # - The ascii printout out will have one extraneous line
203 # near the end for the SourceFindEvent start.
204 # - The only advantage I can see is that you have only
205 # one output file to handle instead of two, the regular
206 # log file and the StallMonitor output.
207 # We might should just delete the Tracer option because it is
208 # clearly inferior ...
def edmStreamStallGrapher.mergeContiguousBlocks (   blocks)

Definition at line 507 of file edmStreamStallGrapher.py.

Referenced by createPDFImage(), and plotPerStreamAboveFirstAndPrepareStack().

508  oldBlocks = blocks
509 
510  blocks = []
511  if not oldBlocks:
512  return blocks
513 
514  lastStartTime,lastTimeLength,lastHeight = oldBlocks[0]
515  for start,length,height in oldBlocks[1:]:
516  if height == lastHeight and lastStartTime+lastTimeLength == start:
517  lastTimeLength += length
518  else:
519  blocks.append((lastStartTime,lastTimeLength,lastHeight))
520  lastStartTime = start
521  lastTimeLength = length
522  lastHeight = height
523  blocks.append((lastStartTime,lastTimeLength,lastHeight))
524 
525  return blocks
526 
527 #----------------------------------------------
def edmStreamStallGrapher.parseTracerOutput (   f)

Definition at line 209 of file edmStreamStallGrapher.py.

References getTime(), createfilelist.int, and SiStripPI.max.

210  processingSteps = []
211  numStreams = 0
212  maxNameSize = 0
213  startTime = 0
214  streamsThatSawFirstEvent = set()
215  for l in f:
216  trans = None
217  # We estimate the start and stop of the source
218  # by the end of the previous event and start of
219  # the event. This is historical, probably because
220  # the Tracer output for the begin and end of the
221  # source event does not include the stream number.
222  if l.find("processing event :") != -1:
223  name = kSourceFindEvent
224  trans = kStartedSource
225  # the end of the source is estimated using the start of the event
226  if l.find("starting:") != -1:
227  trans = kFinishedSource
228  elif l.find("processing event for module") != -1:
229  trans = kStarted
230  if l.find("finished:") != -1:
231  if l.find("prefetching") != -1:
232  trans = kPrefetchEnd
233  else:
234  trans = kFinished
235  else:
236  if l.find("prefetching") != -1:
237  #skip this since we don't care about prefetch starts
238  continue
239  name = l.split("'")[1]
240  elif l.find("processing event acquire for module:") != -1:
241  trans = kStartedAcquire
242  if l.find("finished:") != -1:
243  trans = kFinishedAcquire
244  name = l.split("'")[1]
245  elif l.find("event delayed read from source") != -1:
246  trans = kStartedSourceDelayedRead
247  if l.find("finished:") != -1:
248  trans = kFinishedSourceDelayedRead
249  name = kSourceDelayedRead
250  if trans is not None:
251  time = getTime(l)
252  if startTime == 0:
253  startTime = time
254  time = time - startTime
255  streamIndex = l.find("stream = ")
256  stream = int(l[streamIndex+9:l.find(" ",streamIndex+10)])
257  maxNameSize = max(maxNameSize, len(name))
258 
259  if trans == kFinishedSource and not stream in streamsThatSawFirstEvent:
260  # This is wrong but there is no way to estimate the time better
261  # because there is no previous event for the first event.
262  processingSteps.append((name,kStartedSource,stream,time,True))
263  streamsThatSawFirstEvent.add(stream)
264 
265  processingSteps.append((name,trans,stream,time, True))
266  numStreams = max(numStreams, stream+1)
267 
268  f.close()
269  return (processingSteps,numStreams,maxNameSize)
270 
def edmStreamStallGrapher.plotPerStreamAboveFirstAndPrepareStack (   points,
  allStackTimes,
  ax,
  stream,
  height,
  streamHeightCut,
  doPlot,
  addToStackTimes,
  color,
  threadOffset 
)

Definition at line 528 of file edmStreamStallGrapher.py.

References mergeContiguousBlocks(), reduceSortedPoints(), and ComparisonHelper.zip().

Referenced by createPDFImage().

528 def plotPerStreamAboveFirstAndPrepareStack(points, allStackTimes, ax, stream, height, streamHeightCut, doPlot, addToStackTimes, color, threadOffset):
529  points = sorted(points, key=attrgetter('x'))
530  points = reduceSortedPoints(points)
531  streamHeight = 0
532  preparedTimes = []
533  for t1,t2 in zip(points, points[1:]):
534  streamHeight += t1.y
535  # We make a cut here when plotting because the first row for
536  # each stream was already plotted previously and we do not
537  # need to plot it again. And also we want to count things
538  # properly in allStackTimes. We want to avoid double counting
539  # or missing running modules and this is complicated because
540  # we counted the modules in the first row already.
541  if streamHeight < streamHeightCut:
542  continue
543  preparedTimes.append((t1.x,t2.x-t1.x, streamHeight))
544  preparedTimes.sort(key=itemgetter(2))
545  preparedTimes = mergeContiguousBlocks(preparedTimes)
546 
547  for nthreads, ts in groupby(preparedTimes, itemgetter(2)):
548  theTS = [(t[0],t[1]) for t in ts]
549  if doPlot:
550  theTimes = [(t[0]/1000.,t[1]/1000.) for t in theTS]
551  yspan = (stream-0.4+height,height*(nthreads-1))
552  ax.broken_barh(theTimes, yspan, facecolors=color, edgecolors=color, linewidth=0)
553  if addToStackTimes:
554  allStackTimes[color].extend(theTS*(nthreads-threadOffset))
555 
556 #----------------------------------------------
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def plotPerStreamAboveFirstAndPrepareStack(points, allStackTimes, ax, stream, height, streamHeightCut, doPlot, addToStackTimes, color, threadOffset)
def edmStreamStallGrapher.printHelp ( )

Definition at line 10 of file edmStreamStallGrapher.py.

Referenced by createPDFImage().

10 def printHelp():
11  s = '''
12 To Use: Add the StallMonitor Service to the cmsRun job you want to check for
13  stream stalls. Use something like this in the configuration:
14 
15  process.add_(cms.Service("StallMonitor", fileName = cms.untracked.string("stallMonitor.log")))
16 
17  After running the job, execute this script and pass the name of the
18  StallMonitor log file to the script.
19 
20  By default, the script will then print an 'ASCII art' stall graph
21  which consists of a line of text for each time a module or the
22  source stops or starts. Each line contains the name of the module
23  which either started or stopped running, and the number of modules
24  running on each stream at that moment in time. After that will be
25  the time and stream number. Then if a module just started, you
26  will also see the amount of time the module spent between finishing
27  its prefetching and starting. The state of a module is represented
28  by a symbol:
29 
30  plus ("+") the stream has just finished waiting and is starting a module
31  minus ("-") the stream just finished running a module
32 
33  If a module had to wait more than 0.1 seconds, the end of the line
34  will have "STALLED". Startup actions, e.g. reading conditions,
35  may affect results for the first few events.
36 
37  Using the command line arguments described above you can make the
38  program create a PDF file with actual graphs instead of the 'ASCII art'
39  output.
40 
41  Once the graph is completed, the program outputs the list of modules
42  which had the greatest total stall times. The list is sorted by
43  total stall time and written in descending order. In addition, the
44  list of all stall times for the module is given.
45 
46  There is an inferior alternative (an old obsolete way).
47  Instead of using the StallMonitor Service, you can use the
48  Tracer Service. Make sure to use the 'printTimestamps' option
49  cms.Service("Tracer", printTimestamps = cms.untracked.bool(True))
50  There are problems associated with this and it is not recommended.'''
51  return s
52 
53 kStallThreshold=100 #in milliseconds
54 kTracerInput=False
55 
56 #Stream states
57 kStarted=0
58 kFinished=1
59 kPrefetchEnd=2
60 kStartedAcquire=3
61 kFinishedAcquire=4
62 kStartedSource=5
63 kFinishedSource=6
64 kStartedSourceDelayedRead=7
65 kFinishedSourceDelayedRead=8
66 
67 #Special names
def edmStreamStallGrapher.printStalledModulesInOrder (   stalledModules)

Definition at line 393 of file edmStreamStallGrapher.py.

References join(), SiStripPI.max, and edm.print().

Referenced by createPDFImage().

393 def printStalledModulesInOrder(stalledModules):
394  priorities = []
395  maxNameSize = 0
396  for name,t in six.iteritems(stalledModules):
397  maxNameSize = max(maxNameSize, len(name))
398  t.sort(reverse=True)
399  priorities.append((name,sum(t),t))
400 
401  def sumSort(i,j):
402  return cmp(i[1],j[1])
403  priorities.sort(cmp=sumSort, reverse=True)
404 
405  nameColumn = "Stalled Module"
406  maxNameSize = max(maxNameSize, len(nameColumn))
407 
408  stallColumn = "Tot Stall Time"
409  stallColumnLength = len(stallColumn)
410 
411  print("%-*s" % (maxNameSize, nameColumn), "%-*s"%(stallColumnLength,stallColumn), " Stall Times")
412  for n,s,t in priorities:
413  paddedName = "%-*s:" % (maxNameSize,n)
414  print(paddedName, "%-*.2f"%(stallColumnLength,s/1000.), ", ".join([ "%.2f"%(x/1000.) for x in t]))
415 
416 #--------------------------------------------------------
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
def printStalledModulesInOrder(stalledModules)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def edmStreamStallGrapher.processingStepsFromStallMonitorOutput (   f,
  moduleNames 
)

Definition at line 72 of file edmStreamStallGrapher.py.

References createfilelist.int.

Referenced by edmStreamStallGrapher.StallMonitorParser.processingSteps().

73  for rawl in f:
74  l = rawl.strip()
75  if not l or l[0] == '#':
76  continue
77  (step,payload) = tuple(l.split(None,1))
78  payload=payload.split()
79 
80  # Ignore these
81  if step == 'E' or step == 'e':
82  continue
83 
84  # Payload format is:
85  # <stream id> <..other fields..> <time since begin job>
86  stream = int(payload[0])
87  time = int(payload[-1])
88  trans = None
89  isEvent = True
90 
91  name = None
92  # 'S' = begin of event creation in source
93  # 's' = end of event creation in source
94  if step == 'S' or step == 's':
95  name = kSourceFindEvent
96  trans = kStartedSource
97  # The start of an event is the end of the framework part
98  if step == 's':
99  trans = kFinishedSource
100  else:
101  # moduleID is the second payload argument for all steps below
102  moduleID = payload[1]
103 
104  # 'p' = end of module prefetching
105  # 'M' = begin of module processing
106  # 'm' = end of module processing
107  if step == 'p' or step == 'M' or step == 'm':
108  trans = kStarted
109  if step == 'p':
110  trans = kPrefetchEnd
111  elif step == 'm':
112  trans = kFinished
113  if step == 'm' or step == 'M':
114  isEvent = (int(payload[2]) == 0)
115  name = moduleNames[moduleID]
116 
117  # 'A' = begin of module acquire function
118  # 'a' = end of module acquire function
119  elif step == 'A' or step == 'a':
120  trans = kStartedAcquire
121  if step == 'a':
122  trans = kFinishedAcquire
123  name = moduleNames[moduleID]
124 
125  # Delayed read from source
126  # 'R' = begin of delayed read from source
127  # 'r' = end of delayed read from source
128  elif step == 'R' or step == 'r':
129  trans = kStartedSourceDelayedRead
130  if step == 'r':
131  trans = kFinishedSourceDelayedRead
132  name = kSourceDelayedRead
133 
134  if trans is not None:
135  yield (name,trans,stream,time, isEvent)
136 
137  return
138 
def processingStepsFromStallMonitorOutput(f, moduleNames)
def edmStreamStallGrapher.readLogFile (   inputFile)

Definition at line 301 of file edmStreamStallGrapher.py.

References chooseParser().

Referenced by createPDFImage().

301 def readLogFile(inputFile):
302  parseInput = chooseParser(inputFile)
303  return parseInput(inputFile)
304 
305 #----------------------------------------------
306 #
307 # modules: The time between prefetch finished and 'start processing' is
308 # the time it took to acquire any resources which is by definition the
309 # stall time.
310 #
311 # source: The source just records how long it spent doing work,
312 # not how long it was stalled. We can get a lower bound on the stall
313 # time for delayed reads by measuring the time the stream was doing
314 # no work up till the start of the source delayed read.
315 #
def edmStreamStallGrapher.reduceSortedPoints (   ps)

Definition at line 429 of file edmStreamStallGrapher.py.

Referenced by createPDFImage(), plotPerStreamAboveFirstAndPrepareStack(), and edmStreamStallGrapher.Stack.update().

430  if len(ps) < 2:
431  return ps
432  reducedPoints = []
433  tmp = Point(ps[0].x, ps[0].y)
434  for p in ps[1:]:
435  if tmp.x == p.x:
436  tmp.y += p.y
437  else:
438  reducedPoints.append(tmp)
439  tmp = Point(p.x, p.y)
440  reducedPoints.append(tmp)
441  reducedPoints = [p for p in reducedPoints if p.y != 0]
442  return reducedPoints
443 
444 # -------------------------------------------