12 #include <stk_util/diag/Writer.hpp>
13 #include <stk_util/diag/PrintTimer.hpp>
15 #include <stk_util/util/Bootstrap.hpp>
16 #include <stk_util/util/IndentStreambuf.hpp>
18 #include <stk_util/parallel/ParallelReduce.hpp>
20 #include <stk_util/use_cases/UseCaseEnvironment.hpp>
24 namespace bopt = boost::program_options;
27 typedef unsigned long OptionMask;
37 OptionMaskName(
const std::string &name,
const OptionMask &mask,
const std::string &description =
"No description available")
40 m_description(description)
43 virtual ~OptionMaskName()
48 std::string m_description;
52 class OptionMaskNameMap:
public std::map<std::string, OptionMaskName>
55 void mask(
const std::string &name,
const OptionMask mask,
const std::string &description) {
56 iterator it =
find(name);
58 insert(std::make_pair(name, OptionMaskName(name, mask, description)));
60 (*it).second.m_mask = mask;
61 (*it).second.m_description = description;
66 class OptionMaskParser
69 typedef OptionMask Mask;
76 OptionMaskParser(
const std::string &description)
77 : m_optionMaskNameMap(),
78 m_description(description),
83 virtual ~OptionMaskParser()
86 Mask parse(
const char *mask)
const;
88 virtual void parseArg(
const std::string &name)
const;
90 std::string describe()
const {
91 std::ostringstream strout;
92 strout << m_description << std::endl;
93 for (OptionMaskNameMap::const_iterator it = m_optionMaskNameMap.begin(); it != m_optionMaskNameMap.end(); ++it)
94 strout <<
" " << (*it).first <<
std::setw(14 - (*it).first.size()) <<
" " << (*it).second.m_description << std::endl;
98 void mask(
const std::string &name,
const Mask mask,
const std::string &description) {
99 m_optionMaskNameMap.mask(name, mask, description);
103 OptionMaskNameMap m_optionMaskNameMap;
104 std::string m_description;
105 mutable OptionMask m_optionMask;
106 mutable bool m_status;
110 OptionMaskParser::Mask
111 OptionMaskParser::parse(
112 const char * mask)
const
115 const std::string mask_string(mask);
119 std::string::const_iterator it0 = mask_string.begin();
120 std::string::const_iterator it1;
121 std::string::const_iterator it2;
122 std::string::const_iterator it3;
125 while (it0 != mask_string.end() && *it0 ==
' ')
128 if (it0 == mask_string.end())
131 for (it1 = it0; it1 != mask_string.end(); ++it1) {
132 if (*it1 ==
'(' || *it1 ==
':' || *it1 ==
',')
138 while (it2 != it0 && *(it2 - 1) ==
' ')
141 std::string name(it0, it2);
148 while (it2 != mask_string.end() && *it2 ==
' ')
153 for (; it1 != mask_string.end(); ++it1) {
156 else if (*it1 ==
')') {
158 if (paren_count == 0)
165 while (it3 != it2 && *(it3 - 1) ==
' ')
169 for (; it1 != mask_string.end(); ++it1)
170 if (*it1 ==
':' || *it1 ==
',')
176 const std::string arg(it2, it3);
181 }
while (it1 != mask_string.end());
189 OptionMaskParser::parseArg(
190 const std::string & name)
const
192 OptionMaskNameMap::const_iterator mask_entry = m_optionMaskNameMap.find(name);
194 if (mask_entry != m_optionMaskNameMap.end()) m_optionMask |= (*mask_entry).second.m_mask;
197 std::istringstream mask_hex_stream(name.c_str());
199 m_optionMask |= mask_hex;
207 build_log_description(
208 const bopt::variables_map & vm,
213 std::ostringstream output_description;
221 std::string out_path =
"-";
222 if (vm.count(
"output-log"))
223 out_path = vm[
"output-log"].as<std::string>();
227 std::string out_ostream;
230 if (out_path.size() && out_path[0] !=
'/')
235 output_description <<
"outfile=\"" << out_path <<
"\"";
236 out_ostream =
"outfile";
239 out_ostream = out_path;
242 out_ostream =
"null";
244 std::string pout_ostream =
"null";
245 if (vm.count(
"pout")) {
246 std::string pout_path = vm[
"pout"].as<std::string>();
247 if (pout_path ==
"-") {
248 std::ostringstream s;
257 std::ostringstream s;
264 output_description <<
" poutfile=\"" << pout_path <<
"\"";
265 pout_ostream =
"poutfile";
268 pout_ostream = pout_path;
271 std::string dout_ostream;
272 if (vm.count(
"dout")) {
273 std::string dout_path = vm[
"dout"].as<std::string>();
275 dout_ostream = dout_path;
277 std::ostringstream s;
278 if (dout_path.size() && dout_path[0] !=
'/')
283 output_description <<
" doutfile=\"" << dout_path <<
"\"";
284 dout_ostream =
"doutfile";
288 dout_ostream =
"out";
291 output_description <<
" out>" << out_ostream <<
"+pout";
293 output_description <<
" out>pout";
295 output_description <<
" pout>" << pout_ostream <<
" dout>" << dout_ostream;
297 return output_description.str();
300 OptionMaskParser dw_option_mask(
"use case diagnostic writer");
301 OptionMaskParser timer_option_mask(
"use case timers");
308 dw_option_mask.mask(
"search", use_case::LOG_SEARCH,
"log search diagnostics");
309 dw_option_mask.mask(
"transfer", use_case::LOG_TRANSFER,
"log transfer diagnostics");
310 dw_option_mask.mask(
"timer", use_case::LOG_TIMER,
"log timer diagnostics");
312 timer_option_mask.mask(
"mesh", use_case::TIMER_MESH,
"mesh operations timers");
313 timer_option_mask.mask(
"meshio", use_case::TIMER_MESH_IO,
"mesh I/O timers");
314 timer_option_mask.mask(
"transfer", use_case::TIMER_TRANSFER,
"transfer timers");
315 timer_option_mask.mask(
"search", use_case::TIMER_SEARCH,
"search timers");
317 boost::program_options::options_description desc(
"Use case environment options");
319 (
"help,h",
"produce help message")
320 (
"directory,d", boost::program_options::value<std::string>(),
"working directory")
321 (
"output-log,o", boost::program_options::value<std::string>(),
"output log path")
322 (
"pout", boost::program_options::value<std::string>()->implicit_value(
"-"),
"per-processor log file path")
323 (
"dout", boost::program_options::value<std::string>()->implicit_value(
"out"),
"diagnostic output stream one of: 'cout', 'cerr', 'out' or a file path")
324 (
"dw", boost::program_options::value<std::string>(), dw_option_mask.describe().c_str())
325 (
"timer", boost::program_options::value<std::string>(), timer_option_mask.describe().c_str())
326 (
"runtest,r", boost::program_options::value<std::string>(),
"runtest pid file");
340 static std::ostream s_out(std::cout.rdbuf());
348 static std::ostream s_pout(std::cout.rdbuf());
356 static std::ostream s_dout(std::cout.rdbuf());
364 static std::ostream s_tout(std::cout.rdbuf());
373 static std::ostream s_dwout(&s_dwoutStreambuf);
408 case MSG_PARALLEL_EXCEPTION:
409 os <<
"Parallel exception";
418 const char * message,
422 pout() <<
"Deferred " << (message_type) type <<
": " << message << std::endl;
425 out() << (message_type) type <<
": " << message << std::endl;
446 UseCaseEnvironment::UseCaseEnvironment(
450 m_need_to_finalize(true)
452 initialize(argc, argv);
455 UseCaseEnvironment::UseCaseEnvironment(
460 m_need_to_finalize(false)
462 initialize(argc, argv);
465 void UseCaseEnvironment::initialize(
int* argc,
char*** argv)
475 static_cast<stk_classic::indent_streambuf *>(
dwout().rdbuf())->redirect(
dout().rdbuf());
481 for (
int i = 0; i < *argc; ++i) {
482 const std::string s((*argv)[i]);
483 if (s ==
"-h" || s ==
"-help" || s ==
"--help") {
484 std::cout <<
"Usage: " << (*argv)[0] <<
" [options...]" << std::endl;
502 catch (std::exception &x) {
508 dw().
setPrintMask(dw_option_mask.parse(vm[
"dw"].as<std::string>().c_str()));
511 stk_classic::diag::setEnabledTimerMetricsMask(stk_classic::diag::METRICS_CPU_TIME | stk_classic::diag::METRICS_WALL_TIME);
512 if (vm.count(
"timer"))
513 timerSet().
setEnabledTimerMask(timer_option_mask.parse(vm[
"timer"].as<std::string>().c_str()));
516 m_workingDirectory =
"./";
517 if (vm.count(
"directory"))
518 m_workingDirectory = vm[
"directory"].as<std::string>();
519 if (m_workingDirectory.length() && m_workingDirectory[m_workingDirectory.length() - 1] !=
'/')
520 m_workingDirectory +=
"/";
526 dout() <<
"Output log binding: " << output_description << std::endl;
532 UseCaseEnvironment::~UseCaseEnvironment()
539 stk_classic::diag::printTimersTable(
out(), timer(), stk_classic::diag::METRICS_CPU_TIME | stk_classic::diag::METRICS_WALL_TIME,
false, m_comm);
541 stk_classic::diag::deleteRootTimer(timer());
543 static_cast<stk_classic::indent_streambuf *>(
dwout().rdbuf())->redirect(std::cout.rdbuf());
553 if (m_need_to_finalize) {
560 int error_flag = success ? 0 : 1;
562 bool all_success = !error_flag;
566 std::cout << ( all_success ?
"STK_USECASE_PASS" :
"Use case failed.") << std::endl;