38 class EventProcessor {
43 virtual void process(ProfileDatabase&,
const std::vector<std::string>& signature, va_list&) {
44 fatal(
"Unknown profiling processing event: %s",
join(signature,
" "));
67 void process(ProfileDatabase& db,
const char* txt, ...) {
72 std::string escapedText =
escape(txt);
74 std::vector<std::string> eventSignature =
splitSignature(escapedText);
77 const std::string& keyword = eventSignature[0];
78 assert(eventSignature.size() > 0 &&
"no keyword in event description");
79 assert(
registry.find(keyword) !=
registry.end() &&
"EventProcessor not found!");
80 registry[keyword]->process(db, eventSignature, args);
88 std::map<std::string, EventProcessor*>
registry;
97 std::string
escape(
const std::string& text) {
98 std::string
str(text);
101 while ((start_pos =
str.find(
'\\', start_pos)) != std::string::npos) {
102 if (start_pos ==
str.size()) {
106 if (
str[start_pos] !=
't' &&
str[start_pos] !=
'"' &&
str[start_pos] !=
'\\' &&
107 str[start_pos] !=
'n' &&
str[start_pos] !=
';') {
108 str.replace(start_pos - 1, 1,
"\\\\");
116 static std::vector<std::string>
split(std::string
str, std::string split_str) {
118 bool repeat = (split_str ==
" ");
120 std::vector<std::string> elems;
124 for (
size_t i = 0;
i <
str.size();
i++) {
126 if (
str.at(
i) == split_str.at(0)) {
127 while (
str.at(++
i) == split_str.at(0)) {
130 elems.push_back(temp);
137 for (
size_t j = 0;
j < hold.size();
j++) {
138 if (hold[
j] != split_str[
j]) {
142 if (hold.size() == split_str.size()) {
143 elems.push_back(temp.substr(0, temp.size() - hold.size()));
150 elems.push_back(temp);
158 for (
size_t i = 0;
i <
str.size();
i++) {
159 if (
i > 0 &&
str[
i] ==
';' &&
str[
i - 1] ==
'\\') {
165 std::vector<std::string> result =
split(
str,
";");
166 for (
auto&
i : result) {
180 const class NonRecursiveRuleTimingProcessor :
public EventProcessor {
185 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
186 const std::string&
relation = signature[1];
187 const std::string& srcLocator = signature[2];
188 const std::string&
rule = signature[3];
189 microseconds start = va_arg(args, microseconds);
190 microseconds end = va_arg(args, microseconds);
191 size_t startMaxRSS = va_arg(args,
size_t);
192 size_t endMaxRSS = va_arg(args,
size_t);
193 size_t size = va_arg(args,
size_t);
195 {
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"maxRSS",
"pre"}, startMaxRSS);
197 {
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"maxRSS",
"post"}, endMaxRSS);
199 {
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"source-locator"}, srcLocator);
201 {
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"runtime"}, start, end);
202 db.addSizeEntry({
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"num-tuples"},
size);
209 const class NonRecursiveRuleNumberProcessor :
public EventProcessor {
215 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
216 const std::string&
relation = signature[1];
217 const std::string& srcLocator = signature[2];
218 const std::string&
rule = signature[3];
219 size_t num = va_arg(args,
size_t);
221 {
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"source-locator"}, srcLocator);
222 db.addSizeEntry({
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"num-tuples"}, num);
234 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
235 const std::string&
relation = signature[1];
236 const std::string& version = signature[2];
237 const std::string& srcLocator = signature[3];
238 const std::string&
rule = signature[4];
239 microseconds start = va_arg(args, microseconds);
240 microseconds end = va_arg(args, microseconds);
241 size_t startMaxRSS = va_arg(args,
size_t);
242 size_t endMaxRSS = va_arg(args,
size_t);
243 size_t size = va_arg(args,
size_t);
244 std::string
iteration = std::to_string(va_arg(args,
size_t));
246 version,
"maxRSS",
"pre"},
249 version,
"maxRSS",
"post"},
252 version,
"source-locator"},
254 db.addDurationEntry({
"program",
"relation",
relation,
"iteration",
iteration,
"recursive-rule",
rule,
258 version,
"num-tuples"},
266 const class RecursiveRuleNumberProcessor :
public EventProcessor {
271 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
272 const std::string&
relation = signature[1];
273 const std::string& version = signature[2];
274 const std::string& srcLocator = signature[3];
275 const std::string&
rule = signature[4];
276 size_t number = va_arg(args,
size_t);
277 std::string
iteration = std::to_string(va_arg(args,
size_t));
279 version,
"source-locator"},
282 version,
"num-tuples"},
296 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
297 const std::string&
relation = signature[1];
298 const std::string& srcLocator = signature[2];
299 microseconds start = va_arg(args, microseconds);
300 microseconds end = va_arg(args, microseconds);
301 size_t startMaxRSS = va_arg(args,
size_t);
302 size_t endMaxRSS = va_arg(args,
size_t);
303 size_t size = va_arg(args,
size_t);
304 db.addSizeEntry({
"program",
"relation",
relation,
"maxRSS",
"pre"}, startMaxRSS);
305 db.addSizeEntry({
"program",
"relation",
relation,
"maxRSS",
"post"}, endMaxRSS);
306 db.addSizeEntry({
"program",
"relation",
relation,
"num-tuples"},
size);
307 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
308 db.addDurationEntry({
"program",
"relation",
relation,
"runtime"}, start, end);
321 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
322 const std::string&
relation = signature[1];
323 const std::string& srcLocator = signature[2];
324 size_t num = va_arg(args,
size_t);
325 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
326 db.addSizeEntry({
"program",
"relation",
relation,
"num-tuples"}, num);
339 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
340 const std::string&
relation = signature[1];
341 const std::string& srcLocator = signature[2];
342 microseconds start = va_arg(args, microseconds);
343 microseconds end = va_arg(args, microseconds);
344 size_t startMaxRSS = va_arg(args,
size_t);
345 size_t endMaxRSS = va_arg(args,
size_t);
346 size_t size = va_arg(args,
size_t);
347 std::string
iteration = std::to_string(va_arg(args,
size_t));
348 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
349 db.addDurationEntry({
"program",
"relation",
relation,
"iteration",
iteration,
"runtime"}, start, end);
351 {
"program",
"relation",
relation,
"iteration",
iteration,
"maxRSS",
"pre"}, startMaxRSS);
361 const class RecursiveRelationNumberProcessor :
public EventProcessor {
367 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
368 const std::string&
relation = signature[1];
369 const std::string& srcLocator = signature[2];
370 size_t number = va_arg(args,
size_t);
371 std::string
iteration = std::to_string(va_arg(args,
size_t));
372 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
373 db.addSizeEntry({
"program",
"relation",
relation,
"iteration",
iteration,
"num-tuples"}, number);
386 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
387 const std::string&
relation = signature[1];
388 const std::string& srcLocator = signature[2];
389 microseconds start = va_arg(args, microseconds);
390 microseconds end = va_arg(args, microseconds);
391 size_t startMaxRSS = va_arg(args,
size_t);
392 size_t endMaxRSS = va_arg(args,
size_t);
393 va_arg(args,
size_t);
394 std::string
iteration = std::to_string(va_arg(args,
size_t));
398 {
"program",
"relation",
relation,
"iteration",
iteration,
"maxRSS",
"post"}, endMaxRSS);
399 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
401 {
"program",
"relation",
relation,
"iteration",
iteration,
"copytime"}, start, end);
408 const class RelationIOTimingProcessor :
public EventProcessor {
415 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
416 const std::string&
relation = signature[1];
417 const std::string& srcLocator = signature[2];
418 const std::string ioType = signature[3];
419 microseconds start = va_arg(args, microseconds);
420 microseconds end = va_arg(args, microseconds);
421 db.addTextEntry({
"program",
"relation",
relation,
"source-locator"}, srcLocator);
422 db.addDurationEntry({
"program",
"relation",
relation, ioType}, start, end);
435 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
436 microseconds
time = va_arg(args, microseconds);
437 auto path = signature;
439 db.addTimeEntry(path,
time);
453 ProfileDatabase& db,
const std::vector<std::string>& , va_list& args)
override {
454 microseconds start = va_arg(args, microseconds);
455 microseconds end = va_arg(args, microseconds);
456 db.addDurationEntry({
"program",
"runtime"}, start, end);
470 ProfileDatabase& db,
const std::vector<std::string>& , va_list& args)
override {
471 microseconds
time = va_arg(args, microseconds);
472 uint64_t systemTime = va_arg(args, uint64_t);
473 uint64_t userTime = va_arg(args, uint64_t);
474 size_t maxRSS = va_arg(args,
size_t);
475 std::string timeString = std::to_string(
time.count());
476 db.addSizeEntry({
"program",
"usage",
"timepoint", timeString,
"systemtime"}, systemTime);
477 db.addSizeEntry({
"program",
"usage",
"timepoint", timeString,
"usertime"}, userTime);
478 db.addSizeEntry({
"program",
"usage",
"timepoint", timeString,
"maxRSS"}, maxRSS);
491 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
492 const std::string&
relation = signature[1];
493 const std::string& version = signature[2];
494 const std::string&
rule = signature[3];
495 const std::string& atom = signature[4];
496 const std::string& originalRule = signature[5];
497 size_t level = std::stoi(signature[6]);
498 size_t number = va_arg(args,
size_t);
502 db.addSizeEntry({
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"atom-frequency",
503 rule, atom,
"level"},
505 db.addSizeEntry({
"program",
"relation",
relation,
"non-recursive-rule",
rule,
"atom-frequency",
506 rule, atom,
"num-tuples"},
511 "recursive-rule", originalRule, version,
"atom-frequency",
rule, atom,
"level"},
513 db.addSizeEntry({
"program",
"relation",
relation,
"iteration", std::to_string(
iteration),
514 "recursive-rule", originalRule, version,
"atom-frequency",
rule, atom,
524 const class RelationReadsProcessor :
public EventProcessor {
530 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
531 const std::string&
relation = signature[1];
532 size_t reads = va_arg(args,
size_t);
533 db.addSizeEntry({
"program",
"relation",
relation,
"reads"}, reads);
547 ProfileDatabase& db,
const std::vector<std::string>& , va_list& args)
override {
548 const std::string key = va_arg(args,
char*);
549 const std::string& value = va_arg(args,
char*);
550 db.addTextEntry({
"program",
"configuration", key}, value);
562 void process(ProfileDatabase& db,
const std::vector<std::string>& signature, va_list& args)
override {
563 const std::string text = va_arg(args,
char*);
564 auto path = signature;
565 path.front() =
"program";
566 db.addTextEntry(path, text);