Loading [MathJax]/extensions/TeX/AMSsymbols.js

DUNE-ACFEM (unstable)

optimizationprofile.hh
1#ifndef __DUNE_ACFEM_EXPRESSIONS_OPTIMIZATIONPROFILE_HH__
2#define __DUNE_ACFEM_EXPRESSIONS_OPTIMIZATIONPROFILE_HH__
3
4#include <iostream>
5#include <fstream>
6#include <map>
7
8#include "../common/tostring.hh"
9
10namespace Dune {
11
12 namespace ACFem {
13
14 namespace Expressions {
15
16#ifndef DUNE_ACFEM_PROFILE_OPTIMIZATION
17# define DUNE_ACFEM_RECORD_OPTIMIZATION
18# define DUNE_ACFEM_EXPRESSION_RESULT(EXPR, ...) return EXPR
19#else
20# define DUNE_ACFEM_RECORD_OPTIMIZATION \
21 Dune::ACFem::Expressions::OptimizationProfiler::recordHit(__LINE__, __FILE__, __PRETTY_FUNCTION__)
22
23#if DUNE_ACFEM_TRACE_OPTIMIZATION
24# define DUNE_ACFEM_EXPRESSION_RESULT(EXPR, ...) \
25{ \
26 decltype(auto) result = EXPR; \
27 std::clog << "Expression: " \
28 << toString(result) \
29 << " [" \
30 << std::string(__VA_ARGS__) \
31 << "]" \
32 << std::endl; \
33 return forwardReturnValue<decltype(result)>(result); \
34}
35#else
36# define DUNE_ACFEM_EXPRESSION_RESULT(EXPR, ...) return EXPR
37#endif
38
39 class OptimizationProfiler
40 {
41 using KeyType = std::pair<std::size_t, std::string>;
42 using DataType = std::pair<std::size_t, std::string>;
43 using StorageType = std::map<KeyType, DataType>;
44
45 public:
46 static void recordHit(std::size_t line, const std::string& file, const std::string& prettyFunction)
47 {
48 static OptimizationProfilerDumper dumper;
49 (void)dumper;
50
51 auto key = std::make_pair(line, file);
52 const auto& old = data_.find(key);
53 const auto& fct = old == data_.end() ? parsePrettyFunction(prettyFunction) : old->second.second;
54 data_[key] = std::make_pair(++(data_[key].first), fct);
55#if DUNE_ACFEM_TRACE_OPTIMIZATION
56 std::clog << file << ":" << line << std::endl
57 << prettyFunction << std::endl
58 << std::endl;
59#endif
60 }
61
62 static void clear()
63 {
64 data_.clear();
65 }
66
67 static void dump(std::ostream& out)
68 {
69 out << "COUNT LINE File FUNCTION" << std::endl;
70 for (auto&& kv : data_) {
71 const auto& key = kv.first;
72 const auto& data = kv.second;
73
74 out << data.first << " "
75 << key.first << " "
76 << "\"" << key.second << "\" "
77 << "\"" << parsePrettyFunction(data.second) << "\""
78 << std::endl;
79 }
80 }
81
82 static void read(std::istream& in)
83 {
84 std::string rest;
85 std::string file;
86 std::string fct;
87 std::size_t count;
88 std::size_t line;
89 if (getline(in, rest)) {
90 while (getline(in, rest)) {
91 std::istringstream iss(rest);
92 if (iss >> count >> line) {
93 rest = rest.substr(rest.find("\"")+1);
94 auto posQuote = rest.find("\"");
95 file = rest.substr(0, posQuote);
96 rest = rest.substr(posQuote+3); // " "
97 posQuote = rest.find("\"");
98 fct = rest.substr(0, posQuote);
99
100 auto key = std::make_pair(line, file);
101 const auto& old = data_.find(key);
102 if (old != data_.end()) {
103 if (old->second.second == fct) {
104 count += old->second.first;
105 }
106 }
107 data_[key] = std::make_pair(count, fct);
108 }
109 }
110 }
111 }
112
113 static std::string parsePrettyFunction(const std::string& prettyFunction)
114 {
115 std::vector<std::string> tokens;
116#if DUNE_ACFEM_IS_GCC(0, 9999)
117 auto fctEnd = prettyFunction.find(" [with ");
118#elif DUNE_ACFEM_IS_CLANG(0, 9999)
119 auto fctEnd = prettyFunction.find(" [");
120#endif
121 auto fct = prettyFunction.substr(0, fctEnd);
122 auto rest = prettyFunction.substr(fctEnd+sizeof(" [with ")-1);
123 //std::clog << "rest: " << rest << std::endl;
124 auto pos = std::string::npos;
125 while ((pos = rest.find(";")) != std::string::npos) {
126 tokens.push_back(rest.substr(0, pos-1));
127 rest = rest.substr(pos+2);
128 }
129 tokens.push_back(rest.substr(0, rest.size()-1));
130 for(auto&& token : tokens) {
131 //std::clog << "token: \"" << token << "\"" << std::endl;
132 if (token.find("typename std::enable_if") == 0) {
133 const auto pfxLen = sizeof("typename");
134 fct += "; " + token.substr(pfxLen, token.rfind("::type ")-pfxLen);
135 }
136 }
137
138 return fct;
139 }
140
141 private:
142
143 struct OptimizationProfilerDumper
144 {
145 ~OptimizationProfilerDumper()
146 {
147 std::string dumpFileName = "acfem-expression-profile.dump";
148 std::ifstream oldDumpFile;
149 oldDumpFile.open(dumpFileName);
150 if (oldDumpFile.is_open()) {
151 OptimizationProfiler::read(oldDumpFile);
152 oldDumpFile.close();
153 }
154 std::ofstream dumpFile;
155 dumpFile.open(dumpFileName);
156 if (dumpFile.is_open()) {
157 OptimizationProfiler::dump(dumpFile);
158 dumpFile.close();
159 }
160 }
161 };
162
163 inline static StorageType data_;
164 };
165
166#endif
167
168 } // Expressions::
169
170 } // ACFem::
171
172} // Dune::
173
174#endif // __DUNE_ACFEM_EXPRESSIONS_OPTIMIZATIONPROFILE_HH__
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 12, 23:28, 2025)