Skip to content

Commit 0cd34ac

Browse files
committed
Reuse existing global args pattern for criterion params.
1 parent f26d2f9 commit 0cd34ac

File tree

2 files changed

+76
-101
lines changed

2 files changed

+76
-101
lines changed

nvbench/option_parser.cu

Lines changed: 75 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
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

91116
void 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

733754
void 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

747776
void 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)
9891017
try
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
}
10201078
catch (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 &params_desc = it_criterion->second;
1047-
const nvbench::criterion_params &params = 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 &param) { return param.first == name; });
1056-
1057-
if (it_params == params_desc.end())
1058-
{
1059-
NVBENCH_THROW(std::runtime_error,
1060-
"Unknown stopping criterion parameter:\nBenchmark: `{}`\nCriterion: "
1061-
"`{}`\nParameter: `{}`",
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:\nBenchmark: `{}`\nCriterion: "
1076-
"`{}`\nParameter: `{}`",
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-
10991087
void option_parser::update_float64_prop(const std::string &prop_arg, const std::string &prop_val)
11001088
try
11011089
{

nvbench/option_parser.cuh

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,11 @@ private:
113113
void update_int64_prop(const std::string &prop_arg, const std::string &prop_val);
114114
void update_float64_prop(const std::string &prop_arg, const std::string &prop_val);
115115

116-
void update_criterion_prop(int benchmark_idx,
117-
const std::string &prop_arg,
116+
void update_criterion_prop(const std::string &prop_arg,
118117
const std::string &prop_val,
119118
const nvbench::named_values::type type);
120119

121120
void update_used_device_state() const;
122-
void check_criterion_props();
123-
void apply_criterion_props();
124121

125122
// Command line args
126123
std::vector<std::string> m_args;
@@ -149,16 +146,6 @@ private:
149146

150147
// Used for device modification commands like --log-gpu-clocks
151148
bool m_exit_after_parsing{false};
152-
153-
struct stopping_criterion_property
154-
{
155-
int benchmark_idx;
156-
std::string arg;
157-
std::string val;
158-
nvbench::named_values::type type;
159-
};
160-
161-
std::vector<stopping_criterion_property> m_stopping_criterion_properties;
162149
};
163150

164151
} // namespace nvbench

0 commit comments

Comments
 (0)