CUDA 13.4 samples update - v13.4-public

Release 13.4 of the CUDA Samples supported by CUDA Toolkit 13.4.
See Changelog for more information.
This commit is contained in:
Dheemanth
2026-09-09 15:07:08 -07:00
committed by GitHub
parent b7c5481c55
commit 5443602d89
871 changed files with 6843 additions and 321849 deletions

View File

@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.20)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/Modules")
project(localityDomainsDrv LANGUAGES C CXX CUDA)
find_package(CUDAToolkit REQUIRED)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CUDA_ARCHITECTURES 75 80 86 87 89 90 100 110 120)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
if(ENABLE_CUDA_DEBUG)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -G") # enable cuda-gdb (may significantly affect performance on some targets)
else()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo") # add line information to all builds for debug tools (exclusive to -G option)
endif()
# Source file
# Add target for localityDomainsDrv
add_executable(localityDomainsDrv localityDomainsDrv.cpp)
target_compile_options(localityDomainsDrv PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--extended-lambda>)
target_compile_features(localityDomainsDrv PRIVATE cxx_std_17 cuda_std_17)
set_target_properties(localityDomainsDrv PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_include_directories(localityDomainsDrv PRIVATE
${CUDAToolkit_INCLUDE_DIRS}
)
target_link_libraries(localityDomainsDrv PUBLIC
CUDA::cuda_driver
)
# Include installation configuration
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/InstallSamples.cmake)
setup_samples_install()

View File

@@ -0,0 +1,86 @@
# localityDomainsDrv - CUDA Driver API Locality Domains
## Description
This CUDA Driver API sample demonstrates localized compute and memory resources.
Compute is localized by splitting a device's SM resources into locality domain partitions and constructing a green context and stream per locality domain. Memory is localized by creating a localized memory region and mapping it.
## What You'll Learn
How to:
- query a device's locality domain count and SM count per locality domain
- partition SM resources by locality domain ID
- create green contexts and streams from localized SM partitions
- create and map physical allocations in locality domains
- query the locality domain associated with a stream and device pointer
## Key Concepts
- **Locality domain** — a portion of a GPU that contains streaming multiprocessors (SMs) and device memory.
**Green context** — an execution context created from a selected subset of device resources.
- **Virtual memory management** — separate control over virtual addresses, physical allocations, mappings, and access permissions.
## Key APIs
### CUDA Driver
- `cuDeviceGetAttribute` — query the number of locality domains and SMs per domain
- `cuDevSmResourceSplit` — partition the device's SM resources
- `cuMemCreate` — create localized physical memory
- `cuStreamGetDevResource` — inspect stream locality
- `cuPointerGetAttribute` — inspect allocation locality
## Requirements
### Hardware
- NVIDIA GPU that supports locality domains
### Software
- CUDA Toolkit and NVIDIA driver with locality domain support
- Linux or QNX on x86_64 or aarch64
- CMake 3.20 or newer
- A C++17-capable host compiler
## How to Build
See the [top-level README](../../../README.md#building-cuda-samples) for full build instructions, including how to build all samples or a single sample standalone.
## How to Run
```bash
./localityDomainsDrv
```
No command-line arguments are required. The sample always runs on device 0.
## Expected Output
The number of locality domains and SMs depends on the GPU. A run has the following form:
```text
CUDA Driver API locality domains sample
Locality domain count: <domain count>
SMs per locality domain: <SM count>
Device SMs split into <domain count> partitions
- result[0]: .localityDomainId = 0, .smCount = <SM count>
...
Green context stream 0 is localized to locality domain 0
...
Allocation granularity per chunk: <bytes> bytes
Reserved VA range size: <bytes> bytes
allocation 0x<address> is localized to locality domain 0
...
```
## Files
- `localityDomainsDrv.cpp` — Driver API example
- `README.md` — this file
- `CMakeLists.txt` — build configuration
## See Also
- [CUDA Driver API](https://docs.nvidia.com/cuda/cuda-driver-api/)
- [CUDA Programming Guide](https://docs.nvidia.com/cuda/cuda-programming-guide/)

View File

@@ -0,0 +1,188 @@
/* Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of NVIDIA CORPORATION nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This sample demonstrates CUDA locality domains using the Driver API.
* It creates one green context and stream per reported locality domain and
* maps one virtual-address chunk to each locality domain, then queries the
* placement back from both the stream resource and the device pointer.
*/
#include <cstring>
#include <cuda.h>
#include <iomanip>
#include <iostream>
#include <vector>
int main()
{
std::cout << "CUDA Driver API locality domains sample" << std::endl;
cuInit(0);
CUdevice dev;
cuDeviceGet(&dev, 0);
CUctxCreateParams ctxCreateParams = {};
CUcontext context;
cuCtxCreate(&context, &ctxCreateParams, 0, dev);
// Device information
int localityDomainCount = 0;
{
cuDeviceGetAttribute(&localityDomainCount, CU_DEVICE_ATTRIBUTE_LOCALITY_DOMAIN_COUNT, dev);
int localityDomainSmCount = 0;
cuDeviceGetAttribute(&localityDomainSmCount, CU_DEVICE_ATTRIBUTE_LOCALITY_DOMAIN_MULTIPROCESSOR_COUNT, dev);
std::cout << "Locality domain count: " << localityDomainCount << std::endl;
std::cout << "SMs per locality domain: " << localityDomainSmCount << std::endl;
}
// Construct localized green contexts and streams
std::vector<CUgreenCtx> greenContexts(localityDomainCount);
std::vector<CUstream> streams(localityDomainCount);
{
CUdevResource smResource;
cuDeviceGetDevResource(dev, &smResource, CU_DEV_RESOURCE_TYPE_SM);
std::vector<CU_DEV_SM_RESOURCE_GROUP_PARAMS> params(localityDomainCount);
for (size_t i = 0; i < localityDomainCount; i++) {
std::memset(&params[i], 0, sizeof(params[i]));
params[i].flags = CU_DEV_SM_RESOURCE_GROUP_LOCALITY_DOMAIN_ID;
params[i].localityDomainId = static_cast<unsigned int>(i);
}
std::vector<CUdevResource> result(localityDomainCount);
CUdevResource remainder = {};
cuDevSmResourceSplit(result.data(), localityDomainCount, &smResource, &remainder, 0, params.data());
std::cout << "Device SMs split into " << localityDomainCount << " partitions" << std::endl;
for (size_t i = 0; i < localityDomainCount; i++) {
std::cout << " - result[" << i << "]: .localityDomainId = " << result[i].sm.localityDomainId
<< ", .smCount = " << result[i].sm.smCount << std::endl;
}
if (remainder.sm.smCount > 0) {
std::cout << " - remainder: .localityDomainId = none, .smCount = " << remainder.sm.smCount << std::endl;
}
for (size_t i = 0; i < localityDomainCount; i++) {
CUdevResourceDesc desc;
cuDevResourceGenerateDesc(&desc, &result[i], 1);
cuGreenCtxCreate(&greenContexts[i], desc, dev, CU_GREEN_CTX_DEFAULT_STREAM);
cuGreenCtxStreamCreate(&streams[i], greenContexts[i], CU_STREAM_NON_BLOCKING, 0);
}
}
// Inspect locality of streams
{
for (size_t i = 0; i < localityDomainCount; i++) {
CUdevResource streamSmResource;
cuStreamGetDevResource(streams[i], &streamSmResource, CU_DEV_RESOURCE_TYPE_SM);
bool isStreamLocalized = (streamSmResource.sm.flags & CU_DEV_SM_RESOURCE_GROUP_LOCALITY_DOMAIN_ID) != 0;
std::cout << "Green context stream " << i << " ";
if (isStreamLocalized) {
unsigned int streamLocalityDomain = streamSmResource.sm.localityDomainId;
std::cout << "is localized to locality domain " << streamLocalityDomain << std::endl;
}
else {
std::cout << "is not localized" << std::endl;
}
}
}
// Allocate localized memory
CUdeviceptr allocationBase = 0;
size_t allocationGranularity = 0;
size_t allocationSize = 0;
std::vector<CUdeviceptr> localizedPtrs(localityDomainCount);
{
{
CUmemAllocationProp prop = {};
prop.type = CU_MEM_ALLOCATION_TYPE_PINNED;
prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE_LOCALITY_DOMAIN;
prop.location.localized.deviceId = static_cast<unsigned char>(dev);
prop.location.localized.localityDomainId = 0;
cuMemGetAllocationGranularity(&allocationGranularity, &prop, CU_MEM_ALLOC_GRANULARITY_MINIMUM);
}
std::cout << "Allocation granularity per chunk: " << allocationGranularity << " bytes" << std::endl;
allocationSize = allocationGranularity * localityDomainCount;
cuMemAddressReserve(&allocationBase, allocationSize, 0, 0, 0);
std::cout << "Reserved VA range size: " << allocationSize << " bytes" << std::endl;
for (size_t i = 0; i < localityDomainCount; i++) {
localizedPtrs[i] = allocationBase + i * allocationGranularity;
CUmemGenericAllocationHandle handle;
CUmemAllocationProp prop = {};
prop.type = CU_MEM_ALLOCATION_TYPE_PINNED;
prop.location.type = CU_MEM_LOCATION_TYPE_DEVICE_LOCALITY_DOMAIN;
prop.location.localized.deviceId = static_cast<unsigned char>(dev);
prop.location.localized.localityDomainId = static_cast<unsigned char>(i);
cuMemCreate(&handle, allocationGranularity, &prop, 0);
cuMemMap(localizedPtrs[i], allocationGranularity, 0, handle, 0);
CUmemAccessDesc desc = {};
desc.location.type = CU_MEM_LOCATION_TYPE_DEVICE_LOCALITY_DOMAIN;
desc.location.localized.deviceId = static_cast<unsigned char>(dev);
desc.location.localized.localityDomainId = static_cast<unsigned char>(i);
desc.flags = CU_MEM_ACCESS_FLAGS_PROT_READWRITE;
cuMemSetAccess(localizedPtrs[i], allocationGranularity, &desc, 1);
cuMemRelease(handle);
}
}
// Inspect locality of allocations
{
for (CUdeviceptr ptr : localizedPtrs) {
unsigned int localityDomainId = 0;
cuPointerGetAttribute(&localityDomainId, CU_POINTER_ATTRIBUTE_LOCALITY_DOMAIN_ORDINAL, ptr);
std::cout << "allocation 0x" << std::hex << ptr << std::dec;
if (localityDomainId == -1) {
std::cout << " is not localized." << std::endl;
}
else {
std::cout << " is localized to locality domain " << localityDomainId << std::endl;
}
}
}
// Clean up
for (CUstream stream : streams) {
cuStreamDestroy(stream);
}
for (CUgreenCtx greenContext : greenContexts) {
cuGreenCtxDestroy(greenContext);
}
for (CUdeviceptr localizedPtr : localizedPtrs) {
cuMemUnmap(localizedPtr, allocationGranularity);
}
cuMemAddressFree(allocationBase, allocationSize);
cuCtxDestroy(context);
return 0;
}