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

@@ -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);