NVIDIA/nvbench

What's the right way to include nvbench to an existing cmake project?

Closed this issue · 4 comments

Currently, I am using FetchContent and only worrying about the include directory:

include(FetchContent)
set(FETCHCONTENT_QUIET ON)

message(STATUS "Cloning External Project: NVBench")
get_filename_component(FC_BASE "../externals"
                REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
set(FETCHCONTENT_BASE_DIR ${FC_BASE})

FetchContent_Declare(
    nvbench
    GIT_REPOSITORY https://github.com/NVIDIA/nvbench.git
    GIT_TAG        main
)

FetchContent_GetProperties(nvbench)
if(NOT nvbench_POPULATED)
  FetchContent_Populate(
    nvbench
  )
endif()
set(NVBENCH_INCLUDE_DIR "${nvbench_SOURCE_DIR}")

Then I can link my project with nvbench using;

include(${PROJECT_SOURCE_DIR}/cmake/FetchNVBench.cmake)
target_include_directories(my_project
    INTERFACE ${NVBENCH_INCLUDE_DIR}
)

Compiling a simple example using nvbench, I get the following error:

/nvbench/device_info.cuh:21:10: fatal error: nvbench/config.cuh: No such file or directory
 #include <nvbench/config.cuh>

By the way, in my simple test, all I am doing is:

#include <nvbench/nvbench.cuh>

NVBench needs to build and link a library, so just setting the include directory won't be sufficient.

I'm not terribly familiar with FetchContent and usually use CPM instead since it's much easier to use. But it looks like this should work:

  1. Replace
set(NVBENCH_INCLUDE_DIR "${nvbench_SOURCE_DIR}")

with

add_subdirectory("${nvbench_SOURCE_DIR}" "${nvbench_BINARY_DIR}")
  1. Replace
target_include_directories(my_project
    INTERFACE ${NVBENCH_INCLUDE_DIR}
)

with

target_link_libraries(my_project nvbench::main)

There's also an example project at https://github.com/NVIDIA/nvbench_demo that shows how to setup a CMake project using NVBench that might be helpful. It uses a git submodule to fetch the source code rather than FetchContent, but the linking logic should be the same.

NVBench needs to build and link a library, so just setting the include directory won't be sufficient.

I think I had the wrong impression that this was a header-only library. This makes sense now, thank you for the nvbench_demo pointer as well.

@allisonvacanti follow-up question (maybe this needs to be an issue on its own). Is there a reason why nvbench (or actually nvml) calls would fail on CUDA on WSL?

terminate called after throwing an instance of 'nvbench::nvml::call_failed'
  what():  /home/neoblizz/essentials/externals/nvbench-src/nvbench/device_info.cu:53:
        NVML call failed:
                Call: nvmlDeviceGetHandleByPciBusId(pci_id, &m_nvml_device)
                Error: (999) Unknown Error
Aborted

Any pointers that could help me debug this issue (general search seems to recommend cuda driver issue, and the only thing I can think of in my setup is that I am using WSL)?

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 497.29       Driver Version: 497.29       CUDA Version: 11.5     |
|-------------------------------+----------------------+----------------------+
| GPU  Name            TCC/WDDM | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ... WDDM  | 00000000:02:00.0  On |                  N/A |
| 37%   56C    P0    36W / 180W |   1467MiB /  8192MiB |      3%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

@neoblizz I'm not sure why that would happen, but I'm not that familiar with WSL's limitations.

As a workaround, you can set the CMake variable NVBench_ENABLE_NVML=OFF to disable the nvml bits.