CASToR  2.0
Tomographic Reconstruction (PET/SPECT/CT)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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-2018 all CASToR contributors listed below:
18 
19  --> current contributors: Thibaut MERLIN, Simon STUTE, Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Mael MILLARDET
20  --> past contributors: Valentin VIELZEUF
21 
22 This is CASToR version 2.0.
23 */
24 
32 #include "sChronoManager.hh"
33 
34 // =====================================================================
35 // ---------------------------------------------------------------------
36 // ---------------------------------------------------------------------
37 // =====================================================================
38 
40 
41 // =====================================================================
42 // ---------------------------------------------------------------------
43 // ---------------------------------------------------------------------
44 // =====================================================================
45 
47 {
48  // Simply default all members
49  mp_Instance = NULL;
52  m_nbThreadsMax = 0;
53  // Permanent profiled steps
62  // Custom profiled steps
63  m_nbCustomSteps = 0;
65  mpp_startCustomSteps = NULL;
66  // Verbose
67  m_verbose = 0;
68 }
69 
70 // =====================================================================
71 // ---------------------------------------------------------------------
72 // ---------------------------------------------------------------------
73 // =====================================================================
74 
76 {
77  // Check number of threads
79  {
80  Cerr("***** sChronoManager::CheckParameters() -> Number of threads for projections is incorrectly set !" << endl);
81  return 1;
82  }
84  {
85  Cerr("***** sChronoManager::CheckParameters() -> Number of threads for image computation is incorrectly set !" << endl);
86  return 1;
87  }
88  // Check number of custom steps
89  if (m_nbCustomSteps<0)
90  {
91  Cerr("***** sChronoManager::CheckParameters() -> Number of custom steps is incorrectly set !" << endl);
92  return 1;
93  }
94  // Verbose
95  if (m_verbose<0)
96  {
97  Cerr("***** sChronoManager::CheckParameters() -> Verbose cannot be negative !" << endl);
98  return 1;
99  }
100  // Normal end
101  return 0;
102 }
103 
104 // =====================================================================
105 // ---------------------------------------------------------------------
106 // ---------------------------------------------------------------------
107 // =====================================================================
108 
110 {
111  // Verbose
112  if (m_verbose>=VERBOSE_LIGHT) Cout("sChronoManager::Initialize() -> Initialize all duration counters for profiling" << endl);
113  // Initialize buffers for data update steps
122  for (int th=0; th<m_nbThreadsForProjection; th++)
123  {
124  mp_durationIterativeDataUpdateStep1[th] = chrono::duration<int64_t,nano>::zero();
125  mp_durationIterativeDataUpdateStep2[th] = chrono::duration<int64_t,nano>::zero();
126  mp_durationIterativeDataUpdateStep3[th] = chrono::duration<int64_t,nano>::zero();
127  mp_durationIterativeDataUpdateStep4[th] = chrono::duration<int64_t,nano>::zero();
128  }
129  // Initialize convolution
130  m_durationConvolution = chrono::duration<int64_t,nano>::zero();
131  // Initialize buffers for custom profiling
132  if (m_nbCustomSteps>0)
133  {
136  for (int nb=0; nb<m_nbCustomSteps; nb++)
137  {
140  for (int th=0; th<m_nbThreadsMax; th++) mpp_durationCustomSteps[nb][th] = chrono::duration<int64_t,nano>::zero();
141  }
142  }
143  // Normal end
144  return 0;
145 }
146 
147 // =====================================================================
148 // ---------------------------------------------------------------------
149 // ---------------------------------------------------------------------
150 // =====================================================================
151 
153 {
155  {
156  // Verbose
157  Cout("sChronoManager::Display() -> Results from the profiling" << endl);
158  // Sum over all threads
159  for (int th=1; th<m_nbThreadsForProjection; th++)
160  {
165  }
166  for (int nb=0; nb<m_nbCustomSteps; nb++) for (int th=1; th<m_nbThreadsMax; th++)
168  // Divide by number of threads (not for the custom steps as we cannot know if they are multi-threaded
169  // using the number of threads for projection or image computation)
174  // Display data update steps
175  Cout(" --> Profiling of the data update step:" << endl);
176  Cout(" | Datafile management: " << setfill( '0' )
177  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep1[0] ).count() << " hours "
178  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep1[0] % Hs( 1 ) ).count() << " mins "
179  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep1[0] % Mins( 1 ) ).count() << " secs "
180  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep1[0] % Secs( 1 ) ).count() << " ms" << endl);
181  Cout(" | Dynamic management: " << setfill( '0' )
182  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep2[0] ).count() << " hours "
183  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep2[0] % Hs( 1 ) ).count() << " mins "
184  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep2[0] % Mins( 1 ) ).count() << " secs "
185  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep2[0] % Secs( 1 ) ).count() << " ms" << endl);
186  Cout(" | Projection management: " << setfill( '0' )
187  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep3[0] ).count() << " hours "
188  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep3[0] % Hs( 1 ) ).count() << " mins "
189  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep3[0] % Mins( 1 ) ).count() << " secs "
190  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep3[0] % Secs( 1 ) ).count() << " ms" << endl);
191  Cout(" | Optimizer management: " << setfill( '0' )
192  << setw( 2 ) << chrono::duration_cast<Hs> ( mp_durationIterativeDataUpdateStep4[0] ).count() << " hours "
193  << setw( 2 ) << chrono::duration_cast<Mins>( mp_durationIterativeDataUpdateStep4[0] % Hs( 1 ) ).count() << " mins "
194  << setw( 2 ) << chrono::duration_cast<Secs>( mp_durationIterativeDataUpdateStep4[0] % Mins( 1 ) ).count() << " secs "
195  << setw( 3 ) << chrono::duration_cast<Ms> ( mp_durationIterativeDataUpdateStep4[0] % Secs( 1 ) ).count() << " ms" << endl);
196  // Display convolution performances
197  Cout(" --> Profiling of the convolution steps: " << setfill( '0' )
198  << setw( 2 ) << chrono::duration_cast<Hs> ( m_durationConvolution ).count() << " hours "
199  << setw( 2 ) << chrono::duration_cast<Mins>( m_durationConvolution % Hs( 1 ) ).count() << " mins "
200  << setw( 2 ) << chrono::duration_cast<Secs>( m_durationConvolution % Mins( 1 ) ).count() << " secs "
201  << setw( 3 ) << chrono::duration_cast<Ms> ( m_durationConvolution % Secs( 1 ) ).count() << " ms" << endl);
202  // Display custom update steps
203  for (int nb=0; nb<m_nbCustomSteps; nb++)
204  {
205  Cout(" --> Custom update step " << nb+1 << ": " << setfill( '0' )
206  << setw( 2 ) << chrono::duration_cast<Hs> ( mpp_durationCustomSteps[nb][0] ).count() << " hours "
207  << setw( 2 ) << chrono::duration_cast<Mins>( mpp_durationCustomSteps[nb][0] % Hs( 1 ) ).count() << " mins "
208  << setw( 2 ) << chrono::duration_cast<Secs>( mpp_durationCustomSteps[nb][0] % Mins( 1 ) ).count() << " secs "
209  << setw( 3 ) << chrono::duration_cast<Ms> ( mpp_durationCustomSteps[nb][0] % Secs( 1 ) ).count() << " ms" << endl);
210  }
211  }
212 }
213 
214 // =====================================================================
215 // ---------------------------------------------------------------------
216 // ---------------------------------------------------------------------
217 // =====================================================================
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.