MUQ  0.4.3
OTF2Tracer.h
Go to the documentation of this file.
1 #ifndef OTF2TRACER_H
2 #define OTF2TRACER_H
3 
4 #if MUQ_HAS_OTF2==1
5 #include <otf2/otf2.h>
6 #include <otf2/OTF2_MPI_Collectives.h>
7 #endif
8 
9 namespace muq {
10  namespace Utilities{
11 
21  };
22 
28  public:
29 
30  virtual void enterRegion(TracerRegions region) = 0;
31 
32  virtual void leaveRegion(TracerRegions region) = 0;
33 
34  virtual void write() = 0;
35  };
36 
42  public:
43 
45  OTF2TracerDummy(std::string archive_path, std::string archive_name) {}
46 
47  void enterRegion(TracerRegions region) override {}
48 
49  void leaveRegion(TracerRegions region) override {}
50 
51  void write() override {
52  spdlog::warn("write() has been called on an OTF2TracerDummy; no OTF2 trace file will be written! You may need to install libotf2.");
53  }
54  };
55 
56 
57 #if MUQ_HAS_OTF2==1
58 
59  static OTF2_TimeStamp
60  get_time( void )
61  {
62  double t = MPI_Wtime() * 1e9;
63  return ( uint64_t )t;
64  }
65  static OTF2_FlushType
66  pre_flush( void* userData,
67  OTF2_FileType fileType,
68  OTF2_LocationRef location,
69  void* callerData,
70  bool final )
71  {
72  return OTF2_FLUSH;
73  }
74  static OTF2_TimeStamp
75  post_flush( void* userData,
76  OTF2_FileType fileType,
77  OTF2_LocationRef location )
78  {
79  return get_time();
80  }
81  static OTF2_FlushCallbacks flush_callbacks =
82  {
83  .otf2_pre_flush = pre_flush,
84  .otf2_post_flush = post_flush
85  };
86 
92  class OTF2Tracer : public OTF2TracerBase {
93 
94 
95  public:
96 
97  OTF2Tracer(std::string archive_path, std::string archive_name) {
98  MPI_Comm_size( MPI_COMM_WORLD, &size );
99  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
100  archive = OTF2_Archive_Open( archive_path.c_str(),
101  archive_name.c_str(),
102  OTF2_FILEMODE_WRITE,
103  1024 * 1024 /* event chunk size */,
104  4 * 1024 * 1024 /* def chunk size */,
105  OTF2_SUBSTRATE_POSIX,
106  OTF2_COMPRESSION_NONE );
107  OTF2_Archive_SetFlushCallbacks( archive, &flush_callbacks, NULL );
108  OTF2_MPI_Archive_SetCollectiveCallbacks( archive,
109  MPI_COMM_WORLD,
110  MPI_COMM_NULL );
111  OTF2_Archive_OpenEvtFiles( archive );
112 
113  evt_writer = OTF2_Archive_GetEvtWriter( archive, rank );
114 
115  epoch_start = get_time();
116 
121  setRegionName(TracerRegions::RetrievingProposal, "RetrievingProposal");
124  setRegionName(TracerRegions::FetchingProposal, "FetchingProposal");
125  }
126 
130  void enterRegion(TracerRegions region) override {
131  ensureRegionName(region);
132  OTF2_EvtWriter_Enter( evt_writer,
133  NULL,
134  get_time(),
135  region );
136  }
137 
141  void leaveRegion(TracerRegions region) override {
142  ensureRegionName(region);
143  OTF2_EvtWriter_Leave( evt_writer,
144  NULL,
145  get_time(),
146  region );
147  }
148 
149  private:
154  if (regionNames.count(region) == 0)
155  regionNames[region] = "Unnamed region " + std::to_string(region);
156  }
157 
158  void setRegionName(TracerRegions region, std::string name) {
159  regionNames[region] = name;
160  }
161 
162  public:
163 
164  void write() override {
165  uint64_t epoch_end = get_time();
166  OTF2_Archive_CloseEvtWriter( archive, evt_writer );
167  OTF2_Archive_CloseEvtFiles( archive );
168  OTF2_Archive_OpenDefFiles( archive );
169  OTF2_DefWriter* def_writer = OTF2_Archive_GetDefWriter( archive,
170  rank );
171  OTF2_Archive_CloseDefWriter( archive, def_writer );
172  OTF2_Archive_CloseDefFiles( archive );
173  uint64_t global_epoch_start;
174  MPI_Reduce( &epoch_start,
175  &global_epoch_start,
176  1, OTF2_MPI_UINT64_T, MPI_MIN,
177  0, MPI_COMM_WORLD );
178  uint64_t global_epoch_end;
179  MPI_Reduce( &epoch_end,
180  &global_epoch_end,
181  1, OTF2_MPI_UINT64_T, MPI_MAX,
182  0, MPI_COMM_WORLD );
183  if ( 0 == rank )
184  {
185  OTF2_GlobalDefWriter* global_def_writer = OTF2_Archive_GetGlobalDefWriter( archive );
186  OTF2_GlobalDefWriter_WriteClockProperties( global_def_writer,
187  1000000000,
188  global_epoch_start,
189  global_epoch_end - global_epoch_start + 1 );
190  OTF2_GlobalDefWriter_WriteString( global_def_writer, 0, "" );
191  OTF2_GlobalDefWriter_WriteString( global_def_writer, 1, "Master Thread" );
192  OTF2_GlobalDefWriter_WriteString( global_def_writer, 2, "MPI_Barrier" );
193  OTF2_GlobalDefWriter_WriteString( global_def_writer, 3, "PMPI_Barrier" );
194  OTF2_GlobalDefWriter_WriteString( global_def_writer, 4, "barrier" );
195  OTF2_GlobalDefWriter_WriteString( global_def_writer, 5, "MyHost" );
196  OTF2_GlobalDefWriter_WriteString( global_def_writer, 6, "node" );
197  OTF2_GlobalDefWriter_WriteString( global_def_writer, 7, "MPI" );
198  OTF2_GlobalDefWriter_WriteString( global_def_writer, 8, "MPI_COMM_WORLD" );
199  int num_strings = 9;
200 
201  for ( const auto &regionNamePair : regionNames ) {
202 
203  OTF2_GlobalDefWriter_WriteString( global_def_writer, num_strings, regionNamePair.second.c_str() );
204  OTF2_GlobalDefWriter_WriteRegion( global_def_writer,
205  regionNamePair.first /* id */,
206  num_strings /* region name */,
207  num_strings /* alternative name */,
208  num_strings /* description */,
209  OTF2_REGION_ROLE_CODE,
210  OTF2_PARADIGM_MPI,
211  OTF2_REGION_FLAG_NONE,
212  7 /* source file */,
213  0 /* begin lno */,
214  0 /* end lno */ );
215  num_strings++;
216  }
217  OTF2_GlobalDefWriter_WriteSystemTreeNode( global_def_writer,
218  0 /* id */,
219  5 /* name */,
220  6 /* class */,
221  OTF2_UNDEFINED_SYSTEM_TREE_NODE /* parent */ );
222 
223  for ( int r = 0; r < size; r++ )
224  {
225  char process_name[ 32 ];
226  sprintf( process_name, "MPI Rank %d", r );
227  OTF2_GlobalDefWriter_WriteString( global_def_writer,
228  num_strings + r,
229  process_name );
230  OTF2_GlobalDefWriter_WriteLocationGroup( global_def_writer,
231  r /* id */,
232  num_strings + r /* name */,
233  OTF2_LOCATION_GROUP_TYPE_PROCESS,
234  0 /* system tree */ );
235  OTF2_GlobalDefWriter_WriteLocation( global_def_writer,
236  r /* id */,
237  1 /* name */,
238  OTF2_LOCATION_TYPE_CPU_THREAD,
239  4 /* # events */,
240  r /* location group */ );
241  }
242  uint64_t comm_locations[ size ];
243  for ( int r = 0; r < size; r++ )
244  {
245  comm_locations[ r ] = r;
246  }
247  OTF2_GlobalDefWriter_WriteGroup( global_def_writer,
248  0 /* id */,
249  7 /* name */,
250  OTF2_GROUP_TYPE_COMM_LOCATIONS,
251  OTF2_PARADIGM_MPI,
252  OTF2_GROUP_FLAG_NONE,
253  size,
254  comm_locations );
255  OTF2_GlobalDefWriter_WriteGroup( global_def_writer,
256  1 /* id */,
257  0 /* name */,
258  OTF2_GROUP_TYPE_COMM_GROUP,
259  OTF2_PARADIGM_MPI,
260  OTF2_GROUP_FLAG_NONE,
261  size,
262  comm_locations );
263  OTF2_GlobalDefWriter_WriteComm( global_def_writer,
264  0 /* id */,
265  8 /* name */,
266  1 /* group */,
267  OTF2_UNDEFINED_COMM /* parent */ );
268  OTF2_Archive_CloseGlobalDefWriter( archive,
269  global_def_writer );
270  }
271 
272  OTF2_Archive_Close( archive );
273  }
274 
275  private:
276  int size;
277  int rank;
278  uint64_t epoch_start;
279 
280  OTF2_Archive* archive;
281  OTF2_EvtWriter* evt_writer;
282 
283  std::map<int, std::string> regionNames;
284  };
285 #else
286 
287  using OTF2Tracer = OTF2TracerDummy; // Fall back to dummy implementation if OTF2 library is not found.
288 
289 #endif
290 
291  }
292 }
293 
294 #endif
Base interface for OTF2 tracer implemetations.
Definition: OTF2Tracer.h:27
virtual void leaveRegion(TracerRegions region)=0
virtual void enterRegion(TracerRegions region)=0
Fallback dummy implementation not doing anything; Does not require libotf2.
Definition: OTF2Tracer.h:41
void leaveRegion(TracerRegions region) override
Definition: OTF2Tracer.h:49
OTF2TracerDummy(std::string archive_path, std::string archive_name)
Definition: OTF2Tracer.h:45
void enterRegion(TracerRegions region) override
Definition: OTF2Tracer.h:47
Tracer implementation writing to OTF2 via libotf2 The result can be viewed by several programs,...
Definition: OTF2Tracer.h:92
void enterRegion(TracerRegions region) override
Call this to mark that a certain tracer region has been entered.
Definition: OTF2Tracer.h:130
void leaveRegion(TracerRegions region) override
Call this to mark that a certain tracer region has been left.
Definition: OTF2Tracer.h:141
OTF2Tracer(std::string archive_path, std::string archive_name)
Definition: OTF2Tracer.h:97
void setRegionName(TracerRegions region, std::string name)
Definition: OTF2Tracer.h:158
void ensureRegionName(TracerRegions region)
Makes sure a region name has been defined, otherwise generates a default region name.
Definition: OTF2Tracer.h:153
OTF2_EvtWriter * evt_writer
Definition: OTF2Tracer.h:281
void write() override
Definition: OTF2Tracer.h:164
OTF2_Archive * archive
Definition: OTF2Tracer.h:280
std::map< int, std::string > regionNames
Definition: OTF2Tracer.h:283
static OTF2_TimeStamp post_flush(void *userData, OTF2_FileType fileType, OTF2_LocationRef location)
Definition: OTF2Tracer.h:75
static OTF2_FlushCallbacks flush_callbacks
Definition: OTF2Tracer.h:81
static OTF2_TimeStamp get_time(void)
Definition: OTF2Tracer.h:60
static OTF2_FlushType pre_flush(void *userData, OTF2_FileType fileType, OTF2_LocationRef location, void *callerData, bool final)
Definition: OTF2Tracer.h:66
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25172