KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
profiler.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: Máté Kelemen
11 //
12 
13 #pragma once
14 
15 // Project includes
16 #include "includes/code_location.h"
17 
18 // System includes
19 #include <unordered_map>
20 #include <filesystem>
21 #include <chrono>
22 #include <thread>
23 #include <optional>
24 #include <list>
25 #include <mutex>
26 
27 
28 namespace Kratos::Internals {
29 
30 
31 template <class TTimeUnit>
32 class Profiler
33 {
34 private:
35  using TimeUnit = TTimeUnit;
36 
37  using Duration = TimeUnit;
38 
39  using Clock = std::chrono::high_resolution_clock;
40 
42  class Item
43  {
44  public:
45  Item(CodeLocation&& rLocation);
46 
47  private:
48  Item(std::size_t CallCount,
49  Duration CumulativeDuration,
50  Duration MinDuration,
51  Duration MaxDuration,
52  CodeLocation&& rLocation);
53 
54  Item& operator+=(const Item& rOther);
55 
56  private:
57  friend class Profiler;
58 
59  unsigned mRecursionLevel;
60 
61  std::size_t mCallCount;
62 
63  Duration mCumulative;
64 
65  Duration mMin;
66 
67  Duration mMax;
68 
69  CodeLocation mLocation;
70  }; // class Item
71 
72  struct SourceLocationHash
73  {
74  std::size_t operator()(const CodeLocation& r_argument) const
75  {
76  std::string string(r_argument.GetFileName());
77  string.append(std::to_string(r_argument.GetLineNumber()));
78  return std::hash<std::string>()(string);
79  }
80  };
81 
82  struct SourceLocationEquality
83  {
84  bool operator()(const CodeLocation& r_lhs,
85  const CodeLocation& r_rhs) const
86  {
87  return (std::string(r_lhs.GetFileName()) == std::string(r_rhs.GetFileName())) && (r_lhs.GetLineNumber() == r_rhs.GetLineNumber());
88  }
89  };
90 
91 public:
93  class Scope
94  {
95  public:
96  ~Scope();
97 
98  private:
99  Scope(Item& rItem);
100 
101  Scope(Item& rItem, std::chrono::high_resolution_clock::time_point Begin);
102 
103  Scope(Scope&&) = delete;
104 
105  Scope(const Scope&) = delete;
106 
107  Scope& operator=(Scope&&) = delete;
108 
109  Scope& operator=(const Scope&) = delete;
110 
111  private:
112  friend class Profiler;
113 
117  Item& mrItem;
118 
119  const std::chrono::high_resolution_clock::time_point mBegin;
120  }; // class Scope
121 
122  using ItemMap = std::unordered_map<
123  CodeLocation,
124  Item,
125  SourceLocationHash,
126  SourceLocationEquality
127  >;
128 
129 public:
130  Profiler();
131 
132  Profiler(Profiler&& rOther) = default;
133 
134  Profiler(std::filesystem::path&& r_outputPath);
135 
136  ~Profiler();
137 
138  Profiler& operator=(Profiler&& rOther) = default;
139 
140  [[nodiscard]] Item& Create(CodeLocation&& rItem);
141 
142  [[nodiscard]] Scope Profile(Item& rItem);
143 
145  ItemMap Aggregate() const;
146 
147  void Write(std::ostream& rStream) const;
148 
149 private:
150  Profiler(const Profiler&) = delete;
151 
152  Profiler& operator=(const Profiler&) = delete;
153 
154 private:
169  std::unordered_map<std::thread::id,std::list<Item>> mItemContainerMap;
170 
172  Item mItem;
173 
175  std::unique_ptr<Scope> mpScope;
176 
178  std::filesystem::path mOutputPath;
179 }; // class Profiler
180 
181 
182 template <class T>
183 std::ostream& operator<<(std::ostream& rStream, const Profiler<T>& rProfiler);
184 
185 
186 template <class TTimeUnit>
188 {
189 public:
190  static Profiler<TTimeUnit>& Get() noexcept;
191 
192 private:
193  static std::optional<Profiler<TTimeUnit>> mProfiler;
194 
195  static std::mutex mMutex;
196 }; // class ProfilerSingleton
197 
198 
199 } // namespace Kratos::Internals
200 
201 
202 #if defined(KRATOS_ENABLE_PROFILING)
203  #define KRATOS_DEFINE_SCOPE_PROFILER(KRATOS_TIME_UNIT, CODE_LOCATION) \
204  thread_local static auto& KRATOS_STATIC_PROFILER_REF = Kratos::Internals::ProfilerSingleton<KRATOS_TIME_UNIT>::Get(); \
205  thread_local static auto& KRATOS_SCOPE_PROFILED_ITEM = KRATOS_STATIC_PROFILER_REF.Create(CODE_LOCATION); \
206  const auto KRATOS_SCOPE_PROFILER = KRATOS_STATIC_PROFILER_REF.Profile(KRATOS_SCOPE_PROFILED_ITEM)
207 
208  #define KRATOS_PROFILE_SCOPE_MILLI(CODE_LOCATION) KRATOS_DEFINE_SCOPE_PROFILER(std::chrono::milliseconds, CODE_LOCATION)
209 
210  #define KRATOS_PROFILE_SCOPE_MICRO(CODE_LOCATION) KRATOS_DEFINE_SCOPE_PROFILER(std::chrono::microseconds, CODE_LOCATION)
211 
212  #define KRATOS_PROFILE_SCOPE_NANO(CODE_LOCATION) KRATOS_DEFINE_SCOPE_PROFILER(std::chrono::nanoseconds, CODE_LOCATION)
213 
214  #define KRATOS_PROFILE_SCOPE(CODE_LOCATION) KRATOS_PROFILE_SCOPE_MICRO(CODE_LOCATION)
215 
216 #else
217  #define KRATOS_PROFILE_SCOPE_MILLI(CODE_LOCATION)
218 
219  #define KRATOS_PROFILE_SCOPE_MICRO(CODE_LOCATION)
220 
221  #define KRATOS_PROFILE_SCOPE_NANO(CODE_LOCATION)
222 
223  #define KRATOS_PROFILE_SCOPE(CODE_LOCATION)
224 
225 #endif
226 
227 
228 // Definitions of "inlined" functions.
229 #include "utilities/profiler_impl.h"
Definition: code_location.h:31
int GetLineNumber() const
Definition: code_location.cpp:37
const std::string & GetFileName() const
Definition: code_location.cpp:29
RAII wrapper for updating an Item.
Definition: profiler.h:94
~Scope()
Definition: profiler_impl.h:44
Definition: profiler.h:33
std::unordered_map< CodeLocation, Item, SourceLocationHash, SourceLocationEquality > ItemMap
Definition: profiler.h:127
Profiler()
Definition: profiler.cpp:72
Scope Profile(Item &rItem)
Definition: profiler_impl.h:56
Profiler(Profiler &&rOther)=default
Item & Create(CodeLocation &&rItem)
Definition: profiler.cpp:107
Profiler & operator=(Profiler &&rOther)=default
void Write(std::ostream &rStream) const
Definition: profiler.cpp:168
ItemMap Aggregate() const
Collect results from all threads into a single map.
Definition: profiler.cpp:144
~Profiler()
Definition: profiler.cpp:244
Definition: profiler.h:188
static Profiler< TTimeUnit > & Get() noexcept
Definition: profiler.cpp:252
string path
Definition: DEM_run_all_benchmarks_analysis.py:10
Definition: factory.h:208
std::ostream & operator<<(std::ostream &rOStream, AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheMatrix)
Definition: amatrix_interface.h:329