Skip to content
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
23b445a
Add Windows support
mfranzrebsal May 7, 2026
787e435
Windows support: revert CI specific changes
mfranzrebsal May 13, 2026
78b674b
Re- Enable NVBench Windows build job
oleksandr-pavlyk May 15, 2026
460e14f
Install CUDA Profiler API into toolkit
oleksandr-pavlyk May 16, 2026
c6cd097
Add intall_cuda_profiler_api.ps1
oleksandr-pavlyk May 16, 2026
f8c0554
Inform MSVC that static library export main
oleksandr-pavlyk May 16, 2026
f402b57
Review feedback to PowerShell script
oleksandr-pavlyk May 17, 2026
71eacdc
Fix how CMAKE_CUDA_HOST_COMPILER is set in call to cmake
oleksandr-pavlyk May 17, 2026
cc209bb
Filter out empty directories LD_LIBRARY_PATH/PATH
oleksandr-pavlyk May 17, 2026
d980c2a
Check that cudaVersion and :CUDA_PATH are consistent
oleksandr-pavlyk May 17, 2026
6c44ec6
Do not overwrite ENVIRONMENT property with empty values
oleksandr-pavlyk May 17, 2026
7f2a6dc
Implement retry logic in downloading of CUDA Profiler API
oleksandr-pavlyk May 17, 2026
287d041
Strengthen publisher verification of downloaded artifact
oleksandr-pavlyk May 17, 2026
9f8bf81
Prepend new folders to LD_LIBRARY_PATH, do not overwrite
oleksandr-pavlyk May 17, 2026
adabe4a
Implement timeout, fail on 40x HTTP response code
oleksandr-pavlyk May 17, 2026
a5b3e97
USE ENVIRONMENT_MODIFICATION property, not ENVIRONMENT
oleksandr-pavlyk May 17, 2026
c6347b5
escape environment modification values
oleksandr-pavlyk May 17, 2026
919468f
Fix cmake script error breaking the build
oleksandr-pavlyk May 17, 2026
177c7b0
Added recommented timeout to Invoke-WebRequest
oleksandr-pavlyk May 17, 2026
f83429a
Set cmake_minimum_required version to 3.30.4, consistent with main pr…
oleksandr-pavlyk May 17, 2026
ccfa1b5
Pass NVBENCH environment variables through docker for Windows build
oleksandr-pavlyk May 17, 2026
cb00417
Export IMPORTLIB_LOCATION for CUPTI on Windows and use in testing pro…
oleksandr-pavlyk May 18, 2026
28376eb
Add Zc:preprocessor to host compiler on Windows. Configure runtime en…
oleksandr-pavlyk May 18, 2026
03b8f02
Better fix to add /Zc:preprocessor that also propagates to header tes…
oleksandr-pavlyk May 18, 2026
5ddc847
Address code rabbit concern
oleksandr-pavlyk May 18, 2026
76626e4
Validate before casting in PowerShell script
oleksandr-pavlyk May 18, 2026
3944851
decouple nvbench runtime path setup from cupti target detection
oleksandr-pavlyk May 18, 2026
0c29705
Normalize multiple ARCH args
oleksandr-pavlyk May 18, 2026
806f163
Better validation of gpu_args parameter
oleksandr-pavlyk May 18, 2026
90c2386
use get_imported_location to get CUPTI library to improve multi-confi…
oleksandr-pavlyk May 18, 2026
737bb58
Validation of combinations of gpu, run_tests and device_testing
oleksandr-pavlyk May 18, 2026
fcfb9b6
Resolve code-rabbit concern in handling multiple imported configurati…
oleksandr-pavlyk May 18, 2026
35a0d59
Reject GPU requests for forks
oleksandr-pavlyk May 18, 2026
5a08b81
Prevents installing cuda_profiler_api.h into one toolkit while CMake …
oleksandr-pavlyk May 18, 2026
0be5c9c
Fail fast for deterministic client errors returned by download request
oleksandr-pavlyk May 18, 2026
2dba74d
more robust imported_location computation
oleksandr-pavlyk May 18, 2026
fedba46
Make Linux also use ENVIRONMENT_MODIFICATION to simplify code
oleksandr-pavlyk May 18, 2026
02a4a7e
run_tests=false is not allows when device_testing=true
oleksandr-pavlyk May 18, 2026
2a904bb
Specify Windows CUDA toolkit version major.minor.patch, derive devcon…
oleksandr-pavlyk May 18, 2026
48a77bb
Handle edge case when multiple CUPTI dlls exist, pick up, warn, do no…
oleksandr-pavlyk May 18, 2026
639e9ae
Always specify -DNVBench_ENABLE_DEVICE_TESTING=VAL per value of
oleksandr-pavlyk May 18, 2026
ccde292
Back to cuda major.minor being input
oleksandr-pavlyk May 18, 2026
0ab9320
Remove parameters intended to enable testing builds on Windows. Defer…
oleksandr-pavlyk May 18, 2026
c55f7f2
Handle import nvbench::nvbench the same as nvbench target in NVBenchC…
oleksandr-pavlyk May 18, 2026
dd0a9b0
Forward cmake variables only if set
oleksandr-pavlyk May 18, 2026
d1a50a5
Use UTF-8 encoding when appending to GITHUB_OUTPUT
oleksandr-pavlyk May 18, 2026
697f387
Avoid power-shell footgun where local variable shadows builtin variab…
oleksandr-pavlyk May 18, 2026
307ecf5
enable device testing parameter in build_nvbench, passed as True by w…
oleksandr-pavlyk May 18, 2026
9cd2c0f
Lower CMake version required as much as possible
oleksandr-pavlyk May 18, 2026
9bfe117
LINKER:/INCLUDE:main for proper CUDA link driver routing
oleksandr-pavlyk May 18, 2026
2d004ec
Add conda-specific hints for find_library call to find CUPTI
oleksandr-pavlyk May 18, 2026
25ab217
test_export must require 3.22 version
oleksandr-pavlyk May 18, 2026
4ece868
Delete unused function Test-Preset
oleksandr-pavlyk May 18, 2026
3cd661a
Guard the CUPTI runtime path extraction
oleksandr-pavlyk May 18, 2026
1cc8d01
use the config-aware generator expression for all runtime targets
oleksandr-pavlyk May 18, 2026
9486121
Deduplicate WINDOWS_CI_IMAGE construction
oleksandr-pavlyk May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ jobs:

- name: Build NVBench
env:
NVBENCH_WINDOWS_CUDA: ${{ inputs.cuda }}
NVBENCH_WINDOWS_STD: ${{ inputs.std }}
NVBENCH_WINDOWS_ARCH: ${{ inputs.arch }}
run: |
Expand All @@ -131,7 +132,8 @@ jobs:
@"
`$ErrorActionPreference = 'Stop'
git config --global --add safe.directory '$containerRepo'
& '$containerRepo/ci/windows/build_nvbench.ps1' -std '$env:NVBENCH_WINDOWS_STD' -arch '$env:NVBENCH_WINDOWS_ARCH'
& '$containerRepo/ci/windows/install_cuda_profiler_api.ps1' -cudaVersion "`$env:NVBENCH_WINDOWS_CUDA"
& '$containerRepo/ci/windows/build_nvbench.ps1' -std "`$env:NVBENCH_WINDOWS_STD" -arch "`$env:NVBENCH_WINDOWS_ARCH"
exit `$LASTEXITCODE
"@ | Set-Content -Path $script -Encoding UTF8

Expand All @@ -152,6 +154,9 @@ jobs:
"--env", "GITHUB_REPOSITORY=$env:GITHUB_REPOSITORY",
"--env", "GITHUB_RUN_ID=$env:GITHUB_RUN_ID",
"--env", "GITHUB_SHA=$env:GITHUB_SHA",
"--env", "NVBENCH_WINDOWS_ARCH=$env:NVBENCH_WINDOWS_ARCH",
"--env", "NVBENCH_WINDOWS_CUDA=$env:NVBENCH_WINDOWS_CUDA",
"--env", "NVBENCH_WINDOWS_STD=$env:NVBENCH_WINDOWS_STD",
"--env", "SCCACHE_BUCKET=$env:SCCACHE_BUCKET",
"--env", "SCCACHE_IDLE_TIMEOUT=$env:SCCACHE_IDLE_TIMEOUT",
"--env", "SCCACHE_REGION=$env:SCCACHE_REGION",
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ jobs:

nvbench-windows:
name: NVBench Windows CUDA${{ matrix.config.cuda }} ${{ matrix.config.host }} C++${{ matrix.config.std }}
# TODO: Re-enable after https://github.com/NVIDIA/nvbench/pull/354 fixes the Windows build.
if: false
permissions:
id-token: write
contents: read
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
181 changes: 181 additions & 0 deletions ci/windows/install_cuda_profiler_api.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Param(
[Parameter(Mandatory = $false)]
[Alias("cudaVersion")]
[string]$CUDA_VERSION = ""
)

$ErrorActionPreference = "Stop"

function Get-CudaVersionFromPath {
Param(
[Parameter(Mandatory = $false)]
[string]$Path = ""
)

if ($Path -and $Path -match "v(?<version>\d+\.\d+)[\\/]?$") {
return $Matches.version
}

return ""
}

function Assert-NvidiaAuthenticodeSignature {
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Path
)

$signature = Get-AuthenticodeSignature -FilePath $Path
if ($signature.Status -ne "Valid") {
throw "Invalid Authenticode signature for '$Path': $($signature.Status) $($signature.StatusMessage)"
}

$expectedPublisher = "NVIDIA Corporation"
$publisher = $signature.SignerCertificate.GetNameInfo(
[System.Security.Cryptography.X509Certificates.X509NameType]::SimpleName,
$false
)
if ($publisher -ne $expectedPublisher) {
throw "Unexpected signer for '$Path': $publisher"
}

Write-Host "Validated Authenticode signature for '$Path': $publisher"
}

function Get-HttpStatusCodeFromError {
Param(
[Parameter(Mandatory = $true)]
$ErrorRecord
)

$responseProperty = $ErrorRecord.Exception.PSObject.Properties["Response"]
if (-not $responseProperty) {
return $null
}

$response = $responseProperty.Value
if ($null -eq $response) {
return $null
}

$statusCodeProperty = $response.PSObject.Properties["StatusCode"]
if (-not $statusCodeProperty) {
return $null
}

return [int]$statusCodeProperty.Value
}

function Invoke-WebRequestWithRetry {
Param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$Uri,

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$OutFile,

[Parameter(Mandatory = $false)]
[ValidateRange(1, 10)]
[int]$MaxAttempts = 3
)

for ($attempt = 1; $attempt -le $MaxAttempts; $attempt++) {
try {
Remove-Item $OutFile -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -TimeoutSec 300
return
} catch {
$statusCode = Get-HttpStatusCodeFromError -ErrorRecord $_
if ($statusCode -ge 400 -and $statusCode -lt 500) {
throw "Download failed with non-retryable HTTP status $statusCode from '$Uri'. $_"
}
Comment thread
oleksandr-pavlyk marked this conversation as resolved.

if ($attempt -eq $MaxAttempts) {
throw
}

$delaySeconds = 5 * $attempt
Write-Warning "Download failed on attempt $attempt of $MaxAttempts. Retrying in $delaySeconds seconds. $_"
Start-Sleep -Seconds $delaySeconds
}
}
}

if (-not $CUDA_VERSION) {
$CUDA_VERSION = Get-CudaVersionFromPath -Path $env:CUDA_PATH
if (-not $CUDA_VERSION) {
throw "Could not determine CUDA version. Provide -cudaVersion or set CUDA_PATH to a path ending in v<major>.<minor>."
}
}

$version = [Version]$CUDA_VERSION
$major = $version.Major
$minor = $version.Minor
$build = $version.Build

if ($build -lt 0) {
$build = 0
}
Comment thread
oleksandr-pavlyk marked this conversation as resolved.
Outdated

$mmbVersionTag = "${major}.${minor}.${build}"
$mmVersionTag = "${major}.${minor}"

if ($env:CUDA_PATH) {
$cudaPathVersion = Get-CudaVersionFromPath -Path $env:CUDA_PATH
if (-not $cudaPathVersion) {
throw "CUDA_PATH is set but does not end in v<major>.<minor>: $env:CUDA_PATH"
}
if ($cudaPathVersion -ne $mmVersionTag) {
throw "CUDA_PATH points to CUDA $cudaPathVersion, but CUDA $mmVersionTag was requested."
}
$cudaRoot = $env:CUDA_PATH
} else {
$cudaRoot = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v$mmVersionTag"
}
$profilerHeader = "$cudaRoot\include\cuda_profiler_api.h"

if (Test-Path $profilerHeader) {
Write-Host "CUDA Profiler API is already installed: $profilerHeader"
return
}
Comment thread
oleksandr-pavlyk marked this conversation as resolved.

$component = "cuda_profiler_api_$mmVersionTag"
$cudaMajorUri = "${mmbVersionTag}/network_installers/cuda_${mmbVersionTag}_windows_network.exe"
$cudaVersionUrl = "https://developer.download.nvidia.com/compute/cuda/$cudaMajorUri"
$installer = Join-Path $env:TEMP "cuda_${mmbVersionTag}_windows_network.exe"

Write-Host "Installing CUDA component: $component"
Write-Host "Downloading CUDA network installer: $cudaVersionUrl"
Invoke-WebRequestWithRetry -Uri $cudaVersionUrl -OutFile $installer
Assert-NvidiaAuthenticodeSignature -Path $installer

$installerTimeoutSeconds = 900
$process = $null
try {
$process = Start-Process -PassThru -FilePath $installer -ArgumentList @("-s", $component)
if (-not $process.WaitForExit($installerTimeoutSeconds * 1000)) {
Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue
throw "CUDA network installer timed out after $installerTimeoutSeconds seconds."
}

if ($process.ExitCode -ne 0) {
throw "CUDA network installer failed with exit code $($process.ExitCode)."
}
} finally {
if ($process) {
$process.Dispose()
}
Remove-Item $installer -ErrorAction SilentlyContinue
}

if (-not (Test-Path $profilerHeader)) {
throw "CUDA Profiler API installation completed, but header was not found: $profilerHeader"
}

Write-Host "CUDA Profiler API installed: $profilerHeader"
71 changes: 67 additions & 4 deletions cmake/NVBenchCUPTI.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,84 @@ endif()
# - The dll locations are not specified
# - Dependent libraries nvperf_* are not linked.
# So we create our own targets:
function(nvbench_find_windows_cupti_runtime_library out_var dep_name library_path)
cmake_path(GET library_path PARENT_PATH library_dir)
set(runtime_search_dirs "${library_dir}")

if ("${library_dir}" MATCHES "/Library/lib/x64$")
cmake_path(GET library_dir PARENT_PATH conda_lib_dir)
cmake_path(GET conda_lib_dir PARENT_PATH conda_library_dir)
list(APPEND runtime_search_dirs "${conda_library_dir}/bin")
elseif ("${library_dir}" MATCHES "/Library/lib$")
cmake_path(GET library_dir PARENT_PATH conda_library_dir)
list(APPEND runtime_search_dirs "${conda_library_dir}/bin")
endif()

list(REMOVE_DUPLICATES runtime_search_dirs)

foreach(runtime_search_dir IN LISTS runtime_search_dirs)
if ("${dep_name}" STREQUAL "cupti")
file(GLOB runtime_libraries LIST_DIRECTORIES false
"${runtime_search_dir}/cupti64_*.dll"
)
if (NOT runtime_libraries)
file(GLOB runtime_libraries LIST_DIRECTORIES false
"${runtime_search_dir}/cupti.dll"
)
endif()
else()
file(GLOB runtime_libraries LIST_DIRECTORIES false
"${runtime_search_dir}/${dep_name}.dll"
)
endif()

if (runtime_libraries)
list(LENGTH runtime_libraries num_runtime_libraries)
if (num_runtime_libraries GREATER 1)
message(FATAL_ERROR
"Found multiple runtime DLLs for ${dep_name}: ${runtime_libraries}"
)
endif()

list(GET runtime_libraries 0 runtime_library)
set(${out_var} "${runtime_library}" PARENT_SCOPE)
return()
endif()
endforeach()

message(FATAL_ERROR
"Could not find the runtime DLL for ${dep_name}. "
"Searched these directories: ${runtime_search_dirs}"
)
endfunction()

function(nvbench_add_cupti_dep dep_name)
string(TOLOWER ${dep_name} dep_name_lower)
string(TOUPPER ${dep_name} dep_name_upper)

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)
nvbench_find_windows_cupti_runtime_library(
NVBench_${dep_name_upper}_DLL
${dep_name_lower}
"${NVBench_${dep_name_upper}_LIBRARY}"
)
set_target_properties(nvbench::${dep_name_lower} PROPERTIES
IMPORTED_IMPLIB "${NVBench_${dep_name_upper}_LIBRARY}"
IMPORTED_LOCATION "${NVBench_${dep_name_upper}_DLL}"
)
else()
set_target_properties(nvbench::${dep_name_lower} PROPERTIES
IMPORTED_LOCATION "${NVBench_${dep_name_upper}_LIBRARY}"
)
endif()
endfunction()

nvbench_add_cupti_dep(cupti)
Expand Down
18 changes: 16 additions & 2 deletions cmake/NVBenchConfigTarget.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
)
Expand Down
4 changes: 4 additions & 0 deletions nvbench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ nvbench_config_target(nvbench.main)
target_compile_definitions(nvbench.main PRIVATE NVBENCH_NO_IMPLICIT_SYSTEM_HEADER)
# Propagate `nvbench` to consumers but keep NVBench's own build warning-visible.
target_link_libraries(nvbench.main PUBLIC nvbench)
if (MSVC)
# inform MSVC that library provides main
target_link_options(nvbench.main INTERFACE "/INCLUDE:main")
endif()
# Ensure CUDA/CUPTI/NVML include dirs are visible for nvbench.main's build.
target_link_libraries(nvbench.main PRIVATE ${ctk_libraries})
# Add NVBench's headers privately so the main library itself sees warnings.
Expand Down
4 changes: 4 additions & 0 deletions nvbench/config.cuh.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions testing/axes_metadata.cu
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <fmt/format.h>

#include <algorithm>
#include <iterator>
#include <string_view>

#include "test_asserts.cuh"
Expand Down
Loading