Seismo-VLAB  1.3
An Open-Source Finite Element Software for Meso-Scale Simulations
Profiler.hpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // Seismo Virtual Laboratory
4 // Module for Serial and Parallel Analysis of seismic
5 // wave propagation and soil-structure interaction simulation
6 // Copyright (C) 2018-2021, The California Institute of Technology
7 // All Rights Reserved.
8 //
9 // Commercial use of this program without express permission of the California
10 // Institute of Technology, is strictly prohibited. See file "COPYRIGHT" in
11 // main directory for information on usage and redistribution, and for a
12 // DISCLAIMER OF ALL WARRANTIES.
13 //
14 //==============================================================================
15 //
16 // Written by:
17 // Danilo S. Kusanovic (dkusanov@caltech.edu)
18 // Elnaz E. Seylabi (elnaze@unr.edu)
19 //
20 // Supervised by:
21 // Domniki M. Asimaki (domniki@caltech.edu)
22 //
23 // References :
24 // [1] https://gist.github.com/TheCherno/Instrumentor.h
25 //
26 // Description:
27 // This file contains the "Profiler object" declarations to compute how long it
28 // takes for a program to be executed, and sequentially measures the time of
29 // Execution of each function.
30 //------------------------------------------------------------------------------
31 
32 #ifndef _PROFILER_HHP_
33 #define _PROFILER_HHP_
34 
35 #include <omp.h>
36 #include <string>
37 #include <thread>
38 #include <chrono>
39 #include <algorithm>
40 #include <fstream>
41 #include <sstream>
42 
43 #include "Definitions.hpp"
44 
48  std::string Name;
49 
51  long long Start;
52 
54  long long End;
55 
57  int ThreadID;
58 };
59 
63  std::string Name;
64 };
65 
69 
77 class Profiler{
78 
79  public:
81  Profiler() : m_CurrentSession(nullptr), m_ProfileCount(0){
82  }
83 
86  void BeginSession(const std::string& name){
87  std::stringstream filename;
88  filename << filePath << "/Profiler." << rank << ".json";
89  m_OutputStream.open(filename.str().c_str());
90  WriteHeader();
91  m_CurrentSession = new InstrumentationSession{ name };
92  }
93 
95  void EndSession(){
96  WriteFooter();
97  m_OutputStream.close();
98  delete m_CurrentSession;
99  m_CurrentSession = nullptr;
100  m_ProfileCount = 0;
101  }
102 
105  void WriteProfile(const ProfileResult& result){
106  if (m_ProfileCount++ > 0)
107  m_OutputStream << ",";
108 
109  std::string name = result.Name;
110  std::replace(name.begin(), name.end(), '"', '\'');
111 
112  //The JSON file format to be opened with Google-Chrome
113  m_OutputStream << "{";
114  m_OutputStream << "\"cat\":\"function\",";
115  m_OutputStream << "\"dur\":" << (result.End - result.Start) << ',';
116  m_OutputStream << "\"name\":\"" << name << "\",";
117  m_OutputStream << "\"ph\":\"X\",";
118  m_OutputStream << "\"pid\":\"" << result.ThreadID << "\",";
119  m_OutputStream << "\"tid\":" << rank << ",";
120  m_OutputStream << "\"ts\":" << result.Start;
121  m_OutputStream << "}";
122 
123  //Flush in case the program abruptly stops.
124  m_OutputStream.flush();
125  }
126 
128  void WriteHeader(){
129  m_OutputStream << "{\"otherData\": {},\"traceEvents\":[";
130  m_OutputStream.flush();
131  }
132 
134  void WriteFooter(){
135  m_OutputStream << "]}";
136  m_OutputStream.flush();
137  }
138 
140  static Profiler& Get(){
141  static Profiler instance;
142  return instance;
143  }
144 
145  private:
148 
150  std::ofstream m_OutputStream;
151 
154 };
155 
163 class Timer{
164 
165  public:
168  Timer(const char* name) : m_Name(name), m_Stopped(false){
169  std::this_thread::sleep_for (std::chrono::microseconds(3));
170  m_StartTimepoint = std::chrono::high_resolution_clock::now();
171  }
172 
175  if (!m_Stopped)
176  Stop();
177  }
178 
180  void Stop(){
181  auto endTimepoint = std::chrono::high_resolution_clock::now();
182 
183  long long start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();
184  long long end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimepoint).time_since_epoch().count();
185  int threadID = omp_get_num_threads();
186  Profiler::Get().WriteProfile({ m_Name, start, end, threadID });
187 
188  m_Stopped = true;
189  }
190 
191  private:
193  const char* m_Name;
194 
196  std::chrono::time_point<std::chrono::high_resolution_clock> m_StartTimepoint;
197 
199  bool m_Stopped;
200 };
201 
202 #if PROFILING
203 #define PROFILE_SCOPE(name) Timer timer(name)
206 #define PROFILE_FUNCTION() PROFILE_SCOPE( __PRETTY_FUNCTION__ )
209 #else
210 #define PROFILE_FUNCTION()
211 #endif
212 
213 #endif
int rank
The processor number.
void WriteHeader()
Writes the header file for the JSON-file.
Definition: Profiler.hpp:128
std::ofstream m_OutputStream
The output JSON file where data is written.
Definition: Profiler.hpp:150
std::chrono::time_point< std::chrono::high_resolution_clock > m_StartTimepoint
Time when the timer starts.
Definition: Profiler.hpp:196
~Timer()
Destroys this timer.
Definition: Profiler.hpp:174
const char * m_Name
Name of the function to be timed.
Definition: Profiler.hpp:193
void WriteFooter()
Writes the footer file for the JSON-file.
Definition: Profiler.hpp:134
static Profiler & Get()
Gets the Profiler instance.
Definition: Profiler.hpp:140
int ThreadID
The identifier of this thread.
Definition: Profiler.hpp:57
Structure that holds profiling parameters.
Definition: Profiler.hpp:46
This file sets the global variables to be used during SeismoVLAB execution.
void EndSession()
Ends the Profiler output file.
Definition: Profiler.hpp:95
void Stop()
Stops this timer.
Definition: Profiler.hpp:180
InstrumentationSession * m_CurrentSession
The name of the function to be Profile.
Definition: Profiler.hpp:147
std::string Name
Name of the function to be profiled.
Definition: Profiler.hpp:48
Profiler()
Creates the Profiler object.
Definition: Profiler.hpp:81
void BeginSession(const std::string &name)
Starts the Profiler output file.
Definition: Profiler.hpp:86
long long End
Time when Profiler ends.
Definition: Profiler.hpp:54
Timer(const char *name)
Creates the Scope Timer.
Definition: Profiler.hpp:168
Structure that holds function name to be profile.
Definition: Profiler.hpp:61
bool m_Stopped
Whether or not the timer is stoped.
Definition: Profiler.hpp:199
void WriteProfile(const ProfileResult &result)
Starts the Profiler output file.
Definition: Profiler.hpp:105
Class that compute how long it takes for a program to be executed, and sequentially measures the time...
Definition: Profiler.hpp:163
std::string filePath
The folder path where the file is loaded.
long long Start
Time when Profiler starts.
Definition: Profiler.hpp:51
std::string Name
Name of the function to be profiled.
Definition: Profiler.hpp:63
int m_ProfileCount
Counter for array separator.
Definition: Profiler.hpp:153
Class that creates a JSON file with the time of execution of each function, files can be open at chro...
Definition: Profiler.hpp:77