3939#include < algorithm>
4040#include < cassert>
4141#include < cstdlib>
42+ #include < exception>
4243#include < fstream>
4344#include < iostream>
4445#include < iterator>
@@ -82,11 +83,35 @@ std::string_view submatch_to_sv(const sv_submatch &in)
8283//
8384// So we're stuck with materializing a std::string and calling std::stoX(). Ah
8485// well. At least it's not istream.
85- void parse (std::string_view input, nvbench::int32_t &val) { val = std::stoi (std::string (input)); }
86+ void parse (std::string_view input, nvbench::int32_t &val)
87+ try
88+ {
89+ val = std::stoi (std::string (input));
90+ }
91+ catch (const std::exception &)
92+ { // The default exception messages are not very useful on gcc...it's just "stoi".
93+ NVBENCH_THROW (std::invalid_argument, " Failed to parse int32 value from string '{}'" , input);
94+ }
8695
87- void parse (std::string_view input, nvbench::int64_t &val) { val = std::stoll (std::string (input)); }
96+ void parse (std::string_view input, nvbench::int64_t &val)
97+ try
98+ {
99+ val = std::stoll (std::string (input));
100+ }
101+ catch (const std::exception &)
102+ {
103+ NVBENCH_THROW (std::invalid_argument, " Failed to parse int64 value from string '{}'" , input);
104+ }
88105
89- void parse (std::string_view input, nvbench::float64_t &val) { val = std::stod (std::string (input)); }
106+ void parse (std::string_view input, nvbench::float64_t &val)
107+ try
108+ {
109+ val = std::stod (std::string (input));
110+ }
111+ catch (const std::exception &)
112+ {
113+ NVBENCH_THROW (std::invalid_argument, " Failed to parse float64 value from string '{}'" , input);
114+ }
90115
91116void parse (std::string_view input, std::string &val) { val = input; }
92117
@@ -344,9 +369,6 @@ void option_parser::parse_impl()
344369 }
345370 }
346371
347- this ->apply_criterion_props ();
348- this ->check_criterion_props ();
349-
350372 // Make sure there's a default printer if needed:
351373 if (!m_have_stdout_printer)
352374 {
@@ -538,8 +560,7 @@ void option_parser::parse_range(option_parser::arg_iterator_t first,
538560 if (it != criterion_params.end ())
539561 {
540562 check_params (1 );
541- m_stopping_criterion_properties.push_back (
542- {int (m_benchmarks.size ()) - 1 , first[0 ], first[1 ], it->second });
563+ this ->update_criterion_prop (first[0 ], first[1 ], it->second );
543564 first += 2 ;
544565 }
545566 else
@@ -731,6 +752,7 @@ void option_parser::enable_run_once()
731752}
732753
733754void option_parser::set_stopping_criterion (const std::string &criterion)
755+ try
734756{
735757 // If no active benchmark, save args as global.
736758 if (m_benchmarks.empty ())
@@ -743,6 +765,13 @@ void option_parser::set_stopping_criterion(const std::string &criterion)
743765 benchmark_base &bench = *m_benchmarks.back ();
744766 bench.set_stopping_criterion (criterion);
745767}
768+ catch (std::exception &e)
769+ {
770+ NVBENCH_THROW (std::runtime_error,
771+ " Error handling option `--stopping-criterion {}`:\n {}" ,
772+ criterion,
773+ e.what ());
774+ }
746775
747776void option_parser::disable_blocking_kernel ()
748777{
@@ -982,15 +1011,44 @@ catch (std::exception &e)
9821011 e.what ());
9831012}
9841013
985- void option_parser::update_criterion_prop (int benchmark_idx,
986- const std::string &prop_arg,
1014+ void option_parser::update_criterion_prop (const std::string &prop_arg,
9871015 const std::string &prop_val,
9881016 const nvbench::named_values::type type)
9891017try
9901018{
991- benchmark_base &bench = *m_benchmarks.at (benchmark_idx);
992- nvbench::criterion_params &criterion_params = bench.get_criterion_params ();
993- std::string name (prop_arg.begin () + 2 , prop_arg.end ());
1019+ const std::string name (prop_arg.begin () + 2 , prop_arg.end ());
1020+
1021+ // If no active benchmark, save args as global.
1022+ if (m_benchmarks.empty ())
1023+ {
1024+ // Any global params must either belong to the default criterion or follow a
1025+ // `--stopping-criterion` arg:
1026+ nvbench::criterion_params params;
1027+ if (!params.has_value (name) &&
1028+ std::find (m_global_benchmark_args.cbegin (),
1029+ m_global_benchmark_args.cend (),
1030+ " --stopping-criterion" ) == m_global_benchmark_args.cend ())
1031+ {
1032+ NVBENCH_THROW (std::runtime_error,
1033+ " Unrecognized stopping criterion parameter: `{}` for default criterion." ,
1034+ name);
1035+ }
1036+
1037+ m_global_benchmark_args.push_back (prop_arg);
1038+ m_global_benchmark_args.push_back (prop_val);
1039+ return ;
1040+ }
1041+
1042+ benchmark_base &bench = *m_benchmarks.back ();
1043+
1044+ if (!bench.has_criterion_param (name))
1045+ {
1046+ NVBENCH_THROW (std::runtime_error,
1047+ " Unrecognized stopping criterion parameter: `{}` for `{}`." ,
1048+ name,
1049+ bench.get_stopping_criterion ());
1050+ }
1051+
9941052 if (type == nvbench::named_values::type::float64)
9951053 {
9961054 nvbench::float64_t value{};
@@ -1000,21 +1058,21 @@ try
10001058 { // Specified as percentage, stored as ratio:
10011059 value /= 100.0 ;
10021060 }
1003- criterion_params. set_float64 (name, value);
1061+ bench. set_criterion_param_float64 (name, value);
10041062 }
10051063 else if (type == nvbench::named_values::type::int64)
10061064 {
10071065 nvbench::int64_t value{};
10081066 ::parse (prop_val, value);
1009- criterion_params. set_int64 (name, value);
1067+ bench. set_criterion_param_int64 (name, value);
10101068 }
10111069 else if (type == nvbench::named_values::type::string)
10121070 {
1013- criterion_params. set_string (name, prop_val);
1071+ bench. set_criterion_param_string (name, prop_val);
10141072 }
10151073 else
10161074 {
1017- NVBENCH_THROW (std::runtime_error, " Unrecognized property: `{}`" , prop_arg );
1075+ NVBENCH_THROW (std::runtime_error, " Unrecognized type for property: `{}`" , name );
10181076 }
10191077}
10201078catch (std::exception &e)
@@ -1026,76 +1084,6 @@ catch (std::exception &e)
10261084 e.what ());
10271085}
10281086
1029- void option_parser::check_criterion_props ()
1030- {
1031- const nvbench::criterion_manager::params_map params_map =
1032- nvbench::criterion_manager::get ().get_params_description_map ();
1033-
1034- for (const auto &bench_ptr : m_benchmarks)
1035- {
1036- const std::string &stopping_criterion = bench_ptr->get_stopping_criterion ();
1037- auto it_criterion = params_map.find (stopping_criterion);
1038-
1039- if (it_criterion == params_map.end ())
1040- {
1041- NVBENCH_THROW (std::runtime_error,
1042- " Unknown benchmark stopping criterion `{}`" ,
1043- stopping_criterion);
1044- }
1045-
1046- const nvbench::criterion_manager::params_description ¶ms_desc = it_criterion->second ;
1047- const nvbench::criterion_params ¶ms = bench_ptr->get_criterion_params ();
1048-
1049- std::vector<std::string> param_names = params.get_names ();
1050-
1051- for (const std::string &name : param_names)
1052- {
1053- auto it_params = std::find_if (params_desc.begin (),
1054- params_desc.end (),
1055- [&name](const auto ¶m) { return param.first == name; });
1056-
1057- if (it_params == params_desc.end ())
1058- {
1059- NVBENCH_THROW (std::runtime_error,
1060- " Unknown stopping criterion parameter:\n Benchmark: `{}`\n Criterion: "
1061- " `{}`\n Parameter: `{}`" ,
1062- bench_ptr->get_name (),
1063- it_criterion->first ,
1064- name);
1065- }
1066- }
1067-
1068- for (const auto &pair : params_desc)
1069- {
1070- auto it_params = std::find (param_names.begin (), param_names.end (), pair.first );
1071-
1072- if (it_params == param_names.end ())
1073- {
1074- NVBENCH_THROW (std::runtime_error,
1075- " A stopping criterion parameter isn't set:\n Benchmark: `{}`\n Criterion: "
1076- " `{}`\n Parameter: `{}`" ,
1077- bench_ptr->get_name (),
1078- it_criterion->first ,
1079- pair.first );
1080- }
1081- }
1082- }
1083- }
1084-
1085- void option_parser::apply_criterion_props ()
1086- {
1087- for (const stopping_criterion_property &prop : m_stopping_criterion_properties)
1088- {
1089- int beg = (prop.benchmark_idx == -1 ? 0 : prop.benchmark_idx );
1090- int end = (prop.benchmark_idx == -1 ? int (m_benchmarks.size ()) : prop.benchmark_idx + 1 );
1091-
1092- for (int i = beg; i < end; i++)
1093- {
1094- update_criterion_prop (i, prop.arg , prop.val , prop.type );
1095- }
1096- }
1097- }
1098-
10991087void option_parser::update_float64_prop (const std::string &prop_arg, const std::string &prop_val)
11001088try
11011089{
0 commit comments