From adaef09b200ea386fc7a9df4f46f53ce1ff36283 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 14 Nov 2023 14:08:10 -0500 Subject: [PATCH 1/2] Support static builds of nvbench with nvml enabled. To do this we need to ensure that the nvml init handler is both contained in the library/executable that uses nvbench. The original implementation fails since the singleton can be dropped since it has no usages. So instead we move to a function static which we ensure will always be used. --- cmake/NVBenchExports.cmake | 12 ++++++++ nvbench/CMakeLists.txt | 6 ++-- nvbench/device_info.cu | 3 ++ nvbench/internal/nvml.cuh | 10 +++++++ nvbench/internal/nvml.cxx | 60 ++++++++++++++++---------------------- 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/cmake/NVBenchExports.cmake b/cmake/NVBenchExports.cmake index 614aa000..cb32bf88 100644 --- a/cmake/NVBenchExports.cmake +++ b/cmake/NVBenchExports.cmake @@ -21,6 +21,18 @@ macro(nvbench_generate_exports) ) endif() + if (TARGET nvbench_json) + set(nvbench_json_code_block + [=[ + add_library(nvbench_json INTERFACE IMPORTED) + if (TARGET nlohmann_json::nlohmann_json) + target_link_libraries(nvbench_json INTERFACE nlohmann_json::nlohmann_json) + endif() + ]=]) + string(APPEND nvbench_build_export_code_block ${nvbench_json_code_block}) + string(APPEND nvbench_install_export_code_block ${nvbench_json_code_block}) + endif() + rapids_export(BUILD NVBench EXPORT_SET nvbench-targets NAMESPACE "nvbench::" diff --git a/nvbench/CMakeLists.txt b/nvbench/CMakeLists.txt index 0dfa02df..938ed6a8 100644 --- a/nvbench/CMakeLists.txt +++ b/nvbench/CMakeLists.txt @@ -24,16 +24,14 @@ set(srcs detail/measure_cold.cu detail/measure_hot.cu detail/state_generator.cxx + + internal/nvml.cxx ) if (NVBench_ENABLE_CUPTI) list(APPEND srcs detail/measure_cupti.cu cupti_profiler.cxx) endif() -if (NVBench_ENABLE_NVML) - list(APPEND srcs internal/nvml.cxx) -endif() - # CUDA 11.0 can't compile json_printer without crashing # So for that version fall back to C++ with degraded # output ( no PTX version info ) diff --git a/nvbench/device_info.cu b/nvbench/device_info.cu index 8edad22a..3b26cdbc 100644 --- a/nvbench/device_info.cu +++ b/nvbench/device_info.cu @@ -45,6 +45,9 @@ device_info::device_info(int id) , m_nvml_device(nullptr) { NVBENCH_CUDA_CALL(cudaGetDeviceProperties(&m_prop, m_id)); + // NVML's lifetime should extend for the entirety of the process, so store in a + // global. + [[maybe_unused]] static auto nvml_lifetime = nvbench::nvml::NVMLLifetimeManager(); #ifdef NVBENCH_HAS_NVML // Retrieve the current device's pci_id as a null-terminated string. diff --git a/nvbench/internal/nvml.cuh b/nvbench/internal/nvml.cuh index 963c3819..aa29feaa 100644 --- a/nvbench/internal/nvml.cuh +++ b/nvbench/internal/nvml.cuh @@ -32,6 +32,16 @@ namespace nvbench::nvml { +// RAII struct that initializes and shuts down NVML +// Beeds to be constructed and kept alive while using nvml +struct NVMLLifetimeManager +{ + NVMLLifetimeManager(); + ~NVMLLifetimeManager(); +private: + bool m_inited{false}; +}; + /// Base class for NVML-specific exceptions struct error : std::runtime_error { diff --git a/nvbench/internal/nvml.cxx b/nvbench/internal/nvml.cxx index 4f750bce..2cb58bee 100644 --- a/nvbench/internal/nvml.cxx +++ b/nvbench/internal/nvml.cxx @@ -16,56 +16,46 @@ * limitations under the License. */ +#include #include -#include +#include #include - #include -#include - -namespace +namespace nvbench::nvml +{ +NVMLLifetimeManager::NVMLLifetimeManager() { +#ifdef NVBENCH_HAS_NVML + try + { + NVBENCH_NVML_CALL_NO_API(nvmlInit()); + m_inited = true; + } + catch (std::exception &e) + { + fmt::print("NVML initialization failed:\n {}", e.what()); + } +#endif +} -// RAII struct that initializes and shuts down NVML -struct NVMLLifetimeManager +NVMLLifetimeManager::~NVMLLifetimeManager() { - NVMLLifetimeManager() +#ifdef NVBENCH_HAS_NVML + if (m_inited) { try { - NVBENCH_NVML_CALL_NO_API(nvmlInit()); - m_inited = true; + NVBENCH_NVML_CALL_NO_API(nvmlShutdown()); } catch (std::exception &e) { - fmt::print("NVML initialization failed:\n {}", e.what()); + fmt::print("NVML shutdown failed:\n {}", e.what()); } } +#endif +} - ~NVMLLifetimeManager() - { - if (m_inited) - { - try - { - NVBENCH_NVML_CALL_NO_API(nvmlShutdown()); - } - catch (std::exception &e) - { - fmt::print("NVML shutdown failed:\n {}", e.what()); - } - } - } - -private: - bool m_inited{false}; -}; - -// NVML's lifetime should extend for the entirety of the process, so store in a -// global. -auto nvml_lifetime = NVMLLifetimeManager{}; - -} // namespace +} // namespace nvbench::nvml From cbe9980304957239b22129250c5a95c7f9ac8bf1 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 14 Nov 2023 14:23:56 -0500 Subject: [PATCH 2/2] Correct typo in nvbench/internal/nvml.cuh Co-authored-by: Bradley Dice --- nvbench/internal/nvml.cuh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nvbench/internal/nvml.cuh b/nvbench/internal/nvml.cuh index aa29feaa..05c6764a 100644 --- a/nvbench/internal/nvml.cuh +++ b/nvbench/internal/nvml.cuh @@ -33,7 +33,7 @@ namespace nvbench::nvml { // RAII struct that initializes and shuts down NVML -// Beeds to be constructed and kept alive while using nvml +// Needs to be constructed and kept alive while using nvml struct NVMLLifetimeManager { NVMLLifetimeManager();