OILS / vendor / souffle / profile / OutputProcessor.h View on Github | oilshell.org

384 lines, 226 significant
1/*
2 * Souffle - A Datalog Compiler
3 * Copyright (c) 2016, The Souffle Developers. All rights reserved
4 * Licensed under the Universal Permissive License v 1.0 as shown at:
5 * - https://opensource.org/licenses/UPL
6 * - <souffle root>/licenses/SOUFFLE-UPL.txt
7 */
8
9#pragma once
10
11#include "souffle/profile/Cell.h"
12#include "souffle/profile/CellInterface.h"
13#include "souffle/profile/Iteration.h"
14#include "souffle/profile/ProgramRun.h"
15#include "souffle/profile/Relation.h"
16#include "souffle/profile/Row.h"
17#include "souffle/profile/Rule.h"
18#include "souffle/profile/Table.h"
19#include <chrono>
20#include <memory>
21#include <ratio>
22#include <set>
23#include <string>
24#include <unordered_map>
25#include <utility>
26#include <vector>
27
28namespace souffle {
29namespace profile {
30
31/*
32 * Class to format profiler data structures into tables
33 */
34class OutputProcessor {
35private:
36 std::shared_ptr<ProgramRun> programRun;
37
38public:
39 OutputProcessor() {
40 programRun = std::make_shared<ProgramRun>(ProgramRun());
41 }
42
43 const std::shared_ptr<ProgramRun>& getProgramRun() const {
44 return programRun;
45 }
46
47 Table getRelTable() const;
48
49 Table getRulTable() const;
50
51 Table getSubrulTable(std::string strRel, std::string strRul) const;
52
53 Table getAtomTable(std::string strRel, std::string strRul) const;
54
55 Table getVersions(std::string strRel, std::string strRul) const;
56
57 Table getVersionAtoms(std::string strRel, std::string strRul, int version) const;
58};
59
60/*
61 * rel table :
62 * ROW[0] = TOT_T
63 * ROW[1] = NREC_T
64 * ROW[2] = REC_T
65 * ROW[3] = COPY_T
66 * ROW[4] = TUPLES
67 * ROW[5] = REL NAME
68 * ROW[6] = ID
69 * ROW[7] = SRC
70 * ROW[8] = PERFOR
71 * ROW[9] = LOADTIME
72 * ROW[10] = SAVETIME
73 * ROW[11] = MAXRSSDIFF
74 * ROW[12] = READS
75 *
76 */
77Table inline OutputProcessor::getRelTable() const {
78 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
79 programRun->getRelationMap();
80 Table table;
81 for (auto& rel : relationMap) {
82 std::shared_ptr<Relation> r = rel.second;
83 Row row(13);
84 auto total_time = r->getNonRecTime() + r->getRecTime() + r->getCopyTime();
85 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(total_time);
86 row[1] = std::make_shared<Cell<std::chrono::microseconds>>(r->getNonRecTime());
87 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(r->getRecTime());
88 row[3] = std::make_shared<Cell<std::chrono::microseconds>>(r->getCopyTime());
89 row[4] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(r->size()));
90 row[5] = std::make_shared<Cell<std::string>>(r->getName());
91 row[6] = std::make_shared<Cell<std::string>>(r->getId());
92 row[7] = std::make_shared<Cell<std::string>>(r->getLocator());
93 if (total_time.count() != 0) {
94 row[8] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(
95 static_cast<double>(r->size()) / (static_cast<double>(total_time.count()) / 1000000.0)));
96 } else {
97 row[8] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(r->size()));
98 }
99 row[9] = std::make_shared<Cell<std::chrono::microseconds>>(r->getLoadtime());
100 row[10] = std::make_shared<Cell<std::chrono::microseconds>>(r->getSavetime());
101 row[11] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(r->getMaxRSSDiff()));
102 row[12] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(r->getReads()));
103
104 table.addRow(std::make_shared<Row>(row));
105 }
106 return table;
107}
108/*
109 * rul table :
110 * ROW[0] = TOT_T
111 * ROW[1] = NREC_T
112 * ROW[2] = REC_T
113 * ROW[3] = COPY_T
114 * ROW[4] = TUPLES
115 * ROW[5] = RUL NAME
116 * ROW[6] = ID
117 * ROW[7] = SRC
118 * ROW[8] = PERFOR
119 * ROW[9] = VER
120 * ROW[10]= REL_NAME
121 */
122Table inline OutputProcessor::getRulTable() const {
123 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
124 programRun->getRelationMap();
125 std::unordered_map<std::string, std::shared_ptr<Row>> ruleMap;
126
127 for (auto& rel : relationMap) {
128 for (auto& current : rel.second->getRuleMap()) {
129 Row row(11);
130 std::shared_ptr<Rule> rule = current.second;
131 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
132 row[1] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
133 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
134 row[3] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
135 row[4] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(rule->size()));
136 row[5] = std::make_shared<Cell<std::string>>(rule->getName());
137 row[6] = std::make_shared<Cell<std::string>>(rule->getId());
138 row[7] = std::make_shared<Cell<std::string>>(rel.second->getName());
139 row[8] = std::make_shared<Cell<int64_t>>(0);
140 row[10] = std::make_shared<Cell<std::string>>(rule->getLocator());
141 ruleMap.emplace(rule->getName(), std::make_shared<Row>(row));
142 }
143 for (auto& iter : rel.second->getIterations()) {
144 for (auto& current : iter->getRules()) {
145 std::shared_ptr<Rule> rule = current.second;
146 if (ruleMap.find(rule->getName()) != ruleMap.end()) {
147 Row row = *ruleMap[rule->getName()];
148 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(
149 row[2]->getTimeVal() + rule->getRuntime());
150 row[4] = std::make_shared<Cell<int64_t>>(
151 row[4]->getLongVal() + static_cast<int64_t>(rule->size()));
152 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(
153 row[0]->getTimeVal() + rule->getRuntime());
154 ruleMap[rule->getName()] = std::make_shared<Row>(row);
155 } else {
156 Row row(11);
157 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
158 row[1] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
159 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
160 row[3] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
161 row[4] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(rule->size()));
162 row[5] = std::make_shared<Cell<std::string>>(rule->getName());
163 row[6] = std::make_shared<Cell<std::string>>(rule->getId());
164 row[7] = std::make_shared<Cell<std::string>>(rel.second->getName());
165 row[8] = std::make_shared<Cell<int64_t>>(rule->getVersion());
166 row[10] = std::make_shared<Cell<std::string>>(rule->getLocator());
167 ruleMap[rule->getName()] = std::make_shared<Row>(row);
168 }
169 }
170 }
171 for (auto& current : ruleMap) {
172 std::shared_ptr<Row> row = current.second;
173 Row t = *row;
174 std::chrono::microseconds val = t[1]->getTimeVal() + t[2]->getTimeVal() + t[3]->getTimeVal();
175
176 t[0] = std::make_shared<Cell<std::chrono::microseconds>>(val);
177
178 if (t[0]->getTimeVal().count() != 0) {
179 t[9] = std::make_shared<Cell<double>>(t[4]->getLongVal() / (t[0]->getDoubleVal() * 1000));
180 } else {
181 t[9] = std::make_shared<Cell<double>>(t[4]->getLongVal() / 1.0);
182 }
183 current.second = std::make_shared<Row>(t);
184 }
185 }
186
187 Table table;
188 for (auto& current : ruleMap) {
189 table.addRow(current.second);
190 }
191 return table;
192}
193
194/*
195 * atom table :
196 * ROW[0] = clause
197 * ROW[1] = atom
198 * ROW[2] = level
199 * ROW[3] = frequency
200 */
201Table inline OutputProcessor::getAtomTable(std::string strRel, std::string strRul) const {
202 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
203 programRun->getRelationMap();
204
205 Table table;
206 for (auto& current : relationMap) {
207 std::shared_ptr<Relation> rel = current.second;
208
209 if (rel->getId() != strRel) {
210 continue;
211 }
212
213 for (auto& current : rel->getRuleMap()) {
214 std::shared_ptr<Rule> rule = current.second;
215 if (rule->getId() != strRul) {
216 continue;
217 }
218 for (auto& atom : rule->getAtoms()) {
219 Row row(4);
220 row[0] = std::make_shared<Cell<std::string>>(atom.rule);
221 row[1] = std::make_shared<Cell<std::string>>(atom.identifier);
222 row[2] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(atom.level));
223 row[3] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(atom.frequency));
224
225 table.addRow(std::make_shared<Row>(row));
226 }
227 }
228 }
229 return table;
230}
231
232/*
233 * subrule table :
234 * ROW[0] = subrule
235 */
236Table inline OutputProcessor::getSubrulTable(std::string strRel, std::string strRul) const {
237 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
238 programRun->getRelationMap();
239
240 Table table;
241 for (auto& current : relationMap) {
242 std::shared_ptr<Relation> rel = current.second;
243
244 if (rel->getId() != strRel) {
245 continue;
246 }
247
248 for (auto& current : rel->getRuleMap()) {
249 std::shared_ptr<Rule> rule = current.second;
250 if (rule->getId() != strRul) {
251 continue;
252 }
253 for (auto& atom : rule->getAtoms()) {
254 Row row(1);
255 row[0] = std::make_shared<Cell<std::string>>(atom.rule);
256
257 table.addRow(std::make_shared<Row>(row));
258 }
259 }
260 }
261 return table;
262}
263
264/*
265 * ver table :
266 * ROW[0] = TOT_T
267 * ROW[1] = NREC_T
268 * ROW[2] = REC_T
269 * ROW[3] = COPY_T
270 * ROW[4] = TUPLES
271 * ROW[5] = RUL NAME
272 * ROW[6] = ID
273 * ROW[7] = SRC
274 * ROW[8] = PERFOR
275 * ROW[9] = VER
276 * ROW[10]= REL_NAME
277 */
278Table inline OutputProcessor::getVersions(std::string strRel, std::string strRul) const {
279 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
280 programRun->getRelationMap();
281 Table table;
282
283 std::shared_ptr<Relation> rel;
284 for (auto& current : relationMap) {
285 if (current.second->getId() == strRel) {
286 rel = current.second;
287 break;
288 }
289 }
290 if (rel == nullptr) {
291 return table;
292 }
293
294 std::unordered_map<std::string, std::shared_ptr<Row>> ruleMap;
295 for (auto& iter : rel->getIterations()) {
296 for (auto& current : iter->getRules()) {
297 std::shared_ptr<Rule> rule = current.second;
298 if (rule->getId() == strRul) {
299 std::string strTemp =
300 rule->getName() + rule->getLocator() + std::to_string(rule->getVersion());
301
302 if (ruleMap.find(strTemp) != ruleMap.end()) {
303 Row row = *ruleMap[strTemp];
304 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(
305 row[2]->getTimeVal() + rule->getRuntime());
306 row[4] = std::make_shared<Cell<int64_t>>(
307 row[4]->getLongVal() + static_cast<int64_t>(rule->size()));
308 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
309 ruleMap[strTemp] = std::make_shared<Row>(row);
310 } else {
311 Row row(10);
312 row[1] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
313 row[2] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
314 row[3] = std::make_shared<Cell<std::chrono::microseconds>>(std::chrono::microseconds(0));
315 row[4] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(rule->size()));
316 row[5] = std::make_shared<Cell<std::string>>(rule->getName());
317 row[6] = std::make_shared<Cell<std::string>>(rule->getId());
318 row[7] = std::make_shared<Cell<std::string>>(rel->getName());
319 row[8] = std::make_shared<Cell<int64_t>>(rule->getVersion());
320 row[9] = std::make_shared<Cell<std::string>>(rule->getLocator());
321 row[0] = std::make_shared<Cell<std::chrono::microseconds>>(rule->getRuntime());
322 ruleMap[strTemp] = std::make_shared<Row>(row);
323 }
324 }
325 }
326 }
327
328 for (auto row : ruleMap) {
329 Row t = *row.second;
330 t[0] = std::make_shared<Cell<std::chrono::microseconds>>(
331 t[1]->getTimeVal() + t[2]->getTimeVal() + t[3]->getTimeVal());
332 ruleMap[row.first] = std::make_shared<Row>(t);
333 }
334
335 for (auto& current : ruleMap) {
336 table.addRow(current.second);
337 }
338 return table;
339}
340
341/*
342 * atom table :
343 * ROW[0] = rule
344 * ROW[1] = atom
345 * ROW[2] = level
346 * ROW[3] = frequency
347 */
348Table inline OutputProcessor::getVersionAtoms(std::string strRel, std::string srcLocator, int version) const {
349 const std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap =
350 programRun->getRelationMap();
351 Table table;
352 std::shared_ptr<Relation> rel;
353
354 for (auto& current : relationMap) {
355 if (current.second->getId() == strRel) {
356 rel = current.second;
357 break;
358 }
359 }
360 if (rel == nullptr) {
361 return table;
362 }
363
364 for (auto& iter : rel->getIterations()) {
365 for (auto& current : iter->getRules()) {
366 std::shared_ptr<Rule> rule = current.second;
367 if (rule->getLocator() == srcLocator && rule->getVersion() == version) {
368 for (auto& atom : rule->getAtoms()) {
369 Row row(4);
370 row[0] = std::make_shared<Cell<std::string>>(atom.rule);
371 row[1] = std::make_shared<Cell<std::string>>(atom.identifier);
372 row[2] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(atom.level));
373 row[3] = std::make_shared<Cell<int64_t>>(static_cast<int64_t>(atom.frequency));
374 table.addRow(std::make_shared<Row>(row));
375 }
376 }
377 }
378 }
379
380 return table;
381}
382
383} // namespace profile
384} // namespace souffle