Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / tools / kernel_report / kernel_report.py
1 #!/usr/bin/python
2
3 # Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #    http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 import argparse
18 from os.path import dirname, realpath, join
19
20
21 class Backend:
22     def __init__(self, backendList):
23         self.backends = {}
24
25         for backend in backendList:
26             self.backends[backend] = False
27
28
29 class KernelReporter(object):
30     def __init__(self, args):
31         root_path = dirname(dirname(dirname(realpath(__file__))))
32         self.onertBase = join(root_path, "runtime", "onert")
33         if args.md5:
34             self.printMD5 = True
35         else:
36             self.printMD5 = False
37         self.backendList = args.backends.split(',')
38         self.opListFile = "core/include/ir/Operations.lst"
39         self.operations = []
40         self.kernelGeneratorFile = "KernelGenerator.h"
41         self.kernelMap = {}
42
43     def parseOpList(self):
44         # Parsing line and get op list
45         skipLine = False
46         for line in open(self.onertBase + '/' + self.opListFile, "r"):
47             # Skip license
48             # TODO : Change to skip general comment
49             if skipLine:
50                 if line.startswith(" */"):
51                     skipLine = False
52                     continue
53                 continue
54             if line.startswith("/*"):
55                 skipLine = True
56                 continue
57
58             # Skip comment
59             if line.startswith("//"):
60                 continue
61
62             # Skip macro
63             if line.startswith("#"):
64                 continue
65
66             lineStripped = line.strip()
67             if len(lineStripped) == 0:
68                 continue
69
70             op = lineStripped[3:-1]
71             self.operations.append(op)
72             self.operations.sort()
73
74     def generateKernelMap(self):
75         for op in self.operations:
76             self.kernelMap[op] = Backend(self.backendList)
77
78         for backend in self.backendList:
79             buf = open(
80                 self.onertBase + '/backend/' + backend + '/' + self.kernelGeneratorFile,
81                 "r")
82
83             for line in buf:
84                 words = line.split()
85                 if len(words) < 3:
86                     continue
87                 if words[1] != "visit(const":
88                     continue
89
90                 opName = words[2].split("::")
91                 if len(opName) < 3:
92                     continue
93
94                 if opName[2] in self.operations:
95                     self.kernelMap[opName[2]].backends[backend] = True
96
97             buf.close()
98
99     def printResult(self):
100         print()
101         line = ""
102         for backend in self.backendList:
103             line = line + "{0:^9}".format(backend)
104         print('{0:30}{1}'.format("", line))
105
106         counts = []
107         for i in range(0, len(self.backendList), 1):
108             counts.append(0)
109
110         for op in self.operations:
111             line = ""
112             for i in range(0, len(self.backendList), 1):
113                 support = self.kernelMap[op].backends[self.backendList[i]]
114                 if support:
115                     line = line + "{0:^9}".format("O")
116                     counts[i] += 1
117                 else:
118                     line = line + "{0:^9}".format("-")
119             print('{0:30}{1}'.format(op, line))
120
121         line = ""
122         for count in counts:
123             line = line + "{0:^9}".format(count)
124         print('{0:30}{1}'.format("TOTAL COUNT", line))
125
126     def printMDFormat(self):
127         print()
128         line = "-"
129         for backend in self.backendList:
130             line = line + "|" + backend
131         print(line)
132         line = ""
133         for i in range(0, len(self.backendList), 1):
134             line = line + "-|"
135         print(line + "-")
136
137         counts = []
138         for i in range(0, len(self.backendList), 1):
139             counts.append(0)
140
141         for op in self.operations:
142             line = ""
143             for i in range(0, len(self.backendList), 1):
144                 support = self.kernelMap[op].backends[self.backendList[i]]
145                 if support:
146                     line = line + "|" + "O"
147                     counts[i] += 1
148                 else:
149                     line = line + "|" + "-"
150             print(op + line)
151
152         line = ""
153         for i in range(0, len(self.backendList), 1):
154             line = line + "-|"
155         print(line + "-")
156
157         line = ""
158         for count in counts:
159             line = line + "|" + str(count)
160
161         print("TOTAL COUNT" + line)
162
163     def run(self):
164         self.parseOpList()
165         self.generateKernelMap()
166
167         if self.printMD5:
168             self.printMDFormat()
169         else:
170             self.printResult()
171
172
173 if __name__ == '__main__':
174     arg_parser = argparse.ArgumentParser()
175     arg_parser.add_argument(
176         "--backends",
177         type=str,
178         default='cpu,acl_cl,acl_neon',
179         help="backend list to report (use comma)")
180     arg_parser.add_argument("--md5", action='store_true', help="Print for md5")
181     args = arg_parser.parse_args()
182
183     report = KernelReporter(args)
184     report.run()