14 #include <boost/unordered_map.hpp> 17 #include <stk_util/environment/ReportHandler.hpp> 18 #include <stk_util/util/Bootstrap.hpp> 19 #include <stk_util/util/Marshal.hpp> 38 typedef std::pair<MessageId, std::string> MessageKey;
40 typedef boost::unordered_map<MessageKey, Throttle> MessageIdMap;
42 MessageIdMap s_messageIdMap;
44 MessageIdMap s_deferredMessageIdMap;
46 struct DeferredMessage
54 size_t throttle_cutoff,
56 const std::string & header,
57 const std::string & aggregate)
59 m_messageId(message_id),
61 m_throttleCutoff(throttle_cutoff),
62 m_throttleGroup(throttle_group),
64 m_aggregate(aggregate)
70 size_t m_throttleCutoff;
73 std::string m_aggregate;
76 typedef std::vector<DeferredMessage> DeferredMessageVector;
78 struct DeferredMessageLess :
public std::binary_function<DeferredMessage, DeferredMessage, bool>
80 bool operator()(
const DeferredMessage &key_1,
const DeferredMessage &key_2)
const {
81 return (key_1.m_type < key_2.m_type)
82 || (!(key_2.m_type < key_1.m_type) && key_1.m_messageId < key_2.m_messageId)
83 || (!(key_2.m_type < key_1.m_type) && !(key_2.m_messageId < key_1.m_messageId) && key_1.m_header < key_2.m_header);
87 DeferredMessageVector s_deferredMessageVector;
89 struct MessageTypeInfo
102 typedef boost::unordered_map<unsigned, MessageTypeInfo> MessageTypeInfoMap;
104 MessageTypeInfoMap s_messageTypeInfo;
107 get_message_type_info(
110 MessageTypeInfoMap::iterator it = s_messageTypeInfo.find(type &
MSG_TYPE_MASK);
111 if (it != s_messageTypeInfo.end())
121 MSG_CUTOFF_EXCEEDED = 2
128 const char * message,
129 const Throttle & throttle)
131 std::pair<MessageIdMap::iterator, bool> res = s_messageIdMap.insert(MessageIdMap::value_type(MessageIdMap::key_type(message_id, message), throttle));
132 size_t count = ++(*res.first).second.m_count;
134 if (count < (*res.first).second.m_cutoff)
136 else if (count == (*res.first).second.m_cutoff)
139 return MSG_CUTOFF_EXCEEDED;
142 Marshal &
operator<<(Marshal &mout,
const DeferredMessage &s) {
143 mout << s.m_type << s.m_messageId << s.m_rank << s.m_throttleGroup << s.m_throttleCutoff << s.m_header << s.m_aggregate;
147 Marshal &operator>>(Marshal &min, DeferredMessage &s) {
148 min >> s.m_type >> s.m_messageId >> s.m_rank >> s.m_throttleGroup >> s.m_throttleCutoff >> s.m_header >> s.m_aggregate;
157 unsigned message_type,
161 MessageTypeInfo &message_info = get_message_type_info(message_type);
163 message_info.m_maxCount = max_count;
164 message_info.m_name = name;
170 unsigned message_type)
172 return get_message_type_info(message_type).m_count;
177 increment_message_count(
178 unsigned message_type)
180 return ++get_message_type_info(message_type).m_count;
186 unsigned message_type)
188 get_message_type_info(message_type).m_count = 0;
194 unsigned message_type)
196 return get_message_type_info(message_type).m_name;
202 unsigned message_type,
205 get_message_type_info(message_type).m_maxCount = max_count;
211 unsigned message_type)
213 return get_message_type_info(message_type).m_maxCount;
219 const char * message,
220 unsigned message_type,
224 report(message, message_type);
227 unsigned count = increment_message_count(message_type);
230 if (count == max_count) {
231 report(message, message_type);
233 std::ostringstream s;
234 s <<
"Maximum " <<
get_message_name(message_type) <<
" count has been exceeded and will no longer be displayed";
238 else if (count < max_count) {
239 CutoffStatus cutoff = count_message(message_code.
m_id,
"", message_code.
m_throttle);
241 if (cutoff == MSG_CUTOFF) {
242 report(message, message_type);
244 std::ostringstream s;
245 s <<
"Maximum count for this " <<
get_message_name(message_type) <<
" has been exceeded and will no longer be displayed";
249 else if (cutoff == MSG_DISPLAY)
250 report(message, message_type);
260 for (MessageIdMap::iterator it = s_messageIdMap.begin(); it != s_messageIdMap.end(); ++it)
261 if ((*it).second.m_group == throttle_group)
262 (*it).second.m_count = 0;
270 size_t throttle_cutoff,
273 const char * aggegrate)
275 std::ostringstream s;
276 s << header <<
" " << aggegrate;
280 std::pair<MessageIdMap::iterator, bool> res = s_deferredMessageIdMap.insert(MessageIdMap::value_type(MessageIdMap::key_type(message_id, header),
Throttle(throttle_cutoff, throttle_group)));
281 size_t count = ++(*res.first).second.m_count;
283 if (count <= throttle_cutoff)
284 s_deferredMessageVector.push_back(DeferredMessage(message_type, message_id, throttle_cutoff, throttle_group, header, aggegrate));
295 const int p_root = 0 ;
299 for (DeferredMessageVector::iterator it = s_deferredMessageVector.begin(); it != s_deferredMessageVector.end(); ++it)
300 (*it).m_rank = p_rank;
303 mout << s_deferredMessageVector;
305 DeferredMessageVector deferred_message_vector;
308 std::string send_string(mout.stream.str());
309 int send_count = send_string.
size();
310 std::vector<int> recv_count(p_size, 0);
311 int *
const recv_count_ptr = &recv_count[0] ;
313 int result = MPI_Gather(&send_count, 1, MPI_INT,
314 recv_count_ptr, 1, MPI_INT,
316 if (MPI_SUCCESS != result) {
317 std::ostringstream message ;
318 message <<
"stk_classic::report_deferred_messages FAILED: MPI_Gather = " << result ;
319 throw std::runtime_error(message.str());
323 std::vector<int> recv_displ(p_size + 1, 0);
325 for (
int i = 0 ; i < p_size ; ++i) {
326 recv_displ[i + 1] = recv_displ[i] + recv_count[i] ;
329 const int recv_size = recv_displ[p_size] ;
331 std::vector<char> buffer(recv_size);
334 const char *
const send_ptr = send_string.data();
335 char *
const recv_ptr = recv_size ? & buffer[0] : (
char *) NULL ;
336 int *
const recv_displ_ptr = & recv_displ[0] ;
338 result = MPI_Gatherv((
void *) send_ptr, send_count, MPI_CHAR,
339 recv_ptr, recv_count_ptr, recv_displ_ptr, MPI_CHAR,
341 if (MPI_SUCCESS != result) {
342 std::ostringstream message ;
343 message <<
"stk_classic::report_deferred_messages FAILED: MPI_Gatherv = " << result ;
344 throw std::runtime_error(message.str());
348 if (p_rank == p_root) {
349 for (
int i = 0; i < p_size; ++i) {
350 Marshal min(std::string(recv_ptr + recv_displ[i], recv_ptr + recv_displ[i + 1]));
351 min >> deferred_message_vector;
354 std::stable_sort(deferred_message_vector.begin(), deferred_message_vector.end(), DeferredMessageLess());
356 DeferredMessageVector::const_iterator current_message_it = deferred_message_vector.begin();
357 while (current_message_it != deferred_message_vector.end()) {
358 const DeferredMessage ¤t_message = (*current_message_it);
360 DeferredMessageVector::const_iterator end = current_message_it + 1;
361 while (end != deferred_message_vector.end()
362 && current_message.m_messageId == (*end).m_messageId
363 && current_message.m_header == (*end).m_header)
366 std::ostringstream s;
368 s << current_message.m_header << current_message.m_aggregate;
370 for (DeferredMessageVector::const_iterator it1 = current_message_it + 1; it1 != end; ++it1) {
372 for (DeferredMessageVector::const_iterator it2 = current_message_it; it2 != it1; ++it2)
373 if ((*it1).m_aggregate == (*it2).m_aggregate) {
378 if (!(*it1).m_aggregate.find(
'\n'))
380 s << (*it1).m_aggregate;
386 current_message_it = end;
391 s_deferredMessageIdMap.clear();
392 s_deferredMessageVector.clear();
400 std::ostringstream & os,
401 const char * separator)
404 std::string message = os.str();
407 const int p_root = 0 ;
415 int send_count = message.size();
417 std::vector<int> recv_count(p_size, 0);
419 int *
const recv_count_ptr = & recv_count[0] ;
421 result = MPI_Gather(& send_count, 1, MPI_INT,
422 recv_count_ptr, 1, MPI_INT,
425 if (MPI_SUCCESS != result) {
426 std::ostringstream s;
427 s <<
"stk_classic::all_write FAILED: MPI_Gather = " << result ;
428 throw std::runtime_error(s.str());
432 std::vector<int> recv_displ(p_size + 1, 0);
434 for (
int i = 0 ; i < p_size ; ++i) {
435 recv_displ[i + 1] = recv_displ[i] + recv_count[i] ;
438 const int recv_size = recv_displ[ p_size ] ;
440 std::vector<char> buffer(recv_size);
443 const char *
const send_ptr = message.c_str();
444 char *
const recv_ptr = recv_size ? & buffer[0] : (
char *) NULL ;
445 int *
const recv_displ_ptr = & recv_displ[0] ;
447 result = MPI_Gatherv((
void*) send_ptr, send_count, MPI_CHAR,
448 recv_ptr, recv_count_ptr, recv_displ_ptr, MPI_CHAR,
452 if (MPI_SUCCESS != result) {
453 std::ostringstream s ;
454 s <<
"stk_classic::all_write FAILED: MPI_Gatherv = " << result ;
455 throw std::runtime_error(s.str());
458 if (p_root == (
int) p_rank) {
460 for (
int i = 0 ; i < p_size ; ++i) {
465 char *
const ptr = & buffer[ recv_displ[i] ];
466 os.write(ptr, recv_count[i]);
484 os << get_message_type_info(message_type).m_name;
std::ostream & print(std::ostream &os, const std::string &indent, const Bucket &bucket)
Print the parts and entities of this bucket.
void add_deferred_message(int message_type, MessageId message_id, size_t throttle_cutoff, int throttle_group, const char *header, const char *aggegrate)
Function add_deferred_message adds a message to the deferred message queue.
MessageType
Enumeration MessageType declares the global message types.
Message is informational.
ptrdiff_t MessageId
Typedef MessageId defines a message identifier.
size_t size() const
Member function size returns the byte count of the string of packed bytes creates by put-to operation...
void reset_message_count(unsigned message_type)
Member function reset_message_count ...
void report(const char *message, int type)
Function report calls the current exception reporter to report the message in x.
void register_message_type(unsigned message_type, unsigned max_count, const char *name)
Member function set_message_name ...
Class MessageCode declares a message identifier and throttle characteristics for a message...
Throttle m_throttle
Throttle characteristics.
Class Throttle describes the cutoff limits for a message throttle.
Struct Marshal is a data packer for sending and receiving parallel messages. The data put-to (<<) is ...
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
const std::string & get_message_name(unsigned message_type)
Member function get_message_name ...
std::ostream & operator<<(std::ostream &s, const Bucket &k)
Print the part names for which this bucket is a subset.
unsigned get_max_message_count(unsigned message_type)
Member function get_max_message_count ...
void report_message(const char *message, unsigned message_type, const MessageCode &message_code)
Member function report_message ...
unsigned get_message_count(unsigned message_type)
Member function get_message_count ...
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Message is a fatal error.
void set_max_message_count(unsigned message_type, unsigned max_count)
Member function set_max_message_count ...
void reset_throttle_group(int throttle_group)
Function reset_message_group sets the count to zero of all messages in the specified throttle group...
Class Bootstrap serves as a bootstrapping mechanism for products in the sierra toolkit and elsewhere...
MessageId m_id
Message identifier.
void report_deferred_messages(ParallelMachine comm)
Function report_deferred_messages aggregates and reports the message on the root processor.
static MessageCode s_defaultMessageCode
Default message code.
void aggregate_messages(ParallelMachine comm, std::ostringstream &os, const char *separator)
Function aggregate_messages writes a message message to the output string by joining the messages fro...
eastl::iterator_traits< InputIterator >::difference_type count(InputIterator first, InputIterator last, const T &value)