mirror of
https://github.com/NVIDIA/nvbench.git
synced 2026-03-14 20:27:24 +00:00
Replace params class with nvbench::named_values.
Refactor nvbench::state to use this for axis parameters. These will also be useful for summaries and measurements. Also adds a new ASSERT_THROWS_ANY macro to test some of the new API.
This commit is contained in:
@@ -5,7 +5,7 @@ set(srcs
|
||||
cuda_call.cu
|
||||
float64_axis.cu
|
||||
int64_axis.cu
|
||||
params.cu
|
||||
named_values.cu
|
||||
state.cu
|
||||
string_axis.cu
|
||||
type_axis.cu
|
||||
|
||||
@@ -41,19 +41,19 @@ std::vector<nvbench::state> state_generator::create(const axes_metadata &axes)
|
||||
break;
|
||||
|
||||
case axis_type::int64:
|
||||
state.set_param(
|
||||
state.m_axis_values.set_int64(
|
||||
axis_info.axis,
|
||||
axes.get_int64_axis(axis_info.axis).get_value(axis_info.index));
|
||||
break;
|
||||
|
||||
case axis_type::float64:
|
||||
state.set_param(
|
||||
state.m_axis_values.set_float64(
|
||||
axis_info.axis,
|
||||
axes.get_float64_axis(axis_info.axis).get_value(axis_info.index));
|
||||
break;
|
||||
|
||||
case axis_type::string:
|
||||
state.set_param(
|
||||
state.m_axis_values.set_string(
|
||||
axis_info.axis,
|
||||
axes.get_string_axis(axis_info.axis).get_value(axis_info.index));
|
||||
break;
|
||||
|
||||
109
nvbench/named_values.cu
Normal file
109
nvbench/named_values.cu
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <nvbench/named_values.cuh>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
void named_values::clear() { m_map.clear(); }
|
||||
|
||||
std::size_t named_values::get_size() const { return m_map.size(); }
|
||||
|
||||
std::vector<std::string> named_values::get_names() const
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
names.reserve(m_map.size());
|
||||
std::transform(m_map.cbegin(),
|
||||
m_map.cend(),
|
||||
std::back_inserter(names),
|
||||
[](const auto &val) { return val.first; });
|
||||
return names;
|
||||
}
|
||||
|
||||
bool named_values::has_value(const std::string &name) const
|
||||
{
|
||||
return m_map.find(name) != m_map.cend();
|
||||
}
|
||||
|
||||
const named_values::value_type &
|
||||
named_values::get_value(const std::string &name) const
|
||||
{
|
||||
return m_map.at(name);
|
||||
}
|
||||
|
||||
named_values::type named_values::get_type(const std::string &name) const
|
||||
{
|
||||
return std::visit(
|
||||
[&name]([[maybe_unused]] auto &&arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, nvbench::int64_t>)
|
||||
{
|
||||
return nvbench::named_values::type::int64;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, nvbench::float64_t>)
|
||||
{
|
||||
return nvbench::named_values::type::float64;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::string>)
|
||||
{
|
||||
return nvbench::named_values::type::string;
|
||||
}
|
||||
throw std::runtime_error(fmt::format("{}:{}: Unknown variant type for "
|
||||
"entry '{}'.",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
name));
|
||||
},
|
||||
this->get_value(name));
|
||||
}
|
||||
|
||||
nvbench::int64_t named_values::get_int64(const std::string &name) const
|
||||
{
|
||||
return std::get<nvbench::int64_t>(this->get_value(name));
|
||||
}
|
||||
|
||||
nvbench::float64_t named_values::get_float64(const std::string &name) const
|
||||
{
|
||||
return std::get<nvbench::float64_t>(this->get_value(name));
|
||||
}
|
||||
|
||||
const std::string &named_values::get_string(const std::string &name) const
|
||||
{
|
||||
return std::get<std::string>(this->get_value(name));
|
||||
}
|
||||
|
||||
void named_values::set_int64(std::string name, nvbench::int64_t value)
|
||||
{
|
||||
m_map.insert(std::make_pair(std::move(name), value_type{std::move(value)}));
|
||||
}
|
||||
|
||||
void named_values::set_float64(std::string name, nvbench::float64_t value)
|
||||
{
|
||||
m_map.insert(std::make_pair(std::move(name), value_type{std::move(value)}));
|
||||
}
|
||||
|
||||
void named_values::set_string(std::string name, std::string value)
|
||||
{
|
||||
m_map.insert(std::make_pair(std::move(name), value_type{std::move(value)}));
|
||||
}
|
||||
|
||||
void named_values::set_value(std::string name, named_values::value_type value)
|
||||
{
|
||||
m_map.insert(std::make_pair(std::move(name), std::move(value)));
|
||||
}
|
||||
|
||||
void named_values::remove_value(const std::string &name)
|
||||
{
|
||||
auto iter = m_map.find(name);
|
||||
if (iter != m_map.end())
|
||||
{
|
||||
m_map.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nvbench
|
||||
55
nvbench/named_values.cuh
Normal file
55
nvbench/named_values.cuh
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <nvbench/types.cuh>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
/**
|
||||
* Maintains a map of key / value pairs where the keys are names and the
|
||||
* values may be int64s, float64s, or strings.
|
||||
*/
|
||||
struct named_values
|
||||
{
|
||||
using value_type =
|
||||
std::variant<nvbench::int64_t, nvbench::float64_t, std::string>;
|
||||
|
||||
enum class type
|
||||
{
|
||||
int64,
|
||||
float64,
|
||||
string
|
||||
};
|
||||
|
||||
[[nodiscard]] std::size_t get_size() const;
|
||||
[[nodiscard]] std::vector<std::string> get_names() const;
|
||||
|
||||
void set_value(std::string name, value_type value);
|
||||
|
||||
void set_int64(std::string name, nvbench::int64_t value);
|
||||
void set_float64(std::string name, nvbench::float64_t value);
|
||||
void set_string(std::string name, std::string value);
|
||||
|
||||
[[nodiscard]] nvbench::int64_t get_int64(const std::string &name) const;
|
||||
[[nodiscard]] nvbench::float64_t get_float64(const std::string &name) const;
|
||||
[[nodiscard]] const std::string &get_string(const std::string &name) const;
|
||||
|
||||
[[nodiscard]] type get_type(const std::string &name) const;
|
||||
[[nodiscard]] bool has_value(const std::string &name) const;
|
||||
[[nodiscard]] const value_type& get_value(const std::string &name) const;
|
||||
|
||||
void clear();
|
||||
|
||||
void remove_value(const std::string& name);
|
||||
|
||||
private:
|
||||
using map_type = std::unordered_map<std::string, value_type>;
|
||||
|
||||
map_type m_map;
|
||||
};
|
||||
|
||||
} // namespace nvbench
|
||||
@@ -1,40 +0,0 @@
|
||||
#include <nvbench/params.cuh>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
const std::string ¶ms::get_string_param(const std::string &axis_name) const
|
||||
{
|
||||
return m_string_params.at(axis_name);
|
||||
}
|
||||
|
||||
nvbench::int64_t params::get_int64_param(const std::string &axis_name) const
|
||||
{
|
||||
return m_int64_params.at(axis_name);
|
||||
}
|
||||
|
||||
nvbench::float64_t params::get_float64_param(const std::string &axis_name) const
|
||||
{
|
||||
return m_float64_params.at(axis_name);
|
||||
}
|
||||
|
||||
void params::add_string_param(std::string axis_name, std::string value)
|
||||
{
|
||||
m_string_params.insert(
|
||||
std::make_pair(std::move(axis_name), std::move(value)));
|
||||
}
|
||||
|
||||
void params::add_int64_param(std::string axis_name, nvbench::int64_t value)
|
||||
{
|
||||
m_int64_params.insert(std::make_pair(std::move(axis_name), value));
|
||||
}
|
||||
|
||||
void params::add_float64_param(std::string axis_name, nvbench::float64_t value)
|
||||
{
|
||||
m_float64_params.insert(std::make_pair(std::move(axis_name), value));
|
||||
}
|
||||
|
||||
} // namespace nvbench
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <nvbench/types.cuh>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
struct params
|
||||
{
|
||||
[[nodiscard]] const std::string &
|
||||
get_string_param(const std::string &axis_name) const;
|
||||
|
||||
[[nodiscard]] nvbench::int64_t
|
||||
get_int64_param(const std::string &axis_name) const;
|
||||
|
||||
[[nodiscard]] nvbench::float64_t
|
||||
get_float64_param(const std::string &axis_name) const;
|
||||
|
||||
void add_string_param(std::string axis_name, std::string value);
|
||||
void add_int64_param(std::string axis_name, nvbench::int64_t value);
|
||||
void add_float64_param(std::string axis_name, nvbench::float64_t value);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::string> m_string_params;
|
||||
std::unordered_map<std::string, nvbench::int64_t> m_int64_params;
|
||||
std::unordered_map<std::string, nvbench::float64_t> m_float64_params;
|
||||
};
|
||||
|
||||
} // namespace nvbench
|
||||
@@ -3,44 +3,23 @@
|
||||
#include <nvbench/types.cuh>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
const state::param_type &state::get_param(const std::string &axis_name) const
|
||||
{
|
||||
return m_params.at(axis_name);
|
||||
}
|
||||
|
||||
nvbench::int64_t state::get_int64(const std::string &axis_name) const
|
||||
{
|
||||
return std::get<nvbench::int64_t>(m_params.at(axis_name));
|
||||
return m_axis_values.get_int64(axis_name);
|
||||
}
|
||||
|
||||
nvbench::float64_t state::get_float64(const std::string &axis_name) const
|
||||
{
|
||||
return std::get<nvbench::float64_t>(m_params.at(axis_name));
|
||||
return m_axis_values.get_float64(axis_name);
|
||||
}
|
||||
|
||||
const std::string &state::get_string(const std::string &axis_name) const
|
||||
{
|
||||
return std::get<std::string>(m_params.at(axis_name));
|
||||
}
|
||||
void state::set_param(std::string axis_name, nvbench::int64_t value)
|
||||
{
|
||||
m_params.insert(std::make_pair(std::move(axis_name), value));
|
||||
}
|
||||
|
||||
void state::set_param(std::string axis_name, nvbench::float64_t value)
|
||||
{
|
||||
m_params.insert(std::make_pair(std::move(axis_name), value));
|
||||
}
|
||||
|
||||
void state::set_param(std::string axis_name, std::string value)
|
||||
{
|
||||
m_params.insert(std::make_pair(std::move(axis_name), std::move(value)));
|
||||
return m_axis_values.get_string(axis_name);
|
||||
}
|
||||
|
||||
} // namespace nvbench
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <nvbench/named_values.cuh>
|
||||
#include <nvbench/types.cuh>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
@@ -33,24 +32,9 @@ struct state
|
||||
protected:
|
||||
friend struct nvbench::detail::state_generator;
|
||||
|
||||
using param_type =
|
||||
std::variant<nvbench::int64_t, nvbench::float64_t, std::string>;
|
||||
using params_type = std::unordered_map<std::string, param_type>;
|
||||
|
||||
state() = default;
|
||||
|
||||
explicit state(params_type params)
|
||||
: m_params{std::move(params)}
|
||||
{}
|
||||
|
||||
[[nodiscard]] const params_type &get_params() const { return m_params; }
|
||||
[[nodiscard]] const param_type &get_param(const std::string &name) const;
|
||||
|
||||
void set_param(std::string axis_name, nvbench::int64_t value);
|
||||
void set_param(std::string axis_name, nvbench::float64_t value);
|
||||
void set_param(std::string axis_name, std::string value);
|
||||
|
||||
params_type m_params;
|
||||
nvbench::named_values m_axis_values;
|
||||
};
|
||||
|
||||
} // namespace nvbench
|
||||
|
||||
@@ -5,7 +5,7 @@ set(test_srcs
|
||||
cpu_timer.cu
|
||||
float64_axis.cu
|
||||
int64_axis.cu
|
||||
params.cu
|
||||
named_values.cu
|
||||
state.cu
|
||||
state_generator.cu
|
||||
string_axis.cu
|
||||
|
||||
94
testing/named_values.cu
Normal file
94
testing/named_values.cu
Normal file
@@ -0,0 +1,94 @@
|
||||
#include <nvbench/named_values.cuh>
|
||||
|
||||
#include "test_asserts.cuh"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void test_empty()
|
||||
{
|
||||
nvbench::named_values vals;
|
||||
ASSERT(vals.get_size() == 0);
|
||||
ASSERT(vals.get_names().size() == 0);
|
||||
ASSERT(vals.has_value("Nope") == false);
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto val = vals.get_value("Nope"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto type = vals.get_type("Nope"));
|
||||
// Removing non-existent entries shouldn't cause a problem:
|
||||
vals.remove_value("Nope");
|
||||
}
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
auto sort = [](auto &&vec) {
|
||||
std::sort(vec.begin(), vec.end());
|
||||
return std::forward<decltype(vec)>(vec);
|
||||
};
|
||||
|
||||
nvbench::named_values vals;
|
||||
vals.set_int64("Int", 32);
|
||||
vals.set_float64("Float", 34.5);
|
||||
vals.set_string("String", "string!");
|
||||
vals.set_value("IntVar", nvbench::named_values::value_type{36ll});
|
||||
|
||||
std::vector<std::string> names{"Float", "Int", "IntVar", "String"};
|
||||
|
||||
ASSERT(vals.get_size() == 4);
|
||||
ASSERT(sort(vals.get_names()) == names);
|
||||
|
||||
ASSERT(vals.has_value("Float"));
|
||||
ASSERT(vals.has_value("Int"));
|
||||
ASSERT(vals.has_value("IntVar"));
|
||||
ASSERT(vals.has_value("String"));
|
||||
|
||||
ASSERT(std::get<nvbench::float64_t>(vals.get_value("Float")) == 34.5);
|
||||
ASSERT(std::get<nvbench::int64_t>(vals.get_value("Int")) == 32);
|
||||
ASSERT(std::get<nvbench::int64_t>(vals.get_value("IntVar")) == 36);
|
||||
ASSERT(std::get<std::string>(vals.get_value("String")) == "string!");
|
||||
|
||||
ASSERT(vals.get_type("Float") == nvbench::named_values::type::float64);
|
||||
ASSERT(vals.get_type("Int") == nvbench::named_values::type::int64);
|
||||
ASSERT(vals.get_type("IntVar") == nvbench::named_values::type::int64);
|
||||
ASSERT(vals.get_type("String") == nvbench::named_values::type::string);
|
||||
|
||||
ASSERT(vals.get_int64("Int") == 32);
|
||||
ASSERT(vals.get_int64("IntVar") == 36);
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_int64("Float"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_int64("String"));
|
||||
|
||||
ASSERT(vals.get_float64("Float") == 34.5);
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_float64("Int"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_float64("IntVar"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_float64("String"));
|
||||
|
||||
ASSERT(vals.get_string("String") == "string!");
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_string("Int"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_string("IntVar"));
|
||||
ASSERT_THROWS_ANY([[maybe_unused]] auto v = vals.get_string("Float"));
|
||||
|
||||
vals.remove_value("IntVar");
|
||||
names = {"Float", "Int", "String"};
|
||||
|
||||
ASSERT(vals.get_size() == 3);
|
||||
ASSERT(sort(vals.get_names()) == names);
|
||||
|
||||
ASSERT(!vals.has_value("IntVar"));
|
||||
ASSERT(vals.has_value("Float"));
|
||||
ASSERT(vals.has_value("Int"));
|
||||
ASSERT(vals.has_value("String"));
|
||||
|
||||
vals.clear();
|
||||
names = {};
|
||||
|
||||
ASSERT(vals.get_size() == 0);
|
||||
ASSERT(sort(vals.get_names()) == names);
|
||||
|
||||
ASSERT(!vals.has_value("IntVar"));
|
||||
ASSERT(!vals.has_value("Float"));
|
||||
ASSERT(!vals.has_value("Int"));
|
||||
ASSERT(!vals.has_value("String"));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_empty();
|
||||
test_basic();
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <nvbench/params.cuh>
|
||||
|
||||
#include "test_asserts.cuh"
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
nvbench::params params;
|
||||
params.add_string_param("Axis 1", "Value 1");
|
||||
params.add_int64_param("Axis 2", 2);
|
||||
params.add_float64_param("Axis 3", 3.);
|
||||
params.add_string_param("Axis 4", "Value 4");
|
||||
params.add_int64_param("Axis 5", 5);
|
||||
params.add_float64_param("Axis 6", 6.);
|
||||
|
||||
ASSERT(params.get_string_param("Axis 1") == "Value 1");
|
||||
ASSERT(params.get_int64_param("Axis 2") == 2);
|
||||
ASSERT(params.get_float64_param("Axis 3") == 3.);
|
||||
ASSERT(params.get_string_param("Axis 4") == "Value 4");
|
||||
ASSERT(params.get_int64_param("Axis 5") == 5);
|
||||
ASSERT(params.get_float64_param("Axis 6") == 6.);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_basic();
|
||||
}
|
||||
@@ -7,22 +7,17 @@
|
||||
// Subclass to gain access to protected members for testing:
|
||||
struct state_tester : public nvbench::state
|
||||
{
|
||||
using params_type = nvbench::state::params_type;
|
||||
|
||||
state_tester()
|
||||
: nvbench::state()
|
||||
{}
|
||||
explicit state_tester(params_type params)
|
||||
: nvbench::state{std::move(params)}
|
||||
{}
|
||||
|
||||
template <typename... Args>
|
||||
void set_param(Args &&...args)
|
||||
template <typename T>
|
||||
void set_param(std::string name, T &&value)
|
||||
{
|
||||
this->state::set_param(std::forward<Args>(args)...);
|
||||
this->state::m_axis_values.set_value(std::move(name),
|
||||
nvbench::named_values::value_type{
|
||||
std::forward<T>(value)});
|
||||
}
|
||||
|
||||
const auto &get_params() const { return m_params; }
|
||||
};
|
||||
|
||||
void test_params()
|
||||
@@ -36,13 +31,6 @@ void test_params()
|
||||
ASSERT(state1.get_int64("TestInt") == nvbench::int64_t{22});
|
||||
ASSERT(state1.get_float64("TestFloat") == nvbench::float64_t{3.14});
|
||||
ASSERT(state1.get_string("TestString") == "A String!");
|
||||
|
||||
// Construct a state from the parameter map built above:
|
||||
state_tester state2{state1.get_params()};
|
||||
|
||||
ASSERT(state2.get_int64("TestInt") == nvbench::int64_t{22});
|
||||
ASSERT(state2.get_float64("TestFloat") == nvbench::float64_t{3.14});
|
||||
ASSERT(state2.get_string("TestString") == "A String!");
|
||||
}
|
||||
|
||||
int main() { test_params(); }
|
||||
|
||||
@@ -29,3 +29,25 @@
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define ASSERT_THROWS_ANY(expr) \
|
||||
do \
|
||||
{ \
|
||||
bool threw = false; \
|
||||
try \
|
||||
{ \
|
||||
expr; \
|
||||
} \
|
||||
catch (...) \
|
||||
{ \
|
||||
threw = true; \
|
||||
} \
|
||||
if (!threw) \
|
||||
{ \
|
||||
fmt::print("{}:{}: Expression expected exception: '{}'.", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#expr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
Reference in New Issue
Block a user