| 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/Relation.h"
 | 
| 12 | #include "souffle/profile/StringUtils.h"
 | 
| 13 | #include "souffle/profile/Table.h"
 | 
| 14 | #include <chrono>
 | 
| 15 | #include <cstddef>
 | 
| 16 | #include <memory>
 | 
| 17 | #include <set>
 | 
| 18 | #include <sstream>
 | 
| 19 | #include <string>
 | 
| 20 | #include <unordered_map>
 | 
| 21 | #include <utility>
 | 
| 22 | #include <vector>
 | 
| 23 | 
 | 
| 24 | namespace souffle {
 | 
| 25 | namespace profile {
 | 
| 26 | 
 | 
| 27 | /*
 | 
| 28 |  * Stores the relations of the program
 | 
| 29 |  * ProgramRun -> Relations -> Iterations/Rules
 | 
| 30 |  */
 | 
| 31 | class ProgramRun {
 | 
| 32 | private:
 | 
| 33 |     std::unordered_map<std::string, std::shared_ptr<Relation>> relationMap;
 | 
| 34 |     std::chrono::microseconds startTime{0};
 | 
| 35 |     std::chrono::microseconds endTime{0};
 | 
| 36 | 
 | 
| 37 | public:
 | 
| 38 |     ProgramRun() : relationMap() {}
 | 
| 39 | 
 | 
| 40 |     inline void setStarttime(std::chrono::microseconds time) {
 | 
| 41 |         startTime = time;
 | 
| 42 |     }
 | 
| 43 | 
 | 
| 44 |     inline void setEndtime(std::chrono::microseconds time) {
 | 
| 45 |         endTime = time;
 | 
| 46 |     }
 | 
| 47 | 
 | 
| 48 |     inline void setRelationMap(std::unordered_map<std::string, std::shared_ptr<Relation>>& relationMap) {
 | 
| 49 |         this->relationMap = relationMap;
 | 
| 50 |     }
 | 
| 51 | 
 | 
| 52 |     std::string toString() {
 | 
| 53 |         std::ostringstream output;
 | 
| 54 |         output << "ProgramRun:" << getRuntime() << "\nRelations:\n";
 | 
| 55 |         for (auto& r : relationMap) {
 | 
| 56 |             output << r.second->toString() << "\n";
 | 
| 57 |         }
 | 
| 58 |         return output.str();
 | 
| 59 |     }
 | 
| 60 | 
 | 
| 61 |     inline const std::unordered_map<std::string, std::shared_ptr<Relation>>& getRelationMap() const {
 | 
| 62 |         return relationMap;
 | 
| 63 |     }
 | 
| 64 | 
 | 
| 65 |     std::string getRuntime() const {
 | 
| 66 |         if (startTime == endTime) {
 | 
| 67 |             return "--";
 | 
| 68 |         }
 | 
| 69 |         return formatTime(endTime - startTime);
 | 
| 70 |     }
 | 
| 71 | 
 | 
| 72 |     std::chrono::microseconds getStarttime() const {
 | 
| 73 |         return startTime;
 | 
| 74 |     }
 | 
| 75 | 
 | 
| 76 |     std::chrono::microseconds getEndtime() const {
 | 
| 77 |         return endTime;
 | 
| 78 |     }
 | 
| 79 | 
 | 
| 80 |     std::chrono::microseconds getTotalLoadtime() const {
 | 
| 81 |         std::chrono::microseconds result{0};
 | 
| 82 |         for (auto& item : relationMap) {
 | 
| 83 |             result += item.second->getLoadtime();
 | 
| 84 |         }
 | 
| 85 |         return result;
 | 
| 86 |     }
 | 
| 87 | 
 | 
| 88 |     std::chrono::microseconds getTotalSavetime() const {
 | 
| 89 |         std::chrono::microseconds result{0};
 | 
| 90 |         for (auto& item : relationMap) {
 | 
| 91 |             result += item.second->getSavetime();
 | 
| 92 |         }
 | 
| 93 |         return result;
 | 
| 94 |     }
 | 
| 95 | 
 | 
| 96 |     std::size_t getTotalSize() const {
 | 
| 97 |         std::size_t result = 0;
 | 
| 98 |         for (auto& item : relationMap) {
 | 
| 99 |             result += item.second->size();
 | 
| 100 |         }
 | 
| 101 |         return result;
 | 
| 102 |     }
 | 
| 103 | 
 | 
| 104 |     std::size_t getTotalRecursiveSize() const {
 | 
| 105 |         std::size_t result = 0;
 | 
| 106 |         for (auto& item : relationMap) {
 | 
| 107 |             result += item.second->getTotalRecursiveRuleSize();
 | 
| 108 |         }
 | 
| 109 |         return result;
 | 
| 110 |     }
 | 
| 111 | 
 | 
| 112 |     std::chrono::microseconds getTotalCopyTime() const {
 | 
| 113 |         std::chrono::microseconds result{0};
 | 
| 114 |         for (auto& item : relationMap) {
 | 
| 115 |             result += item.second->getCopyTime();
 | 
| 116 |         }
 | 
| 117 |         return result;
 | 
| 118 |     }
 | 
| 119 | 
 | 
| 120 |     std::chrono::microseconds getTotalTime() const {
 | 
| 121 |         std::chrono::microseconds result{0};
 | 
| 122 |         for (auto& item : relationMap) {
 | 
| 123 |             result += item.second->getRecTime();
 | 
| 124 |         }
 | 
| 125 |         return result;
 | 
| 126 |     }
 | 
| 127 | 
 | 
| 128 |     const Relation* getRelation(const std::string& name) const {
 | 
| 129 |         if (relationMap.find(name) != relationMap.end()) {
 | 
| 130 |             return &(*relationMap.at(name));
 | 
| 131 |         }
 | 
| 132 |         return nullptr;
 | 
| 133 |     }
 | 
| 134 | 
 | 
| 135 |     std::set<std::shared_ptr<Relation>> getRelationsAtTime(
 | 
| 136 |             std::chrono::microseconds start, std::chrono::microseconds end) const {
 | 
| 137 |         std::set<std::shared_ptr<Relation>> result;
 | 
| 138 |         for (auto& cur : relationMap) {
 | 
| 139 |             if (cur.second->getStarttime() <= end && cur.second->getEndtime() >= start) {
 | 
| 140 |                 result.insert(cur.second);
 | 
| 141 |             } else if (cur.second->getLoadStarttime() <= end && cur.second->getLoadEndtime() >= start) {
 | 
| 142 |                 result.insert(cur.second);
 | 
| 143 |             }
 | 
| 144 |         }
 | 
| 145 |         return result;
 | 
| 146 |     }
 | 
| 147 | 
 | 
| 148 |     inline std::string formatTime(std::chrono::microseconds runtime) const {
 | 
| 149 |         return Tools::formatTime(runtime);
 | 
| 150 |     }
 | 
| 151 | 
 | 
| 152 |     inline std::string formatNum(int precision, int64_t number) const {
 | 
| 153 |         return Tools::formatNum(precision, number);
 | 
| 154 |     }
 | 
| 155 | 
 | 
| 156 |     inline std::vector<std::vector<std::string>> formatTable(Table& table, int precision) const {
 | 
| 157 |         return Tools::formatTable(table, precision);
 | 
| 158 |     }
 | 
| 159 | };
 | 
| 160 | 
 | 
| 161 | }  // namespace profile
 | 
| 162 | }  // namespace souffle
 |