TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Perf_counters.h
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#ifndef Perf_counters_included
17#define Perf_counters_included
18
19#include <iostream>
20#include <string>
21#include <chrono>
22#include <memory>
23#include <arch.h>
24
25// This file contains all of the needed for the description of the counter associated with the tracking of performance in the TRUST code.
26
27enum class STD_COUNTERS : int
28{
29 total_execution_time , ///< Lowest level counter that track the total time of the computation
30 computation_start_up , ///< Track the time before the Resoudre loop
31 timeloop , ///< Track time elapsed in the time loop
32 backup_file ,
33 system_solver, ///< Track time elapsed in SolveurSys::resoudre_systeme
34 matrix_assembly ,
35 ajouter_blocs,
36 convection ,
37 diffusion ,
38 gradient ,
39 divergence ,
40 source_terms ,
41 update_variables ,
42 implicit_diffusion, ///< Track time elapsed in Equation_base::conjugue_diff_impl
43 compute_dt , ///< Track time used to compute the time step dt
44 turbulent_viscosity ,
45 restart ,
46 postreatment ,
47 petsc_solver, ///< Track the time elapsed using petsc solver
48 mpi_sendrecv ,
49 mpi_send ,
50 mpi_recv ,
51 mpi_bcast ,
52 mpi_alltoall ,
53 mpi_allgather ,
54 mpi_gather ,
55 mpi_partialsum,
56 mpi_sumdouble ,
57 mpi_mindouble,
58 mpi_maxdouble ,
59 mpi_sumfloat ,
60 mpi_minfloat ,
61 mpi_maxfloat ,
62 mpi_sumint ,
63 mpi_minint ,
64 mpi_maxint ,
65 mpi_barrier ,
66 gpu_library ,
67 gpu_kernel ,
68 gpu_copytodevice ,
69 gpu_copyfromdevice ,
70 gpu_malloc_free,
71 IO_EcrireFicPartageMPIIO ,
72 IO_EcrireFicPartageBin ,
73 interprete_scatter,
74 virtual_swap ,
75 read_scatter,
76 parallel_meshing,
77 NB_OF_STD_COUNTER
78};
79
80
81
82/*! @brief This class stores and manages counters in TRUST. It is a singleton.
83 *
84 */
86{
87public:
88 using clock = std::chrono::high_resolution_clock;
89 using time_point = std::chrono::time_point<clock>;
90 using duration = std::chrono::duration<double>;
91 inline time_point now()
92 {
93 return clock::now();
94 }
95
96////// Time wrapper /////
97
98 inline time_point start_clock() {return now();} ///< Start a clock, return a time_point, not a double
99
100 double compute_time(time_point start); ///< return time since start in seconds
101
102 /*! @brief The class Perf_counters is based on a phoenix singleton pattern. To access to the unique object inside the code, use the getInstance() function
103 *
104 * @return the unique Perf_counters object
105 */
107 {
108 // Static flag for tracking singleton state
109 static bool destroyed = false;
110 static Perf_counters* instance = nullptr;
111
112 if (instance == nullptr)
113 {
114 if (destroyed)
115 {
116 // If the instance has already been destroyed but still asked for somewhere, the instance is reborn
117 std::cout<< "[Stats] The singleton pattern had to be reconstructed for avoiding \'Static Initialization Order Fiasco\' " <<std::endl;
118 std::cout<< "It does not impact the TU files but be careful with the values of times printed afterwards" <<std::endl;
119 static void* memory = ::operator new(sizeof(Perf_counters));
120 instance = new (memory) Perf_counters();
121 // A cleaning method for avoiding memory leaks
122 std::atexit([]()
123 {
124 instance->~Perf_counters();
125 });
126 }
127 else
128 {
129 // For the first creation of the instance
130 static Perf_counters counters_stat_;
131 instance = &counters_stat_;
132
133 // Update destruction flag
134 std::atexit([]()
135 {
136 destroyed = true;
137 instance = nullptr;
138 });
139 }
140 }
141 return *instance;
142 }
143 /*! @brief Create a new counter and add it to the map of custom counters
144 *
145 * @param counter_level
146 * @param counter_description
147 * @param counter_family
148 * @param is_comm
149 * @return create a new counter
150 *
151 * @note If the counter description already exists, it will not create a new counter.
152 */
153 void create_custom_counter(std::string counter_description , int counter_level, std::string counter_family = "None", bool is_comm=false, bool is_gpu=false);
154
155 /*! Standard counters, start the tracking of the wanted operation
156 *
157 * @param std_cnt reference to the standard counter
158 * @param counter_lvl level of the counter you try to open, warning it changes the value of the counter level associated with counter std_cnt
159 */
160 void begin_count(const STD_COUNTERS& std_cnt, int counter_lvl = -100000);
161
162 /*! Custom counters, start the tracking of the wanted operation
163 *
164 * @param custom_count_name string key in the custom counter map
165 * @param counter_lvl level of the counter you try to open, warning it changes the value of the level of the counter associated with custom_count_name
166 */
167 void begin_count(const std::string& custom_count_name, int counter_lvl= -100000);
168
169 /*! @brief End the count of a counter and update the counter values
170 *
171 * @param c is the counter to end the count
172 * @param count_increment is the count increment. If not specified, then it is equal to 1
173 * @param quantity_increment is the increment of custom variable quantity. If not specified, it is set to 0.
174 */
175 void end_count(const std::string& custom_count_name, int count_increment=1, long int quantity_increment=0);
176
177 /*! @brief End the count of a counter and update the counter values
178 *
179 * @param c is the counter to end the count
180 * @param count_increment is the count increment. If not specified, then it is equal to 1
181 * @param quantity_increment is the increment of custom variable quantity. If not specified, it is set to 0.
182 */
183 void end_count(const STD_COUNTERS& std_cnt, int count_increment=1, long int quantity_increment=0);
184
185 /*! @brief Stop all counters, has to be called on every processor simultaneously
186 *
187 */
188 void stop_counters();
189
190 /*! @brief Restart all counters, has to be called on every processor simultaneously
191 *
192 */
193 void restart_counters();
194
195 /*! @brief Reset counters to zero, used between the start-up of the computation, the computation itself and the post-processing
196 *
197 */
198 void reset_counters();
199
200 /*! @brief Function that encapsulate the two functions that writes the TU files
201 *
202 * @param messsage can only take three values: "Computation start-up statistics", "Time loop statistics" or "Post-resolution statistics"
203 * @note It also resets the counters
204 */
205 void print_TU_files(const std::string& message);
206
207
208 /*!@brief Update computation_time_ and return its value as a double (in seconds)
209 *
210 */
211 double get_computation_time();
212
213 /*!@brief Give as a double the total time (in second) elapsed in the operation tracked by the standard counter call name
214 *
215 */
216 double get_total_time(const STD_COUNTERS& name) ;
217
218 /*!@brief Give as a double the total time (in second) elapsed in the operation tracked by the custom counter call name
219 *
220 */
221 double get_total_time(const std::string& name) ;
222
223 /*!@brief Give as a double the time (in second) elapsed in the operation tracked by the standard counter call name since the counter was last opened
224 *
225 */
226 double get_time_since_last_open(const STD_COUNTERS& name);
227
228 /*!@brief Give as a double the time (in second) elapsed in the operation tracked by the standard counter call name since the counter was last opened
229 *
230 */
231 double get_time_since_last_open(const std::string& name) ;
232
233 /*!@brief Check whether a counter is already running. Should rarely be used!
234 *
235 */
236 bool is_running(const STD_COUNTERS& name);
237
238 /*!
239 * @brief Set time_loop_ to true in order to account for cache properly
240 */
241 void start_timeloop();
242
243 /*!
244 * @brief Set time_loop_ to false as we exit the time loop
245 */
246 void end_timeloop();
247
248 /*!
249 * @brief, this function start statistics tracking for a time step. It has to be called at the start of each time step.
250 */
251 void start_time_step();
252
253 /*!@brief This function compute statistics per time steps of counters used at least once during a time step.
254 *
255 * @param tstep is the current time step number
256 */
257 void end_time_step(long int tstep);
258
259 void set_nb_time_steps_elapsed(int n) ;
260
262
263 void record_nb_elem(trustIdType nb_elem);
264
265 /////// GPU features for a cleaner Device class
266
267 void start_gpu_timer();
268
269 void stop_gpu_timer();
270
271 bool is_gpu_verbose_on() const ;
272 void set_gpu_verbose(bool on) ;
273
274 bool get_init_device() const ;
275
276 void set_init_device(bool init) ;
277
278 bool get_gpu_timer() const ;
279
280 void set_gpu_timer(bool timer);
281
282 void add_to_gpu_timer_counter(int to_add) ;
283
284 int get_gpu_timer_counter() const ;
285
287
288 bool get_use_gpu() const;
289
290 bool get_gpu_fence() const;
291
292 void set_gpu_fence(bool fence);
293
294//// end of GPU features
295
296 Perf_counters(const Perf_counters&) = delete;
298
299private:
300
303 class Impl;
304 std::unique_ptr<Impl> pimpl_;
305};
306
307/*! @brief An that compact the access to the unique Perf_counters object
308 *
309 * @return the unique Perf_counters object
310 */
311inline Perf_counters& statistics() {return Perf_counters::getInstance();}
312
313#endif
314
This class stores and manages counters in TRUST. It is a singleton.
int get_last_opened_counter_level() const
bool is_running(const STD_COUNTERS &name)
Check whether a counter is already running. Should rarely be used!
std::chrono::time_point< clock > time_point
void set_gpu_timer(bool timer)
int get_gpu_timer_counter() const
void end_time_step(long int tstep)
This function compute statistics per time steps of counters used at least once during a time step.
double stop_gpu_timer_and_compute_gpu_time()
void start_timeloop()
Set time_loop_ to true in order to account for cache properly.
Perf_counters(const Perf_counters &)=delete
void set_gpu_verbose(bool on)
void set_gpu_fence(bool fence)
time_point now()
bool get_gpu_timer() const
std::chrono::duration< double > duration
static Perf_counters & getInstance()
The class Perf_counters is based on a phoenix singleton pattern. To access to the unique object insid...
std::chrono::high_resolution_clock clock
void record_nb_elem(trustIdType nb_elem)
void begin_count(const STD_COUNTERS &std_cnt, int counter_lvl=-100000)
void set_init_device(bool init)
bool get_gpu_fence() const
void set_nb_time_steps_elapsed(int n)
double get_time_since_last_open(const STD_COUNTERS &name)
Give as a double the time (in second) elapsed in the operation tracked by the standard counter call n...
void add_to_gpu_timer_counter(int to_add)
void stop_counters()
Stop all counters, has to be called on every processor simultaneously.
bool get_use_gpu() const
double get_total_time(const STD_COUNTERS &name)
Give as a double the total time (in second) elapsed in the operation tracked by the standard counter ...
bool get_init_device() const
void restart_counters()
Restart all counters, has to be called on every processor simultaneously.
void end_timeloop()
Set time_loop_ to false as we exit the time loop.
void reset_counters()
Reset counters to zero, used between the start-up of the computation, the computation itself and the ...
double compute_time(time_point start)
return time since start in seconds
void print_TU_files(const std::string &message)
Function that encapsulate the two functions that writes the TU files.
time_point start_clock()
Start a clock, return a time_point, not a double.
void end_count(const std::string &custom_count_name, int count_increment=1, long int quantity_increment=0)
End the count of a counter and update the counter values.
void create_custom_counter(std::string counter_description, int counter_level, std::string counter_family="None", bool is_comm=false, bool is_gpu=false)
Create a new counter and add it to the map of custom counters.
void start_time_step()
, this function start statistics tracking for a time step. It has to be called at the start of each t...
Perf_counters & operator=(const Perf_counters &)=delete
bool is_gpu_verbose_on() const
double get_computation_time()
Update computation_time_ and return its value as a double (in seconds).