Sierra Toolkit Version of the Day
Runtime Message Reporting, Warnings and Dooms (Errors)

Runtime messages are warning and errors which may occur in parallel that need to be reported to the anaylst which may need to be collected to a root processor and written with greater emphasis than regular output. More...

Collaboration diagram for Runtime Message Reporting, Warnings and Dooms (Errors):

Runtime messages are warning and errors which may occur in parallel that need to be reported to the anaylst which may need to be collected to a root processor and written with greater emphasis than regular output.

Parallel system architectures greatly complicate the reporting of warning and fatal error messages. To simplify this, messages are categorized by their generation mechanism. Some messages are generated symmetrically, meaning that all processors contain the exact same information and the root processor may simply write it's message to the log file and the remaining may simple ignore it. Some messages are generated in an ad hoc manner, meaning that some processors may generate them at any time, and the output can simply be collected to the root processor at a later time and reported. And some are generated by several processors with related information and deferred until they should be aggregated to the root processor written as an assembled condensed message.

The message is displayed prominently by the report_handler() via the report() function. Each application registers a report_handler with the set_report_handler() function. The report() accepts two arguments, the message string and a message type. The message types MSG_WARNING, MSG_ERROR, MSG_INFORMATION and MSG_EXCEPTION are currently defined as well as two type flags, MSG_SYMMETRIC and MSG_DEFERRED. These flags indicate the category of the message. Generally, symmetric messages are written to the output log by the root processor and to the per-processor log by the remaining processors, see Symmetric Messages. Ad hoc message are collected at a parallel safe time and written to the output log by the root processor, see Ad hoc Messages. And, deferred message are written immediately to per-processors log and aggregated to the root processors at a parallel safe time, see Deferred Messages.

The messages are counted by the underlying message reporting functions and are limited by message code and content and message occurance type.

Message Throttling and Counting

The messages of each type are counted. Once the display count for a particular message has been exceeded, that message will no longer be displayed. However, it continues to be counted. Deferred messages are counted once for each aggregated message.

By constructing a static MessageCode object, you can throttle the display of messages. These must be static objects for the counting to function properly. See MessageCode::MessageCode MessageCode for details. When constructed, a max display count and a display group may be provided. The count limits the number of times that the message is displayed. Once this count has been exceeded, the message is no longer displayed. The group may be MSG_APPLICATION or MSG_TIME_STEP. The display count for each group may be reset so allow messages to be display for each time step, for instance, even if exceeded by the previous time step.

The functions get_message_count(), get_warning_count() and get_doomed_count() return the current accumulated counts. The root processor has the official count. Other processors counts may be different.

The maximum number of messages to be displayed during the execution of an application can be set using the set_max_message_count(), set_max_warning_count() and set_max_doomed_count() functions.

It may be important to count message during various points in the programs execution. So, to reset the counts back to zero, use the reset_message_count(), reset_warning_count() and reset_doomed_count() functions.

For example:

     if (symmetric_handler_doomed_condition) { // limited to 5 fatal error messages
         static MessageCode message_code(5);
         RuntimeDoomedSymmetric(message_code) << "My useful message about " << some_data;
     }

     if (symmetric_runtime_warning_condition) { // Limited to 5 warning messages on each time step
         static MessageCode message_code(5, stk::MSG_TIME_STEP);
      RuntimeWarningSymmetric(message_code) << "My useful message about " << some_data;
     }

Symmetric Messages

Since these messages are generated symmetrically across all processors, only the root processor needs to send the output to the log. A message generated exclusively on the roor processor could also be written symmetrically as this just relieves the other processors from ignoring the message. These message often occur during input deck parsing and initialization. These messages are counted and throttled on all processors, but have the same throttle count on all processors. The functions report_message(), report_symmetric_warning() and report_symmetric_doomed() send a message string and message type to the report() function.

The sentry classes RuntimeWarningSymmetric and RuntimeDoomedSymmetric may be used to simplify the coding of the messages.

For example:

     if (symmetric_runtime_warning_condition) // Unlimited warning output
      RuntimeWarningSymmetric() << "My useful message about " << some_data;

     if (symmetric_runtime_doomed_condition) // Unlimited doomed output
      RuntimeDoomedSymmetric() << "My useful message about " << some_data;

     if (root_processor_runtime_warning_condition) // Unlimited warning output
      RuntimeWarningSymmetric() << "My useful message about " << some_data;

     if (symmetric_handler_doomed_condition) { // limited to 5 fatal error messages
         static MessageCode message_code(5);
         RuntimeDoomedSymmetric(message_code) << "My useful message about " << some_data;
     }

     if (symmetric_runtime_warning_condition) { // Limited to 5 warning messages on each time step
         static MessageCode message_code(5, stk::MSG_TIME_STEP);
      RuntimeWarningSymmetric(message_code) << "My useful message about " << some_data;
     }

Ad hoc Messages

Deprecated. Use deferred warnings and dooms.

This is the old style message collection technique. Since the messages are not generated in a parallel safe environment, they are buffered into a seperate output stream that is aggregated and written when the main output stream is flushed at a parallel safe time. These message are counted and throttles on each processor and therefore throttled on a per-processor basis.

The sentry classes RuntimeWarningAdHoc and RuntimeDoomedAdHoc may be used to simplify the coding of the messages.

For example (deprecated):

     if (runtime_warning_condition) // Unlimited warning output
      RuntimeWarning() << "My useful message about " << some_data;

     if (runtime_doomed_condition) // Unlimited doomed output
      RuntimeDoomed() << "My useful message about " << some_data;

     if (root_processor_runtime_warning_condition) // Unlimited warning output
      RuntimeWarning() << "My useful message about " << some_data;

     if (handler_doomed_condition) { // limited to 5 fatal error messages on this processor
         static MessageCode message_code(5);
         RuntimeDoomed(message_code) << "My useful message about " << some_data;
     }

     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step on this processor
         static MessageCode message_code(5, stk::MSG_TIME_STEP);
      RuntimeWarning(message_code) << "My useful message about " << some_data;
     }

Deferred Messages

This is the new style of message collection. These messages are also not generated in a parallel safe environment but are buffered to the deferred message queue. When the main output stream is flushed at a parallel safe time, the messages are collected to the root processor and aggregated by message id and message content. All messages which are aggregated are counted as singly and reported in the aggregated form.

For deferred messages, the message is keyed by the message code and the non-aggregate message content. This allows additional aggregation possibilities.

The sentry classes RuntimeWarningDeferred and RuntimeDoomedDeferred may be used to simplify the coding of the messages.

For example:

     if (handler_doomed_condition) { // limited to 5 fatal error messages
         static MessageCode message_code(5);
         RuntimeDoomedDeferred(message_code) << "My useful message about " << some_data;
     }

     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step
         static MessageCode message_code(5, stk::MSG_TIME_STEP);
      RuntimeWarningDeferred(message_code) << "My useful message about " << some_data;
     }

     if (handler_doomed_condition) { // limited to 5 fatal error messages
         static MessageCode message_code(5);
         RuntimeDoomedDeferred x(message_code);
         x << "My useful message about " << some_data;
         x.aggregate << "my proc info";
     }

     if (runtime_warning_condition) { // Limited to 5 warning messages on each time step
         static MessageCode message_code(5, stk::MSG_TIME_STEP);
      RuntimeWarningDeferred x(message_code);
         x << "My useful message about " << some_data;
         x.aggregate << "my proc info";
     }

Message Assembly

Messages are generally assembled into a string output stream and this string is reported via the report() mechanism. You may select to use a variety of interfaces to accomplish this.

The lowest level functions are the report_warning(), report_symmetric_warning() and report_deferred_warning() functions. These functions are counted by message code and write the message based on the category, ad hoc, symmetric or deferred.

There are three convenience classes that make the assembly easier for a developer to identify and simpler to code. The RuntimeWarning, RuntimeWarningSymmetric and RuntimeWarningDeferred sentry classes are constructed with an optional message code, accept additional data via the put-to (<<) operator and report the message upon destruction. All of these classes present the output string stream as the public member variable 'message'. And, the RuntimeWarningDeferred class presents the 'aggregate' public member variable to be written to with aggregation text.

For example:

     if (runtime_doomed_condition) // Unlimited fatal error output
      RuntimeDoomedSymmetric() << "My useful message about " << some_data << " and will die soon";

     if (runtime_doomed_condition) { // Unlimited fatal error output
      RuntimeDoomedSymmetric x;
         x << "My useful message about " << some_data << " and will die soon";
         for (int i = 0; i < 10; ++i)
           x << " " << i;
     }

     if (runtime_doomed_condition) { // Unlimited fatal error output
      RuntimeDoomedSymmetric x;
         x.message << "My useful message about " << some_data << " and will die soon";
         for (int i = 0; i < 10; ++i)
           x.message << " " << i;
     }

     if (runtime_doomed_condition) { // Unlimited fatal error output
      std::ostringstream s;
         x << "My useful message about " << some_data << " and will die soon";
         stk::report_symmetic_warning(s.str());
     }

Message Reporting

The report functions send the assembled message string and message type to the registered report_handler() function. The report handler function has the signature:

     report_handler(const char *message, int type)

and is set with set_report_handler().

If you want special decorations around your messages during execution, you can change the reporter.

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends