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

@@ -71,8 +71,8 @@ find_file(LIBNVVM_HOME nvvm PATHS "$ENV{LIBNVVM_HOME}" "${CUDA_HOME}")
message(STATUS "Using LIBNVVM_HOME: ${LIBNVVM_HOME}")
# Find libNVVM and nvvm.h.
# (Linux: nvvm/lib64, windows: nvvm/lib/x64)
find_library(NVVM_LIB nvvm PATHS "${LIBNVVM_HOME}/lib64" "${LIBNVVM_HOME}/lib/x64")
# (Linux: nvvm/lib64, windows: nvvm/lib/x64, windows on arm:nvvm/lib/arm64)
find_library(NVVM_LIB nvvm PATHS "${LIBNVVM_HOME}/lib64" "${LIBNVVM_HOME}/lib/x64" "${LIBNVVM_HOME}/lib/arm64")
find_file(NVVM_H nvvm.h PATH "${LIBNVVM_HOME}/include")
get_filename_component(NVVM_INCLUDE_DIR ${NVVM_H} DIRECTORY)
include_directories(${NVVM_INCLUDE_DIR})
@@ -110,7 +110,9 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/common/include")
# invocation. See the note about "cuda-c-linking" in README.md.
if (ENABLE_CUDA_C_LINKING_SAMPLE)
# Include the LLVM dev package which is required to build cuda-c-linking.
find_package(LLVM CONFIG PATHS "$ENV{LLVM_HOME}")
# LLVM_HOME is a HINTS entry rather than a PATHS one so that it is searched
# before the system directories, letting it select among installed LLVMs.
find_package(LLVM CONFIG HINTS "$ENV{LLVM_HOME}")
if (LLVM_FOUND)
add_subdirectory(cuda-c-linking)
else ()

View File

@@ -71,27 +71,50 @@ update the CMake invocation in utils/build.sh or build.bat by adding
A Note About the cuda-c-linking Sample
--------------------------------------
This sample requires a development package (or locally-built) LLVM library
between versions 7 to 14 inclusive. LLVM 15 defaults to using opaque pointers,
which are not supported in libNVVM for pre-Blackwell architectures.
This sample requires a development package (or locally-built) LLVM library,
version 7 or newer.
The LLVM_HOME environment variable is required for users who wish to build the
cuda-c-linking sample and have a locally built copy of LLVM that they wish to
use. That sample requires the development package of LLVM with the LLVM header
files and libraries.
Which LLVM versions are usable depends on the GPU the sample runs on. LLVM 15
and newer emit opaque pointers, and libNVVM accepts those only for Blackwell
and later architectures; older architectures require the typed pointers that
LLVM 14 and older emit. The sample queries libNVVM for the LLVM IR version its
target accepts, so building against a newer LLVM and running on a pre-Blackwell
device reports the requirement and exits with code 2 rather than failing. Use
LLVM 7 to 14 if you need a single build that runs on any supported device.
The LLVM_HOME environment variable selects which LLVM to build against. It is
required for users who have a locally built copy of LLVM they wish to use, and
it also picks between installed versions: several LLVM versions install side by
side, so a newer default LLVM does not prevent building this sample against an
older one. With more than one installed and LLVM_HOME unset, which of them is
found is unspecified, so set it explicitly. Whichever copy is used has to be a
development install, with the LLVM header files and libraries.
If the LLVM dependencies are met, the user can enable the building of this
sample by setting the CMake variable "ENABLE_CUDA_C_LINKING_SAMPLE" from either
the command line invocation of CMake or by modifying the CMakeLists.txt in this
directory.
Windows users should download LLVM 14 sources from llvm.org and build+install
Windows users should download LLVM sources from llvm.org and build+install
LLVM locally. Using the llvm.org provided Windows installer lacks some of
the required components the cuda-c-linking sample depends on.
For Ubuntu users, the "llvm-dev" package contains the LLVM headers and libraries
this sample requires, the user should not have to explicitly define an LLVM_HOME
in this case.
For Ubuntu users, the "llvm-dev" package contains the LLVM headers and
libraries this sample requires, and is found without any further configuration.
Note that "llvm-dev" is an unversioned metapackage that tracks the
distribution's current LLVM: on Ubuntu 24.04 it installs "llvm-18-dev", which
runs only on Blackwell and later. To build for an older device, add the
versioned package and select it explicitly:
```bash
sudo apt install llvm-14-dev
LLVM_HOME=/usr/lib/llvm-14 cmake -S . -B build -DENABLE_CUDA_C_LINKING_SAMPLE=1
```
LLVM 15 and newer reference zstd from their CMake package, which the Ubuntu
"llvm-*-dev" packages do not pull in. Install "libzstd-dev" alongside them,
or CMake fails while loading the LLVM package with a missing
"zstd::libzstd_shared" target.
Windows users will want to build this sample using the same CMake build mode
as they built LLVM with. For instance if they built LLVM in Release mode,

View File

@@ -25,26 +25,46 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
message(STATUS "Found LLVM Version ${LLVM_PACKAGE_VERSION}")
if (LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL "15" OR
LLVM_PACKAGE_VERSION VERSION_LESS "7")
message(STATUS "The cuda-c-linking sample is expected to build with "
"LLVM development libraries v7 to v14, opaque pointers are "
"not supported in libNVVM for pre-Blackwell architectures.")
if (LLVM_PACKAGE_VERSION VERSION_LESS "7")
message(STATUS "The cuda-c-linking sample requires LLVM development "
"libraries v7 or newer.")
return()
endif ()
if (LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL "15")
message(STATUS "LLVM 15 and newer emit opaque pointers, which libNVVM "
"accepts only for Blackwell and later architectures. The "
"cuda-c-linking sample will build, and reports the "
"requirement at run time if the device is older. Build "
"against LLVM 14 or older to run on pre-Blackwell devices.")
endif ()
add_executable(cuda-c-linking cuda-c-linking.cpp)
# LLVM 16 and newer headers use C++17 constructs, so build the sample as C++17
# when they are in use. Older LLVM versions keep the compiler default.
if (LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL "16")
target_compile_features(cuda-c-linking PRIVATE cxx_std_17)
endif ()
add_test(NAME cuda-c-linking
COMMAND cuda-c-linking
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
# The sample exits with 2 when the device cannot accept the IR this build
# emits, which is a requirement it does not meet rather than a failure.
set_tests_properties(cuda-c-linking PROPERTIES SKIP_RETURN_CODE 2)
target_link_libraries(cuda-c-linking ${NVVM_LIB} ${CUDA_LIB})
# See https://llvm.org/docs/CMake.html#developing-llvm-passes-out-of-source
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
include_directories(${LLVM_INCLUDE_DIRS})
llvm_map_components_to_libnames(llvm_libs core support)
# Distributions often ship LLVM only as one shared library instead of the
# per-component static libraries, so link that library when it is in use.
if (LLVM_LINK_LLVM_DYLIB)
set(llvm_libs LLVM)
else ()
llvm_map_components_to_libnames(llvm_libs core support)
endif ()
target_link_libraries(cuda-c-linking ${llvm_libs})
if (UNIX)

View File

@@ -27,6 +27,21 @@ This sample is optionally built as part of the libnvvm samples from the CUDA
samples tree. Please see the README file at the root of the libnvvm samples
for build instructions.
It requires the LLVM development headers and libraries, version 7 or newer.
LLVM 15 and newer emit opaque pointers, which libNVVM accepts only for
Blackwell and later architectures, so such a build cannot run on an older GPU:
$ ./cuda-c-linking
Using CUDA Device [0]: NVIDIA L4
Device Compute Capability: 8.9
This sample was built against LLVM 18, which emits opaque pointers, but
libNVVM accepts only LLVM 7 IR for compute_89. Build against LLVM 14 or
older to run on this device, or run on a Blackwell or later device.
The sample exits with code 2 in that case, reporting an unmet requirement
rather than a failure. Building against LLVM 7 to 14 produces a binary that
runs on any device this sample supports.
Usage
-----

View File

@@ -27,6 +27,7 @@
#include <cassert>
#include <cuda.h>
#include <llvm/ADT/StringExtras.h>
#include <llvm/Config/llvm-config.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
@@ -35,6 +36,9 @@
#include <llvm/Support/Path.h>
#include <llvm/Support/Program.h>
#include <llvm/Support/raw_ostream.h>
#if LLVM_VERSION_MAJOR >= 21
#include <llvm/TargetParser/Triple.h>
#endif
#include <memory>
#include <nvvm.h>
#include <string>
@@ -67,7 +71,9 @@ static void __checkCudaErrors(CUresult err, const char *filename, int line)
((CUDA_SUCCESS == res) ? ename : "Unknown"),
filename,
line);
exit(err);
// Exit with EXIT_FAILURE rather than the error code, which 'main'
// reserves to report an unmet requirement.
exit(EXIT_FAILURE);
}
}
@@ -76,10 +82,14 @@ void checkNVVMCall(nvvmResult res)
{
if (res != NVVM_SUCCESS) {
errs() << "libnvvm call failed\n";
exit(res);
exit(EXIT_FAILURE);
}
}
// The libNVVM architecture string for a compute capability, e.g. 10.0 becomes
// "compute_100".
std::string computeArch(int devMajor, int devMinor) { return "compute_" + utostr(devMajor) + utostr(devMinor); }
/// generateModule - Generate and LLVM IR module that calls an
/// externally-defined function
std::unique_ptr<Module> generateModule(LLVMContext &context)
@@ -89,13 +99,22 @@ std::unique_ptr<Module> generateModule(LLVMContext &context)
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-"
"f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:"
"64");
#if LLVM_VERSION_MAJOR >= 21
// LLVM 21 dropped the overload that takes the triple as a string.
mod->setTargetTriple(Triple("nvptx64-nvidia-cuda"));
#else
mod->setTargetTriple("nvptx64-nvidia-cuda");
#endif
// Get pointers to some commonly-used types.
Type *voidTy = Type::getVoidTy(context);
Type *floatTy = Type::getFloatTy(context);
Type *i32Ty = Type::getInt32Ty(context);
Type *floatGenericPtrTy = PointerType::get(floatTy, /* address space */ 0);
Type *voidTy = Type::getVoidTy(context);
#if LLVM_VERSION_MAJOR >= 17
// Pointers are opaque from LLVM 15 on, and LLVM 17 dropped the overload
// that takes a pointee type. The resulting IR spells this type 'ptr'.
Type *floatGenericPtrTy = PointerType::get(context, /* address space */ 0);
#else
Type *floatGenericPtrTy = PointerType::get(Type::getFloatTy(context), /* address space */ 0);
#endif
// void @mandelbrot(float*)
Type *mandelbrotParamTys[] = {floatGenericPtrTy};
@@ -139,7 +158,7 @@ std::unique_ptr<Module> generateModule(LLVMContext &context)
}
// Use libNVVM to compile an NVVM IR module to PTX.
std::string generatePtx(const std::string &module, int devMajor, int devMinor, const char *moduleName)
std::string generatePtx(const std::string &module, const std::string &arch, const char *moduleName)
{
assert(moduleName);
@@ -149,9 +168,7 @@ std::string generatePtx(const std::string &module, int devMajor, int devMinor, c
// Create a libNVVM compilation unit from the NVVM IR.
checkNVVMCall(nvvmAddModuleToProgram(compileUnit, module.c_str(), module.size(), moduleName));
std::string computeArg = "-arch=compute_";
computeArg += utostr(devMajor);
computeArg += utostr(devMinor);
std::string computeArg = "-arch=" + arch;
// Compile the NVVM IR into PTX.
const char *options[] = {computeArg.c_str()};
@@ -216,9 +233,36 @@ int main(int argc, char **argv)
checkCudaErrors(cuDeviceGetAttribute(&devMajor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, device));
checkCudaErrors(cuDeviceGetAttribute(&devMinor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, device));
outs() << "Device Compute Capability: " << devMajor << "." << devMinor << "\n";
if (devMajor < 7 && devMinor < 5) {
errs() << "ERROR: Device 0 is not sm_75 or later.\n";
return 1;
if (devMajor < 7 || (devMajor == 7 && devMinor < 5)) {
outs() << "Device 0 is not sm_75 or later.\n";
// 2 reports an unmet hardware/toolchain requirement rather than a failure.
return 2;
}
const std::string arch = computeArch(devMajor, devMinor);
// The LLVM IR that libNVVM accepts depends on the target architecture:
// pre-Blackwell targets take LLVM 7 IR, which spells pointers with their
// pointee type ('float*'), while Blackwell and later take a much newer IR
// that also accepts the opaque pointers ('ptr') LLVM 15 and later emit.
// Ask libNVVM which one applies to this device rather than assuming.
int nvvmLLVMMajor = 0;
const nvvmResult archSupported = nvvmLLVMVersion(arch.c_str(), &nvvmLLVMMajor);
if (archSupported == NVVM_ERROR_INVALID_INPUT) {
// The device is newer than the toolkit this sample builds against.
outs() << "The libNVVM of this CUDA toolkit does not support " << arch
<< ". Use a toolkit that supports this device.\n";
// 2 reports an unmet hardware/toolchain requirement rather than a failure.
return 2;
}
checkNVVMCall(archSupported);
if (LLVM_VERSION_MAJOR >= 15 && nvvmLLVMMajor < 15) {
outs() << "This sample was built against LLVM " << LLVM_VERSION_MAJOR
<< ", which emits opaque pointers, but libNVVM accepts only LLVM " << nvvmLLVMMajor << " IR for " << arch
<< ". Build against LLVM 14 or older to run on this device, or run on a "
"Blackwell or later device.\n";
// 2 reports an unmet hardware/toolchain requirement rather than a failure.
return 2;
}
// Generate the IR module
@@ -239,7 +283,7 @@ int main(int argc, char **argv)
}
// Generate PTX.
std::string ptx = generatePtx(moduleStr, devMajor, devMinor, module->getModuleIdentifier().c_str());
std::string ptx = generatePtx(moduleStr, arch, module->getModuleIdentifier().c_str());
if (SavePTX) {
std::error_code err;
raw_fd_ostream out("cuda-c-linking.kernel.ptx", err);

View File

@@ -10,8 +10,8 @@ This document assumes the CUDA runtime is used. The method for device-side
launch using the OpenCL runtime is similar but different.
This document is written after the "Device-Side Launch from PTX"
section from CUDA C Programming Guide
(http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-side-launch-from-ptx).
section from CUDA Programming Guide
(https://docs.nvidia.com/cuda/cuda-programming-guide/04-special-topics/dynamic-parallelism.html#device-side-launch-from-ptx).
Kernel Launch APIs
------------------