CMS 3D CMS Logo

dqmMemoryStats.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 import sys
4 
5 from DQMServices.FileIO.DQM import DQMReader
6 from collections import namedtuple
7 
8 HistogramEntry = namedtuple('HistogramEntry', ['type', 'bin_size', 'bin_count', 'extra', 'total_bytes'])
9 
11  BIN_SIZE = {
12  'TH1S': 2, 'TH2S': 2,
13  'TH1F': 4, 'TH2F': 4,
14  'TH1D': 8, 'TH2D': 8,
15  'TH3F': 4,
16  'TProfile': 8, 'TProfile2D': 8,
17  }
18 
19  def __init__(self):
20  self._all = {}
21 
22  def analyze(self, fn, obj):
23  name = fn.split("/")[-1]
24 
25  if hasattr(obj, 'ClassName'):
26  # this is a root type
27  t = str(obj.ClassName())
28  bin_size = self.BIN_SIZE.get(t, None)
29  if bin_size is None:
30  sys.stderr.write("warning: unknown root type: %s\n" % t)
31  sys.stderr.flush()
32  bin_size = 8
33 
34  bin_count = obj.GetNcells()
35  extra = len(fn)
36  total_bytes = bin_count * bin_size + extra
37 
38  self._all[fn] = HistogramEntry(t, bin_size, bin_count, extra, total_bytes)
39  else:
40  t = str(type(obj))
41  #bin_count, bin_size, extra = 0, 0, len(str(obj)) + len(fn)
42  # assume constant size for strings
43  bin_count, bin_size, extra = 0, 0, 10 + len(fn)
44  total_bytes = bin_count * bin_size + extra
45 
46  self._all[fn] = HistogramEntry(t, bin_size, bin_count, extra, total_bytes)
47 
48  def group(self, level):
49  group_stats = {}
50 
51  for k, v in self._all.items():
52  group_key = "/".join(k.split("/")[:level])
53 
54  current = group_stats.get(group_key, 0)
55  group_stats[group_key] = current + v.total_bytes
56 
57  return group_stats
58 
59  def difference(self, ref):
60  results = HistogramAnalyzer()
61  results._all = dict(self._all)
62 
63  zero = HistogramEntry("null", 0, 0, 0, 0)
64  def cmp(a, b):
65  return HistogramEntry(b.type, b.bin_size,
66  a.bin_count - b.bin_count,
67  a.extra - b.extra,
68  a.total_bytes - b.total_bytes )
69 
70  for k, refv in ref._all.items():
71  results._all[k] = cmp(self._all.get(k, zero), refv)
72 
73  return results
74 
75 
76 def kibisize(num,args):
77  pStr="%."+str(args.precision)+"f %s"
78  for prefix in ['KiB','MiB','GiB']:
79  num /= 1024.0
80 
81  if num < 1024.0 or args.units == prefix:
82  return pStr % (num, prefix)
83  return pStr % (num, prefix)
84 
85 def displayDirectoryStatistics(stats, args):
86  group_stats = stats.group(args.depth)
87 
88  cutoff, display = args.cutoff * 1024, args.display
89 
90  as_list = [(v, k, ) for (k, v) in group_stats.items()]
91  as_list.sort(reverse=True, key=lambda (v, k): abs(v))
92 
93  if cutoff is not None:
94  as_list = filter(lambda (v, k): abs(v) > cutoff, as_list)
95 
96  if display is not None:
97  as_list = as_list[:display]
98 
99  if args.human:
100  print "*" * 80
101  print (" DQM level %d folder breakdown " % args.depth).center(80, "*")
102  if cutoff:
103  print ("* Size cutoff: %s" % kibisize(cutoff,args)).ljust(79) + "*"
104  if display:
105  print ("* Showing top %d entries." % display).ljust(79) + "*"
106  print "*" * 80
107 
108  for v, k in as_list:
109  if args.human:
110  print kibisize(v,args).ljust(16, " "), k
111  else:
112  print v, k
113 
114 if __name__ == '__main__':
115  import argparse
116 
117  parser = argparse.ArgumentParser()
118  parser.add_argument("-i", "--input", help = "Input DQM ROOT file")
119  parser.add_argument("-r", "--ref", help = "Reference DQM ROOT file (to diff)")
120  parser.add_argument("--summary", help = "Dump summary", action = "store_true")
121  parser.add_argument("-x", "--human", help = "Human readable output.", action = "store_true")
122  parser.add_argument("-n", "--display", help = "Max entries to display in --summary.", type = int, default = None)
123  parser.add_argument("-c", "--cutoff", help = "Max cutoff to display in --summary.", type = float, default = 512, metavar="KiB")
124  parser.add_argument("-d", "--depth", help = "Folder depth in --summary.", type = int, default = 2)
125  parser.add_argument("-u", "--units", help = "Memory units to use (KiB,MiB,GiB) if fixed output desired", type = str, default = "None")
126  parser.add_argument("-p", "--precision", help = "Places after decimal to display.", type = int, default = 2)
127 
128  args = parser.parse_args()
129 
130  stats = HistogramAnalyzer()
131  reader = DQMReader(args.input)
132  for (fn, v) in reader.read_objects():
133  stats.analyze(fn, v)
134  reader.close()
135 
136  if args.ref:
137  reader = DQMReader(args.ref)
138  ref_stats = HistogramAnalyzer()
139  for (fn, v) in reader.read_objects():
140  ref_stats.analyze(fn, v)
141  reader.close()
142 
143  stats = stats.difference(ref_stats)
144 
145  if args.summary:
146  displayDirectoryStatistics(stats, args)
147 
148  total = stats.group(0)
149  if args.human:
150  print "Total bytes: %s" % kibisize(total[""],args)
151  else:
152  print total[""]
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def kibisize(num, args)
def displayDirectoryStatistics(stats, args)