CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
sChronoManager.cc
Go to the documentation of this file.
1 /*
2 This file is part of CASToR.
3 
4  CASToR is free software: you can redistribute it and/or modify it under the
5  terms of the GNU General Public License as published by the Free Software
6  Foundation, either version 3 of the License, or (at your option) any later
7  version.
8 
9  CASToR is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  details.
13 
14  You should have received a copy of the GNU General Public License along with
15  CASToR (in file GNU_GPL.TXT). If not, see <http://www.gnu.org/licenses/>.
16 
17 Copyright 2017-2019 all CASToR contributors listed below:
18 
19  --> Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Thibaut MERLIN, Mael MILLARDET, Simon STUTE, Valentin VIELZEUF
20 
21 This is CASToR version 3.0.
22 */
23 
31 #include "sChronoManager.hh"
32 
33 // =====================================================================
34 // ---------------------------------------------------------------------
35 // ---------------------------------------------------------------------
36 // =====================================================================
37 
39 
40 // =====================================================================
41 // ---------------------------------------------------------------------
42 // ---------------------------------------------------------------------
43 // =====================================================================
44 
46 {
47  // Simply default all members
48  mp_Instance = NULL;
51  m_nbThreadsMax = 0;
52  // Permanent profiled steps
61  // Custom profiled steps
62  m_nbCustomSteps = 0;
64  mpp_startCustomSteps = NULL;
65  // Verbose
66  m_verbose = 0;
67 }
68 
69 // =====================================================================
70 // ---------------------------------------------------------------------
71 // ---------------------------------------------------------------------
72 // =====================================================================
73 
75 {
76  // Check number of threads
78  {
79  Cerr("***** sChronoManager::CheckParameters() -> Number of threads for projections is incorrectly set !" << endl);
80  return 1;
81  }
83  {
84  Cerr("***** sChronoManager::CheckParameters() -> Number of threads for image computation is incorrectly set !" << endl);
85  return 1;
86  }
87  // Check number of custom steps
88  if (m_nbCustomSteps<0)
89  {
90  Cerr("***** sChronoManager::CheckParameters() -> Number of custom steps is incorrectly set !" << endl);
91  return 1;
92  }
93  // Verbose
94  if (m_verbose<0)
95  {
96  Cerr("***** sChronoManager::CheckParameters() -> Verbose cannot be negative !" << endl);
97  return 1;
98  }
99  // Normal end
100  return 0;
101 }
102 
103 // =====================================================================
104 // ---------------------------------------------------------------------
105 // ---------------------------------------------------------------------
106 // =====================================================================
107 
109 {
110  // Verbose
111  if (m_verbose>=VERBOSE_LIGHT) Cout("sChronoManager::Initialize() -> Initialize all duration counters for profiling" << endl);
112  // Initialize buffers for data update steps
121  for (int th=0; th<m_nbThreadsForProjection; th++)
122  {
123  mp_durationIterativeDataUpdateStep1[th] = chrono::duration<int64_t,nano>::zero();
124  mp_durationIterativeDataUpdateStep2[th] = chrono::duration<int64_t,nano>::zero();
125  mp_durationIterativeDataUpdateStep3[th] = chrono::duration<int64_t,nano>::zero();
126  mp_durationIterativeDataUpdateStep4[th] = chrono::duration<int64_t,nano>::zero();
127  }
128  // Initialize convolution
129  m_durationConvolution = chrono::duration<int64_t,nano>::zero();
130  // Initialize buffers for custom profiling
131  if (m_nbCustomSteps>0)
132  {
135  for (int nb=0; nb<m_nbCustomSteps; nb++)
136  {
139  for (int th=0; th<m_nbThreadsMax; th++) mpp_durationCustomSteps[nb][th] = chrono::duration<int64_t,nano>::zero();
140  }
141  }
142  // Normal end
143  return 0;
144 }
145 
146 // =====================================================================
147 // ---------------------------------------------------------------------
148 // ---------------------------------------------------------------------
149 // =====================================================================
150 
152 {
154  {
155  // Verbose
156  Cout("sChronoManager::Display() -> Results from the profiling" << endl);
157  // Sum over all threads
158  for (int th=1; th<m_nbThreadsForProjection; th++)
159  {
164  }
165  for (int nb=0; nb<m_nbCustomSteps; nb++) for (int th=1; th<m_nbThreadsMax; th++)
167  // Divide by number of threads (not for the custom steps as we cannot know if they are multi-threaded
168  // using the number of threads for projection or image computation)
173  // Display data update steps
174  Cout(" --> Profiling of the data update step:" << endl);
175  Cout(" | Datafile management: " << setfill( '0' )
176  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep1[0] ).count() << " hours "
177  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep1[0] % Hs( 1 ) ).count() << " mins "
178  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep1[0] % Mins( 1 ) ).count() << " secs "
179  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep1[0] % Secs( 1 ) ).count() << " ms" << endl);
180  Cout(" | Dynamic management: " << setfill( '0' )
181  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep2[0] ).count() << " hours "
182  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep2[0] % Hs( 1 ) ).count() << " mins "
183  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep2[0] % Mins( 1 ) ).count() << " secs "
184  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep2[0] % Secs( 1 ) ).count() << " ms" << endl);
185  Cout(" | Projection management: " << setfill( '0' )
186  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep3[0] ).count() << " hours "
187  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep3[0] % Hs( 1 ) ).count() << " mins "
188  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep3[0] % Mins( 1 ) ).count() << " secs "
189  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep3[0] % Secs( 1 ) ).count() << " ms" << endl);
190  Cout(" | Optimizer management: " << setfill( '0' )
191  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep4[0] ).count() << " hours "
192  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep4[0] % Hs( 1 ) ).count() << " mins "
193  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep4[0] % Mins( 1 ) ).count() << " secs "
194  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep4[0] % Secs( 1 ) ).count() << " ms" << endl);
195  // Display convolution performances
196  Cout(" --> Profiling of the convolution steps: " << setfill( '0' )
197  << setw( 2 ) << chrono::duration_cast<Hs> ( m_durationConvolution ).count() << " hours "
198  << setw( 2 ) << chrono::duration_cast<Mins>( m_durationConvolution % Hs( 1 ) ).count() << " mins "
199  << setw( 2 ) << chrono::duration_cast<Secs>( m_durationConvolution % Mins( 1 ) ).count() << " secs "
200  << setw( 3 ) << chrono::duration_cast<Ms> ( m_durationConvolution % Secs( 1 ) ).count() << " ms" << endl);
201  // Display custom update steps
202  for (int nb=0; nb<m_nbCustomSteps; nb++)
203  {
204  Cout(" --> Custom update step " << nb+1 << ": " << setfill( '0' )
205  << setw( 2 ) << chrono::duration_cast<Hs> ( mpp_durationCustomSteps[nb][0] ).count() << " hours "
206  << setw( 2 ) << chrono::duration_cast<Mins>( mpp_durationCustomSteps[nb][0] % Hs( 1 ) ).count() << " mins "
207  << setw( 2 ) << chrono::duration_cast<Secs>( mpp_durationCustomSteps[nb][0] % Mins( 1 ) ).count() << " secs "
208  << setw( 3 ) << chrono::duration_cast<Ms> ( mpp_durationCustomSteps[nb][0] % Secs( 1 ) ).count() << " ms" << endl);
209  }
210  }
211 }
212 
213 // =====================================================================
214 // ---------------------------------------------------------------------
215 // ---------------------------------------------------------------------
216 // =====================================================================
ChronoTime * mp_startIterativeDataUpdateStep3
int m_nbThreadsForImageComputation
int CheckParameters()
Check validity of all parameters.
std::chrono::seconds Secs
sChronoManager()
The constructor of sChronoManager.
std::chrono::hours Hs
DurationNano * mp_durationIterativeDataUpdateStep2
std::chrono::time_point< std::chrono::system_clock > ChronoTime
std::chrono::duration< int64_t, std::nano > DurationNano
std::chrono::minutes Mins
ChronoTime ** mpp_startCustomSteps
ChronoTime * mp_startIterativeDataUpdateStep4
DurationNano m_durationConvolution
static sChronoManager * mp_Instance
DurationNano * mp_durationIterativeDataUpdateStep1
#define Cerr(MESSAGE)
DurationNano * mp_durationIterativeDataUpdateStep3
DurationNano * mp_durationIterativeDataUpdateStep4
#define VERBOSE_LIGHT
int Initialize()
Initialize all thread-safe buffers for profiling.
ChronoTime * mp_startIterativeDataUpdateStep1
Declaration of class sChronoManager.
DurationNano ** mpp_durationCustomSteps
#define Cout(MESSAGE)
This class is designed to manage some profiling of the code.
ChronoTime * mp_startIterativeDataUpdateStep2
void Display()
Display the results of the duration buffers.