00001 // Copyright 2009-2015 Sandia Corporation. Under the terms 00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 00003 // Government retains certain rights in this software. 00004 // 00005 // Copyright (c) 2009-2015, Sandia Corporation 00006 // All rights reserved. 00007 // 00008 // This file is part of the SST software package. For license 00009 // information, see the LICENSE file in the top level directory of the 00010 // distribution. 00011 00012 00013 00014 #ifndef SST_CORE_OUTPUT_H 00015 #define SST_CORE_OUTPUT_H 00016 00017 #include <string.h> 00018 00019 // UNCOMMENT OUT THIS LINE TO ENABLE THE DEBUG METHOD -OR_ 00020 // CHOOSE THE --enable-debug OPTION DURING SST CONFIGURATION 00021 //#define __SST_DEBUG_OUTPUT__ 00022 00023 //This must be defined before inclusion of intttypes.h 00024 #ifndef __STDC_FORMAT_MACROS 00025 #define __STDC_FORMAT_MACROS 00026 #endif 00027 #include <inttypes.h> 00028 #include <cstdio> 00029 00030 #include <sst/core/serialization.h> 00031 00032 namespace SST { 00033 00034 // MACROS TO HELP BUILD THE CALLING FUNCTIONS INFORMATION 00035 #define CALL_INFO __LINE__, __FILE__, __FUNCTION__ 00036 00037 #if defined(__GNUC__) || defined(__clang__) 00038 #define CALL_INFO_LONG __LINE__, __FILE__, __PRETTY_FUNCTION__ 00039 #else 00040 #define CALL_INFO_LONG __LINE__, __FILE__, __FUNCTION__ 00041 #endif 00042 00043 /** 00044 * Output object provides consistant method for outputing data to 00045 * stdout, stderr and/or sst debug file. All components should 00046 * use this class to log any information. 00047 */ 00048 class Output 00049 { 00050 public: 00051 /** Choice of output location 00052 */ 00053 enum output_location_t { 00054 NONE, /*!< No output */ 00055 STDOUT, /*!< Print to stdout */ 00056 STDERR, /*!< Print to stderr */ 00057 FILE /*!< Print to a file */ 00058 }; 00059 00060 /** Constructor. Set up output configuration. 00061 @param prefix Prefix to be prepended to all strings emitted by calls to 00062 debug(), verbose(), fatal() and possibly output(). 00063 NOTE: No space will be inserted between the prepended prefix 00064 string and the normal output string. 00065 Prefix can contain the following escape codes: 00066 - \@f Name of the file in which output call was made. 00067 - \@l Line number in the file in which output call was made. 00068 - \@p Name of the function from which output call was made. 00069 - \@r MPI rank of the calling process. Will be empty if 00070 MPI_COMM_WORLD size is 1. 00071 - \@R MPI rank of the calling process. Will be 0 if 00072 MPI_COMM_WORLD size is 1. 00073 - \@t Simulation time. Will be the raw simulaton cycle time 00074 retrieved from the SST Core. 00075 @param verbose_level Debugging output level. Calls to debug(), 00076 verbose() and fatal() are only output if their output_level 00077 parameter is less than or equal to the verbose_level currently 00078 set for the object 00079 @param verbose_mask Bitmask of allowed message types for debug(), 00080 verbose() and fatal(). The Output object will only output the 00081 message if the set bits of the output_bits parameter 00082 are set in the verbose_mask of the object. It uses this logic: 00083 if (~verbose_mask & output_bits == 0) then output is enabled. 00084 @param location Output location. Ouput will be directed to STDOUT, 00085 STDERR, FILE, or NONE. If FILE output is selected, the 00086 output will be directed to the file defined by the 00087 --debug runtime parameter, or to the file 'sst_output' if the 00088 --debug parameter is not defined. If the size of MPI_COMM_WORLD 00089 is > 1, then the rank process will be appended to the file name. 00090 @param localoutputfilename. Send the output of this class to the 00091 file identified in localoutputfilename instead of the of the 00092 normal output file set by the run time parameter --debug-file. 00093 location parameter must be set to FILE. This parameter is 00094 intended for special case debug purposes only. 00095 */ 00096 // CONSTRUCTION / DESTRUCTION 00097 Output(const std::string& prefix, uint32_t verbose_level, 00098 uint32_t verbose_mask, output_location_t location, 00099 std::string localoutputfilename = ""); 00100 00101 /** Default Constructor. User must call init() to properly initialize obj. 00102 Until init() is called, no output will occur. 00103 */ 00104 Output(); // Default constructor 00105 00106 virtual ~Output(); 00107 00108 00109 /** Initialize the object after construction 00110 @param prefix Prefix to be prepended to all strings emitted by calls to 00111 debug(), verbose(), fatal() and possibly output(). 00112 NOTE: No space will be inserted between the prepended prefix 00113 string and the normal output string. 00114 Prefix can contain the following escape codes: 00115 - \@f Name of the file in which output call was made. 00116 - \@l Line number in the file in which output call was made. 00117 - \@p Name of the function from which output call was made. 00118 - \@r MPI rank of the calling process. Will be empty if 00119 MPI_COMM_WORLD size is 1. 00120 - \@R MPI rank of the calling process. Will be 0 if 00121 MPI_COMM_WORLD size is 1. 00122 - \@t Simulation time. Will be the raw simulaton cycle time 00123 retrieved from the SST Core. 00124 @param verbose_level Debugging output level. Calls to debug(), 00125 verbose() and fatal() are only output if their output_level 00126 parameter is less than or equal to the verbose_level currently 00127 set for the object 00128 @param verbose_mask Bitmask of allowed message types for debug(), 00129 verbose() and fatal(). The Output object will only output the 00130 message if the set bits of the output_bits parameter 00131 are set in the verbose_mask of the object. It uses this logic: 00132 if (~verbose_mask & output_bits == 0) then output is enabled. 00133 @param location Output location. Ouput will be directed to STDOUT, 00134 STDERR, FILE, or NONE. If FILE output is selected, the 00135 output will be directed to the file defined by the 00136 --debug runtime parameter, or to the file 'sst_output' if the 00137 --debug parameter is not defined. If the size of MPI_COMM_WORLD 00138 is > 1, then the rank process will be appended to the file name. 00139 @param localoutputfilename. Send the output of this class to the 00140 file identified in localoutputfilename instead of the of the 00141 normal output file set by the run time parameter --debug-file. 00142 location parameter must be set to FILE. This parameter is 00143 intended for special case debug purposes only. 00144 */ 00145 // INITIALIZATION 00146 void init(const std::string& prefix, uint32_t verbose_level, 00147 uint32_t verbose_mask, output_location_t location, 00148 std::string localoutputfilename = ""); 00149 00150 /** Output the message with formatting as specified by the format parameter. 00151 The output will be prepended with the expanded prefix set in the object. 00152 @param line Line number of calling function (use CALL_INFO macro) 00153 @param file File name calling function (use CALL_INFO macro) 00154 @param func Function name calling function (use CALL_INFO macro) 00155 @param format Format string. All valid formats for printf are available. 00156 @param ... Argument strings for format. 00157 */ 00158 void output(uint32_t line, const char* file, const char* func, 00159 const char* format, ...) const 00160 __attribute__ ((format (printf, 5, 6))) 00161 { 00162 va_list arg; 00163 if (true == m_objInitialized && NONE != m_targetLoc ) { 00164 // Get the argument list and then print it out 00165 va_start(arg, format); 00166 outputprintf(line, file, func, format, arg); 00167 va_end(arg); 00168 } 00169 } 00170 00171 /** Output the message with formatting as specified by the format parameter. 00172 @param format Format string. All valid formats for printf are available. 00173 @param ... Arguments for format. 00174 */ 00175 void output(const char* format, ...) const 00176 __attribute__ ((format (printf, 2, 3))) 00177 { 00178 va_list arg; 00179 if (true == m_objInitialized && NONE != m_targetLoc) { 00180 // Get the argument list and then print it out 00181 va_start(arg, format); 00182 outputprintf(format, arg); 00183 va_end(arg); 00184 } 00185 } 00186 00187 /** Output the verbose message with formatting as specified by the format 00188 parameter. Output will only occur if specified output_level and 00189 output_bits meet criteria defined by object. The output will be 00190 prepended with the expanded prefix set in the object. 00191 @param line Line number of calling function (use CALL_INFO macro) 00192 @param file File name calling function (use CALL_INFO macro) 00193 @param func Function name calling function (use CALL_INFO macro) 00194 @param output_level For output to occur, output_level must be less than 00195 or equal to verbose_level set in object 00196 @param output_bits The Output object will only output the 00197 message if the set bits of the output_bits parameter are set in 00198 the verbose_mask of the object. It uses this logic: 00199 if (~verbose_mask & output_bits == 0) then output is enabled. 00200 @param format Format string. All valid formats for printf are available. 00201 @param ... Arguments for format. 00202 */ 00203 void verbose(uint32_t line, const char* file, const char* func, 00204 uint32_t output_level, uint32_t output_bits, 00205 const char* format, ...) const 00206 __attribute__ ((format (printf, 7, 8))) 00207 { 00208 va_list arg; 00209 00210 if (true == m_objInitialized && NONE != m_targetLoc ) { 00211 // First check to see if we are allowed to send output based upon the 00212 // verbose_mask and verbose_level checks 00213 if (((output_bits & ~m_verboseMask) == 0) && 00214 (output_level <= m_verboseLevel)){ 00215 // Get the argument list and then print it out 00216 va_start(arg, format); 00217 outputprintf(line, file, func, format, arg); 00218 va_end(arg); 00219 } 00220 } 00221 } 00222 00223 /** Output the verbose message with formatting as specified by the format 00224 parameter. Output will only occur if specified output_level and 00225 output_bits meet criteria defined by object. The output will be 00226 prepended with the expanded prefix set in the object. 00227 @param tempPrefix For just this call use this prefix 00228 @param line Line number of calling function (use CALL_INFO macro) 00229 @param file File name calling function (use CALL_INFO macro) 00230 @param func Function name calling function (use CALL_INFO macro) 00231 @param output_level For output to occur, output_level must be less than 00232 or equal to verbose_level set in object 00233 @param output_bits The Output object will only output the 00234 message if the set bits of the output_bits parameter are set in 00235 the verbose_mask of the object. It uses this logic: 00236 if (~verbose_mask & output_bits == 0) then output is enabled. 00237 @param format Format string. All valid formats for printf are available. 00238 @param ... Arguments for format. 00239 */ 00240 void verbosePrefix(const char* tempPrefix, uint32_t line, const char* file, const char* func, 00241 uint32_t output_level, uint32_t output_bits, 00242 const char* format, ...) 00243 __attribute__ ((format (printf, 8, 9))) 00244 { 00245 00246 va_list arg; 00247 00248 if (true == m_objInitialized && NONE != m_targetLoc ) { 00249 const std::string normalPrefix = m_outputPrefix; 00250 m_outputPrefix = tempPrefix; 00251 00252 // First check to see if we are allowed to send output based upon the 00253 // verbose_mask and verbose_level checks 00254 if (((output_bits & ~m_verboseMask) == 0) && 00255 (output_level <= m_verboseLevel)){ 00256 // Get the argument list and then print it out 00257 va_start(arg, format); 00258 outputprintf(line, file, func, format, arg); 00259 va_end(arg); 00260 } 00261 00262 m_outputPrefix = normalPrefix; 00263 } 00264 } 00265 00266 /** Output the debug message with formatting as specified by the format 00267 parameter. Output will only occur if specified output_level and 00268 output_bits meet criteria defined by object. The output will be 00269 prepended with the expanded prefix set in the object. 00270 NOTE: Debug ouputs will only occur if the __SST_DEBUG_OUTPUT__ is defined. 00271 this define can be set in source code or by setting the 00272 --enable-debug option during SST configuration. 00273 @param line Line number of calling function (use CALL_INFO macro) 00274 @param file File name calling function (use CALL_INFO macro) 00275 @param func Function name calling function (use CALL_INFO macro) 00276 @param output_level For output to occur, output_level must be less than 00277 or equal to verbose_level set in object 00278 @param output_bits The Output object will only output the 00279 message if the set bits of the output_bits parameter are set in 00280 the verbose_mask of the object. It uses this logic: 00281 if (~verbose_mask & output_bits == 0) then output is enabled. 00282 @param format Format string. All valid formats for printf are available. 00283 @param ... Arguments for format. 00284 */ 00285 void debug(uint32_t line, const char* file, const char* func, 00286 uint32_t output_level, uint32_t output_bits, 00287 const char* format, ...) const 00288 __attribute__ ((format (printf, 7, 8))) 00289 { 00290 #ifdef __SST_DEBUG_OUTPUT__ 00291 va_list arg; 00292 if (true == m_objInitialized && NONE != m_targetLoc ) { 00293 // First check to see if we are allowed to send output based upon the 00294 // verbose_mask and verbose_level checks 00295 if (((output_bits & ~m_verboseMask) == 0) && 00296 (output_level <= m_verboseLevel)){ 00297 // Get the argument list and then print it out 00298 va_start(arg, format); 00299 outputprintf(line, file, func, format, arg); 00300 va_end(arg); 00301 } 00302 } 00303 #endif 00304 } 00305 00306 00307 /** Output the fatal message with formatting as specified by the format 00308 parameter. Message will be sent to the output location and to stderr. 00309 The output will be prepended with the expanded prefix set 00310 in the object. 00311 NOTE: fatal() will call MPI_Abort(exit_code) to terminate simulation. 00312 @param line Line number of calling function (use CALL_INFO macro) 00313 @param file File name calling function (use CALL_INFO macro) 00314 @param func Function name calling function (use CALL_INFO macro) 00315 @param exit_code The exit code used for termination of simuation. 00316 will be passed to MPI_Abort() 00317 @param format Format string. All valid formats for printf are available. 00318 @param ... Arguments for format. 00319 */ 00320 void fatal(uint32_t line, const char* file, const char* func, 00321 uint32_t exit_code, 00322 const char* format, ...) const 00323 __attribute__ ((format (printf, 6, 7))) ; 00324 00325 // GET / SET METHODS 00326 00327 /** Sets object prefix 00328 @param prefix Prefix to be prepended to all strings emitted by calls to 00329 debug(), verbose(), fatal() and possibly output(). 00330 NOTE: No space will be inserted between the prepended prefix 00331 string and the normal output string. 00332 Prefix can contain the following escape codes: 00333 - \@f Name of the file in which output call was made. 00334 - \@l Line number in the file in which output call was made. 00335 - \@p Name of the function from which output call was made. 00336 - \@r MPI rank of the calling process. Will be empty if 00337 MPI_COMM_WORLD size is 1. 00338 - \@R MPI rank of the calling process. Will be 0 if 00339 MPI_COMM_WORLD size is 1. 00340 - \@t Simulation time. Will be the raw simulaton cycle time 00341 retrieved from the SST Core. 00342 */ 00343 void setPrefix(const std::string& prefix); 00344 00345 /** Returns object prefix */ 00346 std::string getPrefix() const; 00347 00348 /** Sets object verbose mask 00349 @param verbose_mask Bitmask of allowed message types for debug(), 00350 verbose() and fatal(). The Output object will only output the 00351 message if the set bits of the output_bits parameter 00352 are set in the verbose_mask of the object. It uses this logic: 00353 if (~verbose_mask & output_bits == 0) then output is enabled. 00354 */ 00355 void setVerboseMask(uint32_t verbose_mask); 00356 00357 /** Returns object verbose mask */ 00358 uint32_t getVerboseMask() const; 00359 00360 /** Sets object verbose level 00361 @param verbose_level Debugging output level. Calls to debug(), 00362 verbose() and fatal() are only output if their output_level 00363 parameter is less than or equal to the verbose_level currently 00364 set for the object 00365 */ 00366 void setVerboseLevel(uint32_t verbose_level); 00367 00368 /** Returns object verbose level */ 00369 uint32_t getVerboseLevel() const; 00370 00371 /** Sets object output location 00372 @param location Output location. Ouput will be directed to STDOUT, 00373 STDERR, FILE, or NONE. If FILE output is selected, the 00374 output will be directed to the file defined by the 00375 --debug runtime parameter, or to the file 'sst_output' if the 00376 --debug parameter is not defined. If the size of MPI_COMM_WORLD 00377 is > 1, then the rank process will be appended to the file name. 00378 */ 00379 void setOutputLocation(output_location_t location); 00380 00381 /** Returns object output location */ 00382 output_location_t getOutputLocation() const; 00383 00384 /** This method allows for the manual flushing of the output. */ 00385 inline void flush() const {std::fflush(*m_targetOutputRef);} 00386 00387 00388 /** This method sets the static filename used by SST. It can only be called 00389 once, and is automatically called by the SST Core. No components should 00390 call this method. 00391 */ 00392 static void setFileName(const std::string& filename); 00393 00394 private: 00395 // Support Methods 00396 void setTargetOutput(output_location_t location); 00397 void openSSTTargetFile() const; 00398 void closeSSTTargetFile(); 00399 // std::string getMPIProcName() const; 00400 int getMPIWorldRank() const; 00401 int getMPIWorldSize() const; 00402 std::string buildPrefixString(uint32_t line, 00403 const std::string& file, 00404 const std::string& func) const; 00405 void outputprintf(uint32_t line, 00406 const std::string &file, 00407 const std::string &func, 00408 const char *format, 00409 va_list arg) const; 00410 void outputprintf(const char *format, va_list arg) const; 00411 00412 // Internal Member Variables 00413 bool m_objInitialized; 00414 std::string m_outputPrefix; 00415 uint32_t m_verboseLevel; 00416 uint32_t m_verboseMask; 00417 output_location_t m_targetLoc; 00418 00419 // m_targetOutputRef is a pointer to a FILE* object. This is because 00420 // the actual FILE* object (m_sstFileHandle) is not created on construction, 00421 // but during the first call any of output(), verbose() or debug() methods. 00422 // m_targetOutputRef points to either &m_sstFileHandle, &stdout, or &stderr 00423 // depending upon constructor for the object. However m_sstFileHandle is a 00424 // static variable that is set by the startup of SST, and the location 00425 // cannot be changed in the constructor or a call to setFileName(). 00426 std::FILE** m_targetOutputRef; 00427 00428 // m_targetFileHandleRef, m_targetFileNameRef, and m_targetFileAccessCount 00429 // are pointers to their assocted types. These point to either the local 00430 // output file information or to the global simulation output file information. 00431 std::FILE** m_targetFileHandleRef; 00432 std::string* m_targetFileNameRef; 00433 uint32_t* m_targetFileAccessCountRef; 00434 00435 // Static Member Variables regarding the Global simulation file info 00436 static std::string m_sstGlobalSimFileName; 00437 static std::FILE* m_sstGlobalSimFileHandle; 00438 static uint32_t m_sstGlobalSimFileAccessCount; 00439 00440 // File Member Variables regarding the local simulation file info 00441 std::string m_sstLocalFileName; 00442 std::FILE* m_sstLocalFileHandle; 00443 uint32_t m_sstLocalFileAccessCount; 00444 00445 // Serialization Methods 00446 friend class boost::serialization::access; 00447 template<class Archive> void serialize(Archive & ar, const unsigned int version); 00448 }; 00449 00450 } // namespace SST 00451 00452 BOOST_CLASS_EXPORT_KEY(SST::Output) 00453 00454 #endif // SST_CORE_OUTPUT_H