mirror of
https://github.com/NVIDIA/nvbench.git
synced 2026-03-14 20:27:24 +00:00
Add int64_axis.
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(nvbench CUDA)
|
||||
|
||||
include(CPM)
|
||||
|
||||
CPMAddPackage(
|
||||
@@ -23,9 +27,5 @@ CPMAddPackage(
|
||||
# properties...Resorting to brute force to unblock.
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAG} -std=c++17")
|
||||
|
||||
add_library(nvbench INTERFACE)
|
||||
target_include_directories(nvbench INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
target_link_libraries(nvbench INTERFACE benchmark_main)
|
||||
set_target_properties(nvbench PROPERTIES INTERFACE_COMPILE_FEATURES cuda_std_17)
|
||||
|
||||
add_subdirectory(nvbench)
|
||||
add_subdirectory(testing)
|
||||
|
||||
13
nvbench/CMakeLists.txt
Normal file
13
nvbench/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
set(srcs
|
||||
axis_base.cu
|
||||
int64_axis.cu
|
||||
)
|
||||
|
||||
# TODO shared may be a good idea to reduce compilation overhead for large
|
||||
# benchmark libraries.
|
||||
add_library(nvbench STATIC ${srcs})
|
||||
# TODO generator expression for installed paths
|
||||
target_include_directories(nvbench PUBLIC "${nvbench_SOURCE_DIR}")
|
||||
target_link_libraries(nvbench PRIVATE fmt::fmt)
|
||||
target_link_libraries(nvbench INTERFACE benchmark_main)
|
||||
set_target_properties(nvbench PROPERTIES COMPILE_FEATURES cuda_std_17)
|
||||
8
nvbench/axis_base.cu
Normal file
8
nvbench/axis_base.cu
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "axis_base.cuh"
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
axis_base::~axis_base() = default;
|
||||
|
||||
} // namespace nvbench
|
||||
52
nvbench/axis_base.cuh
Normal file
52
nvbench/axis_base.cuh
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
enum class axis_type
|
||||
{
|
||||
type,
|
||||
int64,
|
||||
float64,
|
||||
string
|
||||
};
|
||||
|
||||
struct axis_base
|
||||
{
|
||||
virtual ~axis_base();
|
||||
|
||||
[[nodiscard]] const std::string &get_name() const { return m_name; }
|
||||
|
||||
[[nodiscard]] axis_type get_type() const { return m_type; }
|
||||
|
||||
[[nodiscard]] std::size_t get_size() const { return this->do_get_size(); }
|
||||
|
||||
[[nodiscard]] std::string get_user_string(std::size_t i) const
|
||||
{
|
||||
return this->do_get_user_string(i);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string get_user_description(std::size_t i) const
|
||||
{
|
||||
return this->do_get_user_description(i);
|
||||
}
|
||||
|
||||
protected:
|
||||
axis_base(std::string name, axis_type type)
|
||||
: m_name{std::move(name)}
|
||||
, m_type{type}
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::size_t do_get_size() const = 0;
|
||||
virtual std::string do_get_user_string(std::size_t) const = 0;
|
||||
virtual std::string do_get_user_description(std::size_t) const = 0;
|
||||
|
||||
std::string m_name;
|
||||
axis_type m_type;
|
||||
};
|
||||
|
||||
} // namespace nvbench
|
||||
52
nvbench/int64_axis.cu
Normal file
52
nvbench/int64_axis.cu
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <nvbench/int64_axis.cuh>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
int64_axis::~int64_axis() = default;
|
||||
|
||||
void int64_axis::set_inputs(const std::vector<int64_t> &inputs)
|
||||
{
|
||||
m_inputs = inputs;
|
||||
if (!m_is_power_of_two)
|
||||
{
|
||||
m_values = inputs;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_values.resize(inputs.size());
|
||||
|
||||
auto conv = [](int64_t in) -> int64_t {
|
||||
if (in < 0 || in >= 64)
|
||||
{
|
||||
throw std::runtime_error(fmt::format("{}:{}: Input value exceeds valid "
|
||||
"range "
|
||||
"for power-of-two mode. "
|
||||
"Input={} ValidRange=[0, 63]",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
in));
|
||||
}
|
||||
return 1ll << in;
|
||||
};
|
||||
|
||||
std::transform(inputs.cbegin(), inputs.cend(), m_values.begin(), conv);
|
||||
}
|
||||
}
|
||||
std::string int64_axis::do_get_user_string(std::size_t i) const
|
||||
{
|
||||
return fmt::to_string(m_inputs[i]);
|
||||
}
|
||||
std::string int64_axis::do_get_user_description(std::size_t i) const
|
||||
{
|
||||
return m_is_power_of_two ? fmt::format("2^{} = {}", m_inputs[i], m_values[i])
|
||||
: std::string{};
|
||||
}
|
||||
|
||||
} // namespace nvbench
|
||||
45
nvbench/int64_axis.cuh
Normal file
45
nvbench/int64_axis.cuh
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <nvbench/axis_base.cuh>
|
||||
#include <nvbench/types.cuh>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
struct int64_axis final : public axis_base
|
||||
{
|
||||
int64_axis(std::string name, bool is_power_of_two)
|
||||
: axis_base{std::move(name), axis_type::int64}
|
||||
, m_is_power_of_two{is_power_of_two}
|
||||
{}
|
||||
|
||||
~int64_axis() final;
|
||||
|
||||
[[nodiscard]] bool get_is_power_of_two() const { return m_is_power_of_two; }
|
||||
|
||||
void set_inputs(const std::vector<int64_t> &inputs);
|
||||
|
||||
[[nodiscard]] const std::vector<int64_t> &get_inputs() const
|
||||
{
|
||||
return m_inputs;
|
||||
};
|
||||
|
||||
[[nodiscard]] const std::vector<int64_t> &get_values() const
|
||||
{
|
||||
return m_values;
|
||||
};
|
||||
|
||||
std::size_t do_get_size() const final { return m_inputs.size(); }
|
||||
std::string do_get_user_string(std::size_t) const final;
|
||||
std::string do_get_user_description(std::size_t) const final;
|
||||
|
||||
private:
|
||||
std::vector<int64_t> m_inputs;
|
||||
std::vector<int64_t> m_values;
|
||||
bool m_is_power_of_two;
|
||||
};
|
||||
|
||||
} //
|
||||
19
nvbench/types.cuh
Normal file
19
nvbench/types.cuh
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace nvbench
|
||||
{
|
||||
|
||||
using int8_t = std::int8_t;
|
||||
using int16_t = std::int16_t;
|
||||
using int32_t = std::int32_t;
|
||||
using int64_t = std::int64_t;
|
||||
using uint8_t = std::uint8_t;
|
||||
using uint16_t = std::uint16_t;
|
||||
using uint32_t = std::uint32_t;
|
||||
using uint64_t = std::uint64_t;
|
||||
using float32_t = float;
|
||||
using float64_t = double;
|
||||
|
||||
} // namespace nvbench
|
||||
@@ -1,4 +1,5 @@
|
||||
set(test_srcs
|
||||
int64_axis.cu
|
||||
type_list.cu
|
||||
)
|
||||
|
||||
@@ -6,7 +7,7 @@ foreach(test_src IN LISTS test_srcs)
|
||||
get_filename_component(test_name "${test_src}" NAME_WLE)
|
||||
string(PREPEND test_name "nvbench.test.")
|
||||
add_executable(${test_name} "${test_src}")
|
||||
target_link_libraries(${test_name} PRIVATE nvbench)
|
||||
target_link_libraries(${test_name} PRIVATE nvbench fmt)
|
||||
set_target_properties(${test_name} PROPERTIES COMPILE_FEATURES cuda_std_17)
|
||||
add_test(NAME ${test_name} COMMAND "$<TARGET_FILE:${test_target}>")
|
||||
endforeach()
|
||||
|
||||
58
testing/int64_axis.cu
Normal file
58
testing/int64_axis.cu
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <nvbench/int64_axis.cuh>
|
||||
|
||||
#include "testing/test_asserts.cuh"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
nvbench::int64_axis axis{"BasicAxis", false};
|
||||
ASSERT(axis.get_name() == "BasicAxis");
|
||||
ASSERT(axis.get_type() == nvbench::axis_type::int64);
|
||||
ASSERT(!axis.get_is_power_of_two());
|
||||
|
||||
axis.set_inputs({0, 1, 2, 3, 7, 6, 5, 4});
|
||||
ASSERT(axis.get_size() == 8);
|
||||
|
||||
std::vector<nvbench::int64_t> ref{0, 1, 2, 3, 7, 6, 5, 4};
|
||||
ASSERT(axis.get_inputs() == ref);
|
||||
ASSERT(axis.get_values() == ref);
|
||||
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
ASSERT(axis.get_user_string(i) == fmt::to_string(ref[i]));
|
||||
ASSERT(axis.get_user_description(i).empty());
|
||||
}
|
||||
}
|
||||
|
||||
void test_power_of_two()
|
||||
{
|
||||
nvbench::int64_axis axis{"POTAxis", true};
|
||||
ASSERT(axis.get_name() == "POTAxis");
|
||||
ASSERT(axis.get_type() == nvbench::axis_type::int64);
|
||||
ASSERT(axis.get_is_power_of_two());
|
||||
|
||||
axis.set_inputs({0, 1, 2, 3, 7, 6, 5, 4});
|
||||
ASSERT(axis.get_size() == 8);
|
||||
|
||||
std::vector<nvbench::int64_t> ref_inputs{0, 1, 2, 3, 7, 6, 5, 4};
|
||||
std::vector<nvbench::int64_t> ref_values{1, 2, 4, 8, 128, 64, 32, 16};
|
||||
ASSERT(axis.get_inputs() == ref_inputs);
|
||||
ASSERT(axis.get_values() == ref_values);
|
||||
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
fmt::print("{}: {}\n", i, axis.get_user_description(i));
|
||||
ASSERT(axis.get_user_string(i) == fmt::to_string(ref_inputs[i]));
|
||||
ASSERT(axis.get_user_description(i) ==
|
||||
fmt::format("2^{} = {}", ref_inputs[i], ref_values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_basic();
|
||||
test_power_of_two();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
31
testing/test_asserts.cuh
Normal file
31
testing/test_asserts.cuh
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#define ASSERT(cond) \
|
||||
do \
|
||||
{ \
|
||||
if (cond) \
|
||||
{} \
|
||||
else \
|
||||
{ \
|
||||
fmt::print("{}:{}: Assertion failed ({}).\n", __FILE__, __LINE__, #cond); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define ASSERT_MSG(cond, msg) \
|
||||
do \
|
||||
{ \
|
||||
if (cond) \
|
||||
{} \
|
||||
else \
|
||||
{ \
|
||||
fmt::print("{}:{}: Test assertion failed ({}) {}\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#cond, \
|
||||
msg); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (false)
|
||||
Reference in New Issue
Block a user