SST  6.0.0
StructuralSimulationToolkit
output.h
1 // Copyright 2009-2016 Sandia Corporation. Under the terms
2 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2016, Sandia Corporation
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 
13 
14 #ifndef SST_CORE_OUTPUT_H
15 #define SST_CORE_OUTPUT_H
16 
17 #include <string.h>
18 
19 // UNCOMMENT OUT THIS LINE TO ENABLE THE DEBUG METHOD -OR_
20 // CHOOSE THE --enable-debug OPTION DURING SST CONFIGURATION
21 //#define __SST_DEBUG_OUTPUT__
22 
23 //This must be defined before inclusion of intttypes.h
24 #ifndef __STDC_FORMAT_MACROS
25 #define __STDC_FORMAT_MACROS
26 #endif
27 #include <cinttypes>
28 #include <cstdio>
29 #include <thread>
30 #include <unordered_map>
31 
32 #include <stdarg.h>
33 
34 #include <sst/core/rankInfo.h>
35 
36 extern int main(int argc, char **argv);
37 
38 namespace SST {
39 
40 // MACROS TO HELP BUILD THE CALLING FUNCTIONS INFORMATION
41 #define CALL_INFO __LINE__, __FILE__, __FUNCTION__
42 
43 #if defined(__GNUC__) || defined(__clang__)
44 #define CALL_INFO_LONG __LINE__, __FILE__, __PRETTY_FUNCTION__
45 #else
46 #define CALL_INFO_LONG __LINE__, __FILE__, __FUNCTION__
47 #endif
48 
49 /**
50  * Output object provides consistant method for outputing data to
51  * stdout, stderr and/or sst debug file. All components should
52  * use this class to log any information.
53  */
54 class Output
55 {
56 public:
57  /** Choice of output location
58  */
60  NONE, /*!< No output */
61  STDOUT, /*!< Print to stdout */
62  STDERR, /*!< Print to stderr */
63  FILE /*!< Print to a file */
64  };
65 
66  /** Constructor. Set up output configuration.
67  @param prefix Prefix to be prepended to all strings emitted by calls to
68  debug(), verbose(), fatal() and possibly output().
69  NOTE: No space will be inserted between the prepended prefix
70  string and the normal output string.
71  Prefix can contain the following escape codes:
72  - \@f Name of the file in which output call was made.
73  - \@l Line number in the file in which output call was made.
74  - \@p Name of the function from which output call was made.
75  - \@r MPI rank of the calling process. Will be empty if
76  MPI_COMM_WORLD size is 1.
77  - \@R MPI rank of the calling process. Will be 0 if
78  MPI_COMM_WORLD size is 1.
79  - \@i Thread Id of the calling process. Will be empty if
80  number of threads is 1.
81  - \@I Thread Id of the calling process. Will be 0 if
82  number of threads is 1.
83  - \@x Rank information of the calling process. Will be empty if
84  number of MPI ranks and number of threads are both 1
85  Same as [\@r:\@i]
86  - \@X Rank information of the calling process. Will be [0.0] if
87  number of MPI ranks and number of threads are both 1
88  Same as [\@R:\@I]
89  - \@t Simulation time. Will be the raw simulaton cycle time
90  retrieved from the SST Core.
91  @param verbose_level Debugging output level. Calls to debug(),
92  verbose() and fatal() are only output if their output_level
93  parameter is less than or equal to the verbose_level currently
94  set for the object
95  @param verbose_mask Bitmask of allowed message types for debug(),
96  verbose() and fatal(). The Output object will only output the
97  message if the set bits of the output_bits parameter
98  are set in the verbose_mask of the object. It uses this logic:
99  if (~verbose_mask & output_bits == 0) then output is enabled.
100  @param location Output location. Ouput will be directed to STDOUT,
101  STDERR, FILE, or NONE. If FILE output is selected, the
102  output will be directed to the file defined by the
103  --debug runtime parameter, or to the file 'sst_output' if the
104  --debug parameter is not defined. If the size of MPI_COMM_WORLD
105  is > 1, then the rank process will be appended to the file name.
106  @param localoutputfilename. Send the output of this class to the
107  file identified in localoutputfilename instead of the of the
108  normal output file set by the run time parameter --debug-file.
109  location parameter must be set to FILE. This parameter is
110  intended for special case debug purposes only.
111  */
112  // CONSTRUCTION / DESTRUCTION
113  Output(const std::string& prefix, uint32_t verbose_level,
114  uint32_t verbose_mask, output_location_t location,
115  std::string localoutputfilename = "");
116 
117  /** Default Constructor. User must call init() to properly initialize obj.
118  Until init() is called, no output will occur.
119  */
120  Output(); // Default constructor
121 
122  virtual ~Output();
123 
124 
125  /** Initialize the object after construction
126  @param prefix Prefix to be prepended to all strings emitted by calls to
127  debug(), verbose(), fatal() and possibly output().
128  NOTE: No space will be inserted between the prepended prefix
129  string and the normal output string.
130  Prefix can contain the following escape codes:
131  - \@f Name of the file in which output call was made.
132  - \@l Line number in the file in which output call was made.
133  - \@p Name of the function from which output call was made.
134  - \@r MPI rank of the calling process. Will be empty if
135  MPI_COMM_WORLD size is 1.
136  - \@R MPI rank of the calling process. Will be 0 if
137  MPI_COMM_WORLD size is 1.
138  - \@i Thread Id of the calling process. Will be empty if
139  number of threads is 1.
140  - \@I Thread Id of the calling process. Will be 0 if
141  number of threads is 1.
142  - \@x Rank information of the calling process. Will be empty if
143  number of MPI ranks and number of threads are both 1
144  Same as [\@r:\@i]
145  - \@X Rank information of the calling process. Will be [0.0] if
146  number of MPI ranks and number of threads are both 1
147  Same as [\@R:\@I]
148  - \@t Simulation time. Will be the raw simulaton cycle time
149  retrieved from the SST Core.
150  @param verbose_level Debugging output level. Calls to debug(),
151  verbose() and fatal() are only output if their output_level
152  parameter is less than or equal to the verbose_level currently
153  set for the object
154  @param verbose_mask Bitmask of allowed message types for debug(),
155  verbose() and fatal(). The Output object will only output the
156  message if the set bits of the output_bits parameter
157  are set in the verbose_mask of the object. It uses this logic:
158  if (~verbose_mask & output_bits == 0) then output is enabled.
159  @param location Output location. Ouput will be directed to STDOUT,
160  STDERR, FILE, or NONE. If FILE output is selected, the
161  output will be directed to the file defined by the
162  --debug runtime parameter, or to the file 'sst_output' if the
163  --debug parameter is not defined. If the size of MPI_COMM_WORLD
164  is > 1, then the rank process will be appended to the file name.
165  @param localoutputfilename. Send the output of this class to the
166  file identified in localoutputfilename instead of the of the
167  normal output file set by the run time parameter --debug-file.
168  location parameter must be set to FILE. This parameter is
169  intended for special case debug purposes only.
170  */
171  // INITIALIZATION
172  void init(const std::string& prefix, uint32_t verbose_level,
173  uint32_t verbose_mask, output_location_t location,
174  std::string localoutputfilename = "");
175 
176  /** Output the message with formatting as specified by the format parameter.
177  The output will be prepended with the expanded prefix set in the object.
178  @param line Line number of calling function (use CALL_INFO macro)
179  @param file File name calling function (use CALL_INFO macro)
180  @param func Function name calling function (use CALL_INFO macro)
181  @param format Format string. All valid formats for printf are available.
182  @param ... Argument strings for format.
183  */
184  void output(uint32_t line, const char* file, const char* func,
185  const char* format, ...) const
186  __attribute__ ((format (printf, 5, 6)))
187  {
188  va_list arg;
189  if (true == m_objInitialized && NONE != m_targetLoc ) {
190  // Get the argument list and then print it out
191  va_start(arg, format);
192  outputprintf(line, file, func, format, arg);
193  va_end(arg);
194  }
195  }
196 
197  /** Output the message with formatting as specified by the format parameter.
198  @param format Format string. All valid formats for printf are available.
199  @param ... Arguments for format.
200  */
201  void output(const char* format, ...) const
202  __attribute__ ((format (printf, 2, 3)))
203  {
204  va_list arg;
205  if (true == m_objInitialized && NONE != m_targetLoc) {
206  // Get the argument list and then print it out
207  va_start(arg, format);
208  outputprintf(format, arg);
209  va_end(arg);
210  }
211  }
212 
213  /** Output the verbose message with formatting as specified by the format
214  parameter. Output will only occur if specified output_level and
215  output_bits meet criteria defined by object. The output will be
216  prepended with the expanded prefix set in the object.
217  @param line Line number of calling function (use CALL_INFO macro)
218  @param file File name calling function (use CALL_INFO macro)
219  @param func Function name calling function (use CALL_INFO macro)
220  @param output_level For output to occur, output_level must be less than
221  or equal to verbose_level set in object
222  @param output_bits The Output object will only output the
223  message if the set bits of the output_bits parameter are set in
224  the verbose_mask of the object. It uses this logic:
225  if (~verbose_mask & output_bits == 0) then output is enabled.
226  @param format Format string. All valid formats for printf are available.
227  @param ... Arguments for format.
228  */
229  void verbose(uint32_t line, const char* file, const char* func,
230  uint32_t output_level, uint32_t output_bits,
231  const char* format, ...) const
232  __attribute__ ((format (printf, 7, 8)))
233  {
234  va_list arg;
235 
236  if (true == m_objInitialized && NONE != m_targetLoc ) {
237  // First check to see if we are allowed to send output based upon the
238  // verbose_mask and verbose_level checks
239  if (((output_bits & ~m_verboseMask) == 0) &&
240  (output_level <= m_verboseLevel)){
241  // Get the argument list and then print it out
242  va_start(arg, format);
243  outputprintf(line, file, func, format, arg);
244  va_end(arg);
245  }
246  }
247  }
248 
249  /** Output the verbose message with formatting as specified by the format
250  parameter. Output will only occur if specified output_level and
251  output_bits meet criteria defined by object. The output will be
252  prepended with the expanded prefix set in the object.
253  @param tempPrefix For just this call use this prefix
254  @param line Line number of calling function (use CALL_INFO macro)
255  @param file File name calling function (use CALL_INFO macro)
256  @param func Function name calling function (use CALL_INFO macro)
257  @param output_level For output to occur, output_level must be less than
258  or equal to verbose_level set in object
259  @param output_bits The Output object will only output the
260  message if the set bits of the output_bits parameter are set in
261  the verbose_mask of the object. It uses this logic:
262  if (~verbose_mask & output_bits == 0) then output is enabled.
263  @param format Format string. All valid formats for printf are available.
264  @param ... Arguments for format.
265  */
266  void verbosePrefix(const char* tempPrefix, uint32_t line, const char* file, const char* func,
267  uint32_t output_level, uint32_t output_bits,
268  const char* format, ...)
269  __attribute__ ((format (printf, 8, 9)))
270  {
271 
272  va_list arg;
273 
274  if (true == m_objInitialized && NONE != m_targetLoc ) {
275  const std::string normalPrefix = m_outputPrefix;
276  m_outputPrefix = tempPrefix;
277 
278  // First check to see if we are allowed to send output based upon the
279  // verbose_mask and verbose_level checks
280  if (((output_bits & ~m_verboseMask) == 0) &&
281  (output_level <= m_verboseLevel)){
282  // Get the argument list and then print it out
283  va_start(arg, format);
284  outputprintf(line, file, func, format, arg);
285  va_end(arg);
286  }
287 
288  m_outputPrefix = normalPrefix;
289  }
290  }
291 
292  /** Output the debug message with formatting as specified by the format
293  parameter. Output will only occur if specified output_level and
294  output_bits meet criteria defined by object. The output will be
295  prepended with the expanded prefix set in the object.
296  NOTE: Debug ouputs will only occur if the __SST_DEBUG_OUTPUT__ is defined.
297  this define can be set in source code or by setting the
298  --enable-debug option during SST configuration.
299  @param line Line number of calling function (use CALL_INFO macro)
300  @param file File name calling function (use CALL_INFO macro)
301  @param func Function name calling function (use CALL_INFO macro)
302  @param output_level For output to occur, output_level must be less than
303  or equal to verbose_level set in object
304  @param output_bits The Output object will only output the
305  message if the set bits of the output_bits parameter are set in
306  the verbose_mask of the object. It uses this logic:
307  if (~verbose_mask & output_bits == 0) then output is enabled.
308  @param format Format string. All valid formats for printf are available.
309  @param ... Arguments for format.
310  */
311  void debug(uint32_t line, const char* file, const char* func,
312  uint32_t output_level, uint32_t output_bits,
313  const char* format, ...) const
314  __attribute__ ((format (printf, 7, 8)))
315  {
316 #ifdef __SST_DEBUG_OUTPUT__
317  va_list arg;
318  if (true == m_objInitialized && NONE != m_targetLoc ) {
319  // First check to see if we are allowed to send output based upon the
320  // verbose_mask and verbose_level checks
321  if (((output_bits & ~m_verboseMask) == 0) &&
322  (output_level <= m_verboseLevel)){
323  // Get the argument list and then print it out
324  va_start(arg, format);
325  outputprintf(line, file, func, format, arg);
326  va_end(arg);
327  }
328  }
329 #endif
330  }
331 
332 
333  /** Output the fatal message with formatting as specified by the format
334  parameter. Message will be sent to the output location and to stderr.
335  The output will be prepended with the expanded prefix set
336  in the object.
337  NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation.
338  @param line Line number of calling function (use CALL_INFO macro)
339  @param file File name calling function (use CALL_INFO macro)
340  @param func Function name calling function (use CALL_INFO macro)
341  @param exit_code The exit code used for termination of simuation.
342  will be passed to MPI_Abort()
343  @param format Format string. All valid formats for printf are available.
344  @param ... Arguments for format.
345  */
346  void fatal(uint32_t line, const char* file, const char* func,
347  uint32_t exit_code,
348  const char* format, ...) const
349  __attribute__ ((format (printf, 6, 7))) ;
350 
351 
352  // GET / SET METHODS
353 
354  /** Sets object prefix
355  @param prefix Prefix to be prepended to all strings emitted by calls to
356  debug(), verbose(), fatal() and possibly output().
357  NOTE: No space will be inserted between the prepended prefix
358  string and the normal output string.
359  Prefix can contain the following escape codes:
360  - \@f Name of the file in which output call was made.
361  - \@l Line number in the file in which output call was made.
362  - \@p Name of the function from which output call was made.
363  - \@r MPI rank of the calling process. Will be empty if
364  MPI_COMM_WORLD size is 1.
365  - \@R MPI rank of the calling process. Will be 0 if
366  MPI_COMM_WORLD size is 1.
367  - \@i Thread Id of the calling process. Will be empty if
368  number of threads is 1.
369  - \@I Thread Id of the calling process. Will be 0 if
370  number of threads is 1.
371  - \@x Rank information of the calling process. Will be empty if
372  number of MPI ranks and number of threads are both 1
373  Same as [\@r:\@i]
374  - \@X Rank information of the calling process. Will be [0.0] if
375  number of MPI ranks and number of threads are both 1
376  Same as [\@R:\@I]
377  - \@t Simulation time. Will be the raw simulaton cycle time
378  retrieved from the SST Core.
379  */
380  void setPrefix(const std::string& prefix);
381 
382  /** Returns object prefix */
383  std::string getPrefix() const;
384 
385  /** Sets object verbose mask
386  @param verbose_mask Bitmask of allowed message types for debug(),
387  verbose() and fatal(). The Output object will only output the
388  message if the set bits of the output_bits parameter
389  are set in the verbose_mask of the object. It uses this logic:
390  if (~verbose_mask & output_bits == 0) then output is enabled.
391  */
392  void setVerboseMask(uint32_t verbose_mask);
393 
394  /** Returns object verbose mask */
395  uint32_t getVerboseMask() const;
396 
397  /** Sets object verbose level
398  @param verbose_level Debugging output level. Calls to debug(),
399  verbose() and fatal() are only output if their output_level
400  parameter is less than or equal to the verbose_level currently
401  set for the object
402  */
403  void setVerboseLevel(uint32_t verbose_level);
404 
405  /** Returns object verbose level */
406  uint32_t getVerboseLevel() const;
407 
408  /** Sets object output location
409  @param location Output location. Ouput will be directed to STDOUT,
410  STDERR, FILE, or NONE. If FILE output is selected, the
411  output will be directed to the file defined by the
412  --debug runtime parameter, or to the file 'sst_output' if the
413  --debug parameter is not defined. If the size of MPI_COMM_WORLD
414  is > 1, then the rank process will be appended to the file name.
415  */
416  void setOutputLocation(output_location_t location);
417 
418  /** Returns object output location */
420 
421  /** This method allows for the manual flushing of the output. */
422  inline void flush() const {std::fflush(*m_targetOutputRef);}
423 
424 
425  /** This method sets the static filename used by SST. It can only be called
426  once, and is automatically called by the SST Core. No components should
427  call this method.
428  */
429  static void setFileName(const std::string& filename);
430 
431  static Output& getDefaultObject() { return m_defaultObject; }
432 
433 private:
434  // Support Methods
435  void setTargetOutput(output_location_t location);
436  void openSSTTargetFile() const;
437  void closeSSTTargetFile();
438  // std::string getMPIProcName() const;
439  int getMPIWorldRank() const;
440  int getMPIWorldSize() const;
441  uint32_t getNumThreads() const;
442  uint32_t getThreadRank() const;
443  std::string buildPrefixString(uint32_t line,
444  const std::string& file,
445  const std::string& func) const;
446  void outputprintf(uint32_t line,
447  const std::string &file,
448  const std::string &func,
449  const char *format,
450  va_list arg) const;
451  void outputprintf(const char *format, va_list arg) const;
452 
453  friend int ::main(int argc, char **argv);
454  static Output& setDefaultObject(const std::string& prefix, uint32_t verbose_level,
455  uint32_t verbose_mask, output_location_t location,
456  std::string localoutputfilename = "")
457  {
458  m_defaultObject.init(prefix, verbose_level, verbose_mask, location, localoutputfilename);
459  return getDefaultObject();
460  }
461 
462  static void setWorldSize(const RankInfo &ri, int mpiRank)
463  {
464  m_worldSize = ri;
465  m_mpiRank = mpiRank;
466  }
467 
468  static void setThreadID(std::thread::id mach, uint32_t user)
469  {
470  m_threadMap.insert(std::make_pair(mach, user));
471  }
472 
473 
474  // Internal Member Variables
475  bool m_objInitialized;
476  std::string m_outputPrefix;
477  uint32_t m_verboseLevel;
478  uint32_t m_verboseMask;
479  output_location_t m_targetLoc;
480 
481  static Output m_defaultObject;
482 
483  // m_targetOutputRef is a pointer to a FILE* object. This is because
484  // the actual FILE* object (m_sstFileHandle) is not created on construction,
485  // but during the first call any of output(), verbose() or debug() methods.
486  // m_targetOutputRef points to either &m_sstFileHandle, &stdout, or &stderr
487  // depending upon constructor for the object. However m_sstFileHandle is a
488  // static variable that is set by the startup of SST, and the location
489  // cannot be changed in the constructor or a call to setFileName().
490  std::FILE** m_targetOutputRef;
491 
492  // m_targetFileHandleRef, m_targetFileNameRef, and m_targetFileAccessCount
493  // are pointers to their assocted types. These point to either the local
494  // output file information or to the global simulation output file information.
495  std::FILE** m_targetFileHandleRef;
496  std::string* m_targetFileNameRef;
497  uint32_t* m_targetFileAccessCountRef;
498 
499  // Static Member Variables regarding the Global simulation file info
500  static std::string m_sstGlobalSimFileName;
501  static std::FILE* m_sstGlobalSimFileHandle;
502  static uint32_t m_sstGlobalSimFileAccessCount;
503 
504  // File Member Variables regarding the local simulation file info
505  std::string m_sstLocalFileName;
506  std::FILE* m_sstLocalFileHandle;
507  uint32_t m_sstLocalFileAccessCount;
508 
509  static std::unordered_map<std::thread::id, uint32_t> m_threadMap;
510  static RankInfo m_worldSize;
511  static int m_mpiRank;
512 
513 };
514 
515 // Class to easily trace function enter and exit
517 public:
518  TraceFunction(uint32_t line, const char* file, const char* func);
519  ~TraceFunction();
520 
521  Output& getOutput() {return output;}
522 
523 private:
524  Output output;
525  uint32_t line;
526  std::string file;
527  std::string function;
528  uint32_t rank;
529  uint32_t thread;
530 };
531 
532 
533 } // namespace SST
534 
535 #endif // SST_CORE_OUTPUT_H
Output object provides consistant method for outputing data to stdout, stderr and/or sst debug file...
Definition: output.h:54
void setVerboseLevel(uint32_t verbose_level)
Sets object verbose level.
Definition: output.cc:100
void setOutputLocation(output_location_t location)
Sets object output location.
Definition: output.cc:136
void debug(uint32_t line, const char *file, const char *func, uint32_t output_level, uint32_t output_bits, const char *format,...) const
Output the debug message with formatting as specified by the format parameter.
Definition: output.h:311
output_location_t
Choice of output location.
Definition: output.h:59
uint32_t getVerboseLevel() const
Returns object verbose level.
Definition: output.cc:106
void setVerboseMask(uint32_t verbose_mask)
Sets object verbose mask.
Definition: output.cc:112
void output(const char *format,...) const
Output the message with formatting as specified by the format parameter.
Definition: output.h:201
void init(const std::string &prefix, uint32_t verbose_level, uint32_t verbose_mask, output_location_t location, std::string localoutputfilename="")
Initialize the object after construction.
Definition: output.cc:68
Output()
Default Constructor.
Definition: output.cc:56
std::string getPrefix() const
Returns object prefix.
Definition: output.cc:130
Definition: output.h:60
Definition: action.cc:17
void verbose(uint32_t line, const char *file, const char *func, uint32_t output_level, uint32_t output_bits, const char *format,...) const
Output the verbose message with formatting as specified by the format parameter.
Definition: output.h:229
void verbosePrefix(const char *tempPrefix, uint32_t line, const char *file, const char *func, uint32_t output_level, uint32_t output_bits, const char *format,...)
Output the verbose message with formatting as specified by the format parameter.
Definition: output.h:266
Definition: output.h:63
Definition: output.h:516
static void setFileName(const std::string &filename)
This method sets the static filename used by SST.
Definition: output.cc:215
Definition: output.h:61
void output(uint32_t line, const char *file, const char *func, const char *format,...) const
Output the message with formatting as specified by the format parameter.
Definition: output.h:184
Definition: output.h:62
void fatal(uint32_t line, const char *file, const char *func, uint32_t exit_code, const char *format,...) const
Output the fatal message with formatting as specified by the format parameter.
Definition: output.cc:152
uint32_t getVerboseMask() const
Returns object verbose mask.
Definition: output.cc:118
void flush() const
This method allows for the manual flushing of the output.
Definition: output.h:422
output_location_t getOutputLocation() const
Returns object output location.
Definition: output.cc:146
void setPrefix(const std::string &prefix)
Sets object prefix.
Definition: output.cc:124