diff --git a/examples/custom_iteration_spaces.cu b/examples/custom_iteration_spaces.cu index c733890..ced264d 100644 --- a/examples/custom_iteration_spaces.cu +++ b/examples/custom_iteration_spaces.cu @@ -72,9 +72,8 @@ void tied_copy_sweep_grid_shape(nvbench::state &state) } NVBENCH_BENCH(tied_copy_sweep_grid_shape) // Every power of two from 64->1024: - .add_int64_axis("BlockSize", {32,64,128,256}) - .add_int64_axis("NumBlocks", {1024,512,256,128}) - .zip_axes({"BlockSize", "NumBlocks"}); + .add_zip_axes(nvbench::int64_axis{"BlockSize", {32, 64, 128, 256}}, + nvbench::int64_axis{"NumBlocks", {1024, 512, 256, 128}}); //============================================================================== // under_diag: @@ -89,7 +88,8 @@ struct under_diag final : nvbench::user_axis_space { under_diag(std::vector input_indices, std::vector output_indices) - : nvbench::user_axis_space(std::move(input_indices), std::move(output_indices)) + : nvbench::user_axis_space(std::move(input_indices), + std::move(output_indices)) {} mutable std::size_t x_pos = 0; @@ -154,15 +154,12 @@ void user_copy_sweep_grid_shape(nvbench::state &state) copy_sweep_grid_shape(state); } NVBENCH_BENCH(user_copy_sweep_grid_shape) - // Every power of two from 64->1024: - .add_int64_power_of_two_axis("BlockSize", nvbench::range(6, 10)) - .add_int64_power_of_two_axis("NumBlocks", nvbench::range(6, 10)) - .user_iteration_axes({"NumBlocks", "BlockSize"}, - [](auto... args) - -> std::unique_ptr { - return std::make_unique(args...); - }); - + .add_user_iteration_axes( + [](auto... args) -> std::unique_ptr { + return std::make_unique(args...); + }, + nvbench::int64_axis("BlockSize", {64, 128, 256, 512, 1024}), + nvbench::int64_axis("NumBlocks", {1024, 521, 256, 128, 64})); //============================================================================== // gauss: @@ -174,7 +171,8 @@ struct gauss final : nvbench::user_axis_space gauss(std::vector input_indices, std::vector output_indices) - : nvbench::user_axis_space(std::move(input_indices), std::move(output_indices)) + : nvbench::user_axis_space(std::move(input_indices), + std::move(output_indices)) {} nvbench::detail::axis_space_iterator do_iter(axes_info info) const @@ -233,15 +231,13 @@ void dual_float64_axis(nvbench::state &state) }); } NVBENCH_BENCH(dual_float64_axis) - .add_float64_axis("Duration_A", nvbench::range(0., 1e-4, 1e-5)) - .add_float64_axis("Duration_B", nvbench::range(0., 1e-4, 1e-5)) - .user_iteration_axes({"Duration_A"}, - [](auto... args) - -> std::unique_ptr { - return std::make_unique(args...); - }) - .user_iteration_axes({"Duration_B"}, - [](auto... args) - -> std::unique_ptr { - return std::make_unique(args...); - }); + .add_user_iteration_axes( + [](auto... args) -> std::unique_ptr { + return std::make_unique(args...); + }, + nvbench::float64_axis("Duration_A", nvbench::range(0., 1e-4, 1e-5))) + .add_user_iteration_axes( + [](auto... args) -> std::unique_ptr { + return std::make_unique(args...); + }, + nvbench::float64_axis("Duration_B", nvbench::range(0., 1e-4, 1e-5))); diff --git a/nvbench/axes_metadata.cuh b/nvbench/axes_metadata.cuh index 053ebe6..ff5adac 100644 --- a/nvbench/axes_metadata.cuh +++ b/nvbench/axes_metadata.cuh @@ -62,6 +62,24 @@ struct axes_metadata void add_string_axis(std::string name, std::vector data); + void add_axis(const axis_base& axis); + + template + void add_zip_axes(Args &&...args) + { + (this->add_axis(std::forward(args)), ...); + this->zip_axes({args.get_name()...}); + } + + template + void add_user_iteration_axes( + std::function make, + Args &&...args) + { + (this->add_axis(std::forward(args)), ...); + this->user_iteration_axes({args.get_name()...}, std::move(make)); + } + void zip_axes(std::vector names); void diff --git a/nvbench/axes_metadata.cxx b/nvbench/axes_metadata.cxx index c39fed9..7e758bd 100644 --- a/nvbench/axes_metadata.cxx +++ b/nvbench/axes_metadata.cxx @@ -117,38 +117,28 @@ catch (std::exception &e) void axes_metadata::add_float64_axis(std::string name, std::vector data) { - m_value_space.push_back( - std::make_unique(m_axes.size(), - m_axes.size() - m_type_axe_count)); - - auto axis = std::make_unique(std::move(name)); - axis->set_inputs(std::move(data)); - m_axes.push_back(std::move(axis)); + this->add_axis(nvbench::float64_axis{name,data}); } void axes_metadata::add_int64_axis(std::string name, std::vector data, nvbench::int64_axis_flags flags) { - m_value_space.push_back( - std::make_unique(m_axes.size(), - m_axes.size() - m_type_axe_count)); - - auto axis = std::make_unique(std::move(name)); - axis->set_inputs(std::move(data), flags); - m_axes.push_back(std::move(axis)); + this->add_axis(nvbench::int64_axis{name,data,flags}); } void axes_metadata::add_string_axis(std::string name, std::vector data) +{ + this->add_axis(nvbench::string_axis{name,data}); +} + +void axes_metadata::add_axis(const axis_base& axis) { m_value_space.push_back( std::make_unique(m_axes.size(), m_axes.size() - m_type_axe_count)); - - auto axis = std::make_unique(std::move(name)); - axis->set_inputs(std::move(data)); - m_axes.push_back(std::move(axis)); + m_axes.push_back(axis.clone()); } namespace diff --git a/nvbench/benchmark_base.cuh b/nvbench/benchmark_base.cuh index 61269e1..d1c7a3f 100644 --- a/nvbench/benchmark_base.cuh +++ b/nvbench/benchmark_base.cuh @@ -111,12 +111,26 @@ struct benchmark_base return *this; } + template + benchmark_base &add_zip_axes(Args&&... args) + { + m_axes.add_zip_axes(std::forward(args)...); + return *this; + } + benchmark_base &zip_axes(std::vector names) { m_axes.zip_axes(std::move(names)); return *this; } + template + benchmark_base &add_user_iteration_axes(Args&&... args) + { + m_axes.add_user_iteration_axes(std::forward(args)...); + return *this; + } + benchmark_base & user_iteration_axes(std::vector names, std::function make) diff --git a/nvbench/float64_axis.cuh b/nvbench/float64_axis.cuh index 0d60651..b9bcdc8 100644 --- a/nvbench/float64_axis.cuh +++ b/nvbench/float64_axis.cuh @@ -34,6 +34,11 @@ struct float64_axis final : public axis_base , m_values{} {} + explicit float64_axis(std::string name, std::vector inputs) + : axis_base{std::move(name), axis_type::float64} + , m_values{std::move(inputs)} + {} + ~float64_axis() final; void set_inputs(std::vector inputs) diff --git a/nvbench/int64_axis.cuh b/nvbench/int64_axis.cuh index a6cec2e..08d6686 100644 --- a/nvbench/int64_axis.cuh +++ b/nvbench/int64_axis.cuh @@ -51,6 +51,10 @@ struct int64_axis final : public axis_base , m_flags{int64_axis_flags::none} {} + explicit int64_axis(std::string name, + std::vector inputs, + int64_axis_flags flags = int64_axis_flags::none); + ~int64_axis() final; [[nodiscard]] bool is_power_of_two() const diff --git a/nvbench/int64_axis.cxx b/nvbench/int64_axis.cxx index 24ff913..271f93c 100644 --- a/nvbench/int64_axis.cxx +++ b/nvbench/int64_axis.cxx @@ -26,23 +26,24 @@ #include #include -namespace nvbench +namespace { -int64_axis::~int64_axis() = default; - -void int64_axis::set_inputs(std::vector inputs, int64_axis_flags flags) +std::vector +construct_values(nvbench::int64_axis_flags flags, + const std::vector &inputs) { - m_inputs = std::move(inputs); - m_flags = flags; - if (!this->is_power_of_two()) + std::vector values; + const bool is_power_of_two = + static_cast(flags & nvbench::int64_axis_flags::power_of_two); + if (!is_power_of_two) { - m_values = m_inputs; + values = inputs; } else { - m_values.resize(m_inputs.size()); + values.resize(inputs.size()); auto conv = [](int64_t in) -> int64_t { if (in < 0 || in >= 64) @@ -52,11 +53,35 @@ void int64_axis::set_inputs(std::vector inputs, int64_axis_flags flags) "Input={} ValidRange=[0, 63]", in); } - return int64_axis::compute_pow2(in); + return nvbench::int64_axis::compute_pow2(in); }; - std::transform(m_inputs.cbegin(), m_inputs.cend(), m_values.begin(), conv); + std::transform(inputs.cbegin(), inputs.cend(), values.begin(), conv); } + + return values; +} +} // namespace + +namespace nvbench +{ + +int64_axis::int64_axis(std::string name, + std::vector inputs, + int64_axis_flags flags) + : axis_base{std::move(name), axis_type::int64} + , m_inputs{std::move(inputs)} + , m_values{construct_values(flags, m_inputs)} + , m_flags{flags} +{} + +int64_axis::~int64_axis() = default; + +void int64_axis::set_inputs(std::vector inputs, int64_axis_flags flags) +{ + m_inputs = std::move(inputs); + m_flags = flags; + m_values = construct_values(flags, m_inputs); } std::string int64_axis::do_get_input_string(std::size_t i) const diff --git a/nvbench/string_axis.cuh b/nvbench/string_axis.cuh index 2f526e7..d2a3bde 100644 --- a/nvbench/string_axis.cuh +++ b/nvbench/string_axis.cuh @@ -34,6 +34,11 @@ struct string_axis final : public axis_base , m_values{} {} + explicit string_axis(std::string name, std::vector inputs) + : axis_base{std::move(name), axis_type::string} + , m_values{std::move(inputs)} + {} + ~string_axis() final; void set_inputs(std::vector inputs) diff --git a/testing/axes_iteration_space.cu b/testing/axes_iteration_space.cu index fca5757..4e9ec93 100644 --- a/testing/axes_iteration_space.cu +++ b/testing/axes_iteration_space.cu @@ -81,9 +81,8 @@ void test_zip_axes() { using benchmark_type = nvbench::benchmark; benchmark_type bench; - bench.add_float64_axis("F64 Axis", {0., .1, .25, .5, 1.}); - bench.add_int64_axis("I64 Axis", {1, 3, 2, 4, 5}); - bench.zip_axes({"F64 Axis", "I64 Axis"}); + bench.add_zip_axes(nvbench::float64_axis("F64 Axis", {0., .1, .25, .5, 1.}), + nvbench::int64_axis("I64 Axis", {1, 3, 2, 4, 5})); ASSERT_MSG(bench.get_config_count() == 5 * bench.get_devices().size(), "Got {}", @@ -107,11 +106,10 @@ void test_tie_unequal_length() { using benchmark_type = nvbench::benchmark; benchmark_type bench; - bench.add_float64_axis("F64 Axis", {0., .1, .25, .5, 1.}); - bench.add_int64_axis("I64 Axis", {1, 3, 2}); - bench.zip_axes({"I64 Axis", "F64 Axis"}); - ASSERT_THROWS_ANY(bench.zip_axes({"F64 Axis", "I64 Axis"})); + ASSERT_THROWS_ANY( + bench.add_zip_axes(nvbench::float64_axis("F64 Axis", {0., .1, .25, .5, 1.}), + nvbench::int64_axis("I64 Axis", {1, 3, 2}))); } void test_tie_type_axi() @@ -191,11 +189,11 @@ void test_tie_clone() using benchmark_type = nvbench::benchmark; benchmark_type bench; bench.set_devices(std::vector{}); - bench.add_string_axis("Strings", {"string a", "string b", "string c"}); bench.add_int64_power_of_two_axis("I64 POT Axis", {10, 20}); bench.add_int64_axis("I64 Axis", {10, 20}); - bench.add_float64_axis("F64 Axis", {0., .1, .25}); - bench.zip_axes({"F64 Axis", "Strings"}); + bench.add_zip_axes(nvbench::string_axis("Strings", + {"string a", "string b", "string c"}), + nvbench::float64_axis("F64 Axis", {0., .1, .25})); const auto expected_count = bench.get_config_count(); @@ -237,7 +235,8 @@ struct under_diag final : nvbench::user_axis_space { under_diag(std::vector input_indices, std::vector output_indices) - : nvbench::user_axis_space(std::move(input_indices), std::move(output_indices)) + : nvbench::user_axis_space(std::move(input_indices), + std::move(output_indices)) {} mutable std::size_t x_pos = 0;