mirror of
https://github.com/NVIDIA/nvbench.git
synced 2026-05-11 17:00:01 +00:00
Add Windows support
This commit is contained in:
@@ -39,6 +39,9 @@ if (${CUDAToolkit_VERSION} VERSION_LESS 11.3)
|
||||
endif()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build NVBench as a shared library" ON)
|
||||
if (WIN32 AND BUILD_SHARED_LIBS)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
endif()
|
||||
|
||||
option(NVBench_ENABLE_NVML "Build with NVML support from the Cuda Toolkit." ON)
|
||||
option(NVBench_ENABLE_CUPTI "Build NVBench with CUPTI." ${cupti_default})
|
||||
|
||||
@@ -12,6 +12,7 @@ CUDA_COMPILER=${CUDACXX:-nvcc} # $CUDACXX if set, otherwise `nvcc`
|
||||
CUDA_ARCHS= # Empty, use presets by default.
|
||||
GLOBAL_CMAKE_OPTIONS=()
|
||||
DISABLE_CUB_BENCHMARKS= # Enable to force-disable building CUB benchmarks.
|
||||
HOST_OS="linux" # "linux" or "windows"
|
||||
|
||||
# Check if the correct number of arguments has been provided
|
||||
function usage {
|
||||
@@ -21,6 +22,7 @@ function usage {
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -v/--verbose: enable shell echo for debugging"
|
||||
echo " -os: Target OS, \"linux\" or \"windows\" (Defaults to linux)"
|
||||
echo " -cuda: CUDA compiler (Defaults to \$CUDACXX if set, otherwise nvcc)"
|
||||
echo " -cxx: Host compiler (Defaults to \$CXX if set, otherwise g++)"
|
||||
echo " -std: CUDA/C++ standard (Defaults to 17)"
|
||||
@@ -32,6 +34,7 @@ function usage {
|
||||
echo " $ PARALLEL_LEVEL=8 $0 -cxx g++-9"
|
||||
echo " $ $0 -cxx clang++-8"
|
||||
echo " $ $0 -cxx g++-8 -std 20 -arch 80-real -v -cuda /usr/local/bin/nvcc"
|
||||
echo " $ $0 -os windows -cxx cl.exe -arch native"
|
||||
echo " $ $0 -cmake-options \"-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-Wfatal-errors\""
|
||||
exit 1
|
||||
}
|
||||
@@ -44,6 +47,7 @@ args=("$@")
|
||||
while [ "${#args[@]}" -ne 0 ]; do
|
||||
case "${args[0]}" in
|
||||
-v | --verbose) VERBOSE=1; args=("${args[@]:1}");;
|
||||
-os) HOST_OS="${args[1]}"; args=("${args[@]:2}");;
|
||||
-cxx) HOST_COMPILER="${args[1]}"; args=("${args[@]:2}");;
|
||||
-std) CXX_STANDARD="${args[1]}"; args=("${args[@]:2}");;
|
||||
-cuda) CUDA_COMPILER="${args[1]}"; args=("${args[@]:2}");;
|
||||
@@ -66,8 +70,8 @@ while [ "${#args[@]}" -ne 0 ]; do
|
||||
done
|
||||
|
||||
# Convert to full paths:
|
||||
HOST_COMPILER=$(which ${HOST_COMPILER})
|
||||
CUDA_COMPILER=$(which ${CUDA_COMPILER})
|
||||
HOST_COMPILER=$(which "${HOST_COMPILER}")
|
||||
CUDA_COMPILER=$(which "${CUDA_COMPILER}")
|
||||
|
||||
if [[ -n "${CUDA_ARCHS}" ]]; then
|
||||
GLOBAL_CMAKE_OPTIONS+=("-DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCHS}")
|
||||
@@ -91,11 +95,15 @@ BUILD_DIR="../build/${CCCL_BUILD_INFIX}"
|
||||
|
||||
# The most recent build will always be symlinked to cccl/build/latest
|
||||
mkdir -p $BUILD_DIR
|
||||
rm -f ../build/latest
|
||||
ln -sf $BUILD_DIR ../build/latest
|
||||
|
||||
# Now that BUILD_DIR exists, use readlink to canonicalize the path:
|
||||
BUILD_DIR=$(readlink -f "${BUILD_DIR}")
|
||||
if [[ "${HOST_OS}" == "windows" ]]; then
|
||||
# Git Bash on Windows cannot create directory symlinks without elevated privileges
|
||||
BUILD_DIR=$(cd "${BUILD_DIR}" && pwd)
|
||||
else
|
||||
rm -f ../build/latest
|
||||
ln -sf $BUILD_DIR ../build/latest
|
||||
# Now that BUILD_DIR exists, use readlink to canonicalize the path:
|
||||
BUILD_DIR=$(readlink -f "${BUILD_DIR}")
|
||||
fi
|
||||
|
||||
# Prepare environment for CMake:
|
||||
export CMAKE_BUILD_PARALLEL_LEVEL="${PARALLEL_LEVEL}"
|
||||
|
||||
@@ -23,14 +23,20 @@ function(nvbench_add_cupti_dep dep_name)
|
||||
add_library(nvbench::${dep_name_lower} SHARED IMPORTED)
|
||||
|
||||
find_library(NVBench_${dep_name_upper}_LIBRARY ${dep_name_lower} REQUIRED
|
||||
DOC "The full path to lib${dep_name_lower}.so from the CUDA Toolkit."
|
||||
DOC "The import library for ${dep_name_lower} from the CUDA Toolkit."
|
||||
HINTS "${nvbench_cupti_root}/lib64"
|
||||
)
|
||||
mark_as_advanced(NVBench_${dep_name_upper}_LIBRARY)
|
||||
|
||||
set_target_properties(nvbench::${dep_name_lower} PROPERTIES
|
||||
IMPORTED_LOCATION "${NVBench_${dep_name_upper}_LIBRARY}"
|
||||
)
|
||||
if (WIN32)
|
||||
set_target_properties(nvbench::${dep_name_lower} PROPERTIES
|
||||
IMPORTED_IMPLIB "${NVBench_${dep_name_upper}_LIBRARY}"
|
||||
)
|
||||
else()
|
||||
set_target_properties(nvbench::${dep_name_lower} PROPERTIES
|
||||
IMPORTED_LOCATION "${NVBench_${dep_name_upper}_LIBRARY}"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
nvbench_add_cupti_dep(cupti)
|
||||
|
||||
@@ -91,11 +91,25 @@ endif()
|
||||
if (CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
|
||||
# fmtlib uses llvm's _BitInt internally, which is not available when compiling through nvcc:
|
||||
target_compile_definitions(nvbench.build_interface INTERFACE "FMT_USE_BITINT=0")
|
||||
if (MSVC)
|
||||
# cudafe cannot evaluate fmtlib's UTF-8 literal check even when /utf-8 is passed to the host compiler:
|
||||
target_compile_definitions(nvbench.build_interface INTERFACE
|
||||
$<$<COMPILE_LANGUAGE:CUDA>:FMT_UNICODE=0>
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_compile_options(nvbench.build_interface INTERFACE
|
||||
$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:-Xcudafe=--display_error_number>
|
||||
$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:-Wno-deprecated-gpu-targets>
|
||||
$<$<AND:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>,$<CXX_COMPILER_ID:MSVC>>:-Xcompiler=/utf-8>
|
||||
# Suppress cudafe diagnostics triggered by fmtlib headers when compiled through MSVC+nvcc:
|
||||
# 27: character value is out of range (char32_t sentinel values in lookup tables)
|
||||
# 128: loop is not reachable (dead code in constexpr string comparison)
|
||||
# 2417: constexpr constructor calls non-constexpr function (bigint default ctor)
|
||||
$<$<AND:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>,$<CXX_COMPILER_ID:MSVC>>:-Xcudafe=--diag_suppress=27>
|
||||
$<$<AND:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>,$<CXX_COMPILER_ID:MSVC>>:-Xcudafe=--diag_suppress=128>
|
||||
$<$<AND:$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>,$<CXX_COMPILER_ID:MSVC>>:-Xcudafe=--diag_suppress=2417>
|
||||
)
|
||||
if (NVBench_ENABLE_WERROR)
|
||||
target_compile_options(nvbench.build_interface INTERFACE
|
||||
@@ -115,8 +129,8 @@ function(nvbench_config_target target_name)
|
||||
# the library path, other times they're in a subdirectory that isn't added to
|
||||
# the library path...
|
||||
# To simplify installed nvbench usage, add the CUPTI libraries path to the
|
||||
# installed nvbench rpath:
|
||||
if (NVBench_ENABLE_CUPTI AND nvbench_cupti_root)
|
||||
# installed nvbench rpath (Unix only; Windows uses PATH for DLL lookup):
|
||||
if (NVBench_ENABLE_CUPTI AND nvbench_cupti_root AND NOT WIN32)
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
INSTALL_RPATH "${nvbench_cupti_root}/lib64"
|
||||
)
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
// Defined if NVBench has been built with CUPTI support.
|
||||
#cmakedefine NVBENCH_HAS_CUPTI
|
||||
|
||||
#if defined(_MSVC_LANG)
|
||||
#define NVBENCH_CPLUSPLUS _MSVC_LANG
|
||||
#else
|
||||
#define NVBENCH_CPLUSPLUS __cplusplus
|
||||
#endif
|
||||
|
||||
// Detect current dialect:
|
||||
#if NVBENCH_CPLUSPLUS < 201703L
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
|
||||
#include "test_asserts.cuh"
|
||||
|
||||
@@ -9,6 +9,14 @@ set(cmake_opts
|
||||
-D "CMAKE_CUDA_FLAGS=${CMAKE_CUDA_FLAGS}"
|
||||
-D "CMAKE_CUDA_ARCHITECTURES=${arches}"
|
||||
)
|
||||
if (WIN32)
|
||||
list(APPEND cmake_opts
|
||||
-D "CMAKE_CUDA_HOST_COMPILER=${CMAKE_CXX_COMPILER}"
|
||||
-D "CMAKE_LINKER=${CMAKE_LINKER}"
|
||||
-D "CMAKE_RC_COMPILER=${CMAKE_RC_COMPILER}"
|
||||
-D "CMAKE_MT=${CMAKE_MT}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Temporary installation prefix for tests against installed nvbench:
|
||||
set(tmp_install_prefix "${CMAKE_CURRENT_BINARY_DIR}/test_nvbench_install")
|
||||
@@ -32,6 +40,13 @@ function(nvbench_add_compile_test full_test_name_var subdir test_id)
|
||||
${ARGN}
|
||||
--test-command "${CMAKE_CTEST_COMMAND}" --output-on-failure
|
||||
)
|
||||
if (WIN32 AND NVBench_ENABLE_CUPTI AND nvbench_cupti_root)
|
||||
cmake_path(NATIVE_PATH nvbench_cupti_root cupti_native)
|
||||
cmake_path(NATIVE_PATH NVBench_EXECUTABLE_OUTPUT_DIR bin_native)
|
||||
set_tests_properties(${test_name} PROPERTIES
|
||||
ENVIRONMENT "PATH=${bin_native}\\;${cupti_native}\\lib64\\;$ENV{PATH}"
|
||||
)
|
||||
endif()
|
||||
set(${full_test_name_var} ${test_name} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -10,45 +10,53 @@ enable_testing()
|
||||
add_test(NAME test_bench COMMAND "$<TARGET_FILE:test_bench>" --timeout 1)
|
||||
add_test(NAME nvbench_ctl COMMAND "$<TARGET_FILE:nvbench::ctl>")
|
||||
|
||||
# Setup LD_LIBRARY_PATH for testing
|
||||
if (UNIX)
|
||||
set(ctl_lib_path "")
|
||||
set(cupti_lib_path "")
|
||||
# Setup runtime library paths for testing.
|
||||
# Unix uses LD_LIBRARY_PATH; Windows uses PATH for DLL lookup.
|
||||
get_property(nvbench_config TARGET nvbench::nvbench
|
||||
PROPERTY IMPORTED_CONFIGURATIONS
|
||||
)
|
||||
list(LENGTH nvbench_config num_configs)
|
||||
if (num_configs GREATER 1)
|
||||
message(WARNING
|
||||
"Multiple IMPORTED_CONFIGURATIONS for nvbench::nvbench. "
|
||||
"Picking the first one. This may cause issues."
|
||||
)
|
||||
list(GET nvbench_config 0 nvbench_config)
|
||||
endif()
|
||||
|
||||
# Need to find installed libnvbench.so for installed nvbench-ctl.
|
||||
# Not needed for build_tree test because of RUNPATH.
|
||||
if (TEST_TYPE STREQUAL "INSTALL_TREE")
|
||||
get_property(nvbench_config TARGET nvbench::nvbench
|
||||
PROPERTY IMPORTED_CONFIGURATIONS
|
||||
)
|
||||
set(nvbench_lib_dir "")
|
||||
# On Unix the build tree uses RUNPATH so only the install tree needs the path.
|
||||
# On Windows there is no RUNPATH so we always need the DLL directory.
|
||||
if (WIN32 OR TEST_TYPE STREQUAL "INSTALL_TREE")
|
||||
get_property(nvbench_lib TARGET nvbench::nvbench
|
||||
PROPERTY IMPORTED_LOCATION_${nvbench_config}
|
||||
)
|
||||
cmake_path(GET nvbench_lib PARENT_PATH nvbench_lib_dir)
|
||||
endif()
|
||||
|
||||
list(LENGTH nvbench_config num_configs)
|
||||
if (num_configs GREATER 1)
|
||||
message(WARNING
|
||||
"Multiple IMPORTED_CONFIGURATIONS for nvbench::nvbench. "
|
||||
"Picking the first one. This may cause issues."
|
||||
)
|
||||
list(GET nvbench_config 0 nvbench_config)
|
||||
endif()
|
||||
|
||||
get_property(ctl_lib_path TARGET nvbench::nvbench
|
||||
PROPERTY IMPORTED_LOCATION_${nvbench_config}
|
||||
)
|
||||
cmake_path(GET ctl_lib_path PARENT_PATH ctl_lib_path)
|
||||
endif()
|
||||
|
||||
# Need to add the CUPTI path to LD_LIBRARY_PATH to make sure CUPTI libraries
|
||||
# are found at runtime:
|
||||
if (TARGET nvbench::cupti)
|
||||
get_property(cupti_lib_path TARGET nvbench::cupti PROPERTY IMPORTED_LOCATION)
|
||||
cmake_path(GET cupti_lib_path PARENT_PATH cupti_lib_path)
|
||||
set(cupti_lib_dir "")
|
||||
if (TARGET nvbench::cupti)
|
||||
if (WIN32)
|
||||
get_property(cupti_lib TARGET nvbench::cupti PROPERTY IMPORTED_IMPLIB)
|
||||
else()
|
||||
get_property(cupti_lib TARGET nvbench::cupti PROPERTY IMPORTED_LOCATION)
|
||||
endif()
|
||||
cmake_path(GET cupti_lib PARENT_PATH cupti_lib_dir)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(lib_dirs "${nvbench_lib_dir}\\;${cupti_lib_dir}")
|
||||
set_property(TEST test_bench PROPERTY
|
||||
ENVIRONMENT "LD_LIBRARY_PATH=${cupti_lib_path}"
|
||||
ENVIRONMENT "PATH=${lib_dirs}\\;$ENV{PATH}"
|
||||
)
|
||||
set_property(TEST nvbench_ctl PROPERTY
|
||||
ENVIRONMENT "LD_LIBRARY_PATH=${ctl_lib_path}:${cupti_lib_path}"
|
||||
ENVIRONMENT "PATH=${lib_dirs}\\;$ENV{PATH}"
|
||||
)
|
||||
else()
|
||||
set_property(TEST test_bench PROPERTY
|
||||
ENVIRONMENT "LD_LIBRARY_PATH=${cupti_lib_dir}"
|
||||
)
|
||||
set_property(TEST nvbench_ctl PROPERTY
|
||||
ENVIRONMENT "LD_LIBRARY_PATH=${nvbench_lib_dir}:${cupti_lib_dir}"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user