CMS 3D CMS Logo

callgraph.py
Go to the documentation of this file.
1 #! /usr/bin/env python3
2 from __future__ import print_function
3 import networkx as nx
4 import re
5 import json
6 from yaml import load, dump, FullLoader
7 try:
8  from yaml import CLoader as Loader, CDumper as Dumper
9 except ImportError:
10  from yaml import Loader, Dumper
11 
12 topfunc = r"::(accumulate|acquire|startingNewLoop|duringLoop|endOfLoop|beginOfJob|endOfJob|produce|analyze|filter|beginLuminosityBlock|beginRun|beginStream|streamBeginRun|streamBeginLuminosityBlock|streamEndRun|streamEndLuminosityBlock|globalBeginRun|globalEndRun|globalBeginLuminosityBlock|globalEndLuminosityBlock|endRun|endLuminosityBlock)\("
13 topfuncre = re.compile(topfunc)
14 
15 baseclass = r"\b(edm::)?(one::|stream::|global::)?((DQM)?(Global|One)?ED(Producer|Filter|Analyzer|(IterateNTimes|NavigateEvents)?Looper)(Base)?|impl::(ExternalWork|Accumulator|RunWatcher|RunCacheHolder))\b"
16 baseclassre = re.compile(baseclass)
17 assert(baseclassre.match('edm::global::EDFilter::filter() virtual'))
18 assert(topfuncre.search('edm::global::EDFilterBase::filter(&) const virtual'))
19 
20 farg = re.compile(r"\(.*?\)")
21 tmpl = re.compile(r'<.*?>')
22 toplevelfuncs = set()
23 
24 epfuncre = re.compile(r"edm::eventsetup::EventSetupRecord::get<(class|struct) edm::ES(Transient)?Handle<(class|struct) .*>>\((const char \*, |const std::string &, )(class|struct) edm::ES(Transient)?Handle<(class|struct).*> &\) const")
25 f= 'edm::eventsetup::EventSetupRecord::get<class edm::ESHandle<class CaloTopology>>(const std::string &, class edm::ESHandle<class CaloTopology> &) const'
26 assert(epfuncre.search(f))
27 
28 skipfunc = re.compile(r"TGraph::IsA\(.*\)")
29 epfuncs = set()
30 
31 function='(anonymous namespace in /src/RecoTracker/TkHitPairs/plugins/HitPairEDProducer.cc)::Impl<(anonymous namespace)::ImplSeedingHitSets, (anonymous namespace)::DoNothing, (anonymous namespace)::RegionsLayersSeparate>::produce(const _Bool, edm::Event &, const edm::EventSetup &);'
32 function2='HitPairEDProducer::produce(edm::Event &, const edm::EventSetup &);'
33 value='HitPairEDProducer'
34 valuere=r'\b%s\b' % value
35 vre=re.compile(valuere)
36 m=vre.search(function)
37 assert(m)
38 m2=vre.search(function2)
39 assert(m2)
40 
41 modules = list()
42 with open('modules_in_ib.txt', 'r') as m:
43  for line in m:
44  modules.append(line.strip())
45 mods='|'.join(modules)
46 mods_regex=r'\b(' + mods+ r'QQQQQQQQ)\b'
47 comp_mods_regex=re.compile(mods_regex)
48 n=comp_mods_regex.search(function)
49 assert(n)
50 n2=comp_mods_regex.search(function2)
51 assert(n2)
52 
53 module2package = dict()
54 with open('module_to_package.yaml') as m:
55  module2package=load(m, Loader=FullLoader)
56 
57 with open('packages.json', 'r') as j:
58  p = json.load(j)
59 
60 for k,v in p.items():
61  module=k.split('|')[0]
62  dirs=v.split('|')
63  package=dirs[0]+'/'+dirs[1]
64  module2package.setdefault(package, []).append(module)
65 
66 for k in module2package.keys():
67  module2package[k]=sorted(set(module2package[k]))
68 
69 G = nx.DiGraph()
70 with open('function-calls-db.txt') as f:
71  for line in f:
72  fields = line.split("'")
73  if len(fields) < 3:
74  continue
75  if fields[2] == ' calls function ':
76  G.add_edge(fields[1], fields[3], kind=fields[2])
77  if epfuncre.search(fields[3]):
78  epfuncs.add(fields[3])
79  if fields[2] == ' overrides function ':
80  if baseclassre.match(fields[3]):
81  G.add_edge(fields[1], fields[3], kind=' overrides function ')
82  if topfuncre.search(fields[1]) and comp_mods_regex.search(fields[1]):
83  toplevelfuncs.add(fields[1])
84  else:
85  G.add_edge(fields[3], fields[1], kind=' overriden function calls function ')
86  if epfuncre.search(fields[3]):
87  epfuncs.add(fields[3])
88 
89 callstacks = set()
90 for tfunc in toplevelfuncs:
91  for epfunc in epfuncs:
92  if G.has_node(tfunc) and G.has_node(epfunc) and nx.has_path(G, tfunc, epfunc):
93  for path in nx.all_shortest_paths(G, tfunc, epfunc):
94  cs = str("")
95  previous = str("")
96  for p in path:
97  if epfuncre.match(p):
98  break
99  #stripped=re.sub(farg, "()", p)
100  stripped=p
101  if previous != stripped:
102  cs += stripped + '; '
103  previous = stripped
104  if cs not in callstacks:
105  callstacks.add(cs)
106 
107 report = dict()
108 for key in sorted(set(module2package.keys())):
109  for value in sorted(set(module2package[key])):
110  if comp_mods_regex.match(value):
111  regex_str = r'\b%s\b'%value
112  vre=re.compile(regex_str)
113  for callstack in sorted(callstacks):
114  if vre.search(callstack):
115  report.setdefault(str(key), {}).setdefault(str(value), []).append(str(callstack))
116 
117 r = open('eventsetuprecord-get.yaml', 'w')
118 dump(report, r, width=float("inf"))
submitPVValidationJobs.dump
dump
Definition: submitPVValidationJobs.py:55
dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
cms::cuda::assert
assert(be >=bs)
str
#define str(s)
Definition: TestProcessor.cc:53
svgfig.load
def load(fileName)
Definition: svgfig.py:547
mps_setup.append
append
Definition: mps_setup.py:85