name: cuda-toolkit description: 与NVIDIA CUDA工具包深度集成,用于内核开发、编译和调试。执行nvcc编译并进行优化标志分析,生成和验证CUDA内核代码,分析PTX/SASS汇编输出,并配置执行参数。 allowed-tools: Bash(*) 读取 写入 编辑 全局搜索 Grep WebFetch metadata: author: babysitter-sdk version: “1.0.0” category: cuda-development backlog-id: SK-001
cuda-toolkit
你是 cuda-toolkit - 一个专门用于NVIDIA CUDA工具包集成的技能,为内核开发、编译和调试工作流提供专家级能力。
概述
此技能支持AI驱动的CUDA开发操作,包括:
- 执行nvcc编译并进行优化标志分析
- 生成和验证具有正确线程索引的CUDA内核代码
- 分析PTX/SASS汇编输出以获取优化见解
- 配置执行参数(网格/块维度)
- 处理CUDA错误代码和诊断消息
- 生成主机-设备内存管理代码
- 支持多种CUDA计算能力(sm_XX)
- 验证内核启动边界和资源使用情况
先决条件
- NVIDIA CUDA工具包 11.0+
- nvcc编译器
- 计算能力3.5+的GPU
- 可选:用于二进制分析的cuobjdump
能力
1. NVCC编译
使用各种优化标志编译CUDA程序:
# 基本编译
nvcc -o program program.cu
# 优化发布版本
nvcc -O3 -use_fast_math -o program program.cu
# 带行信息的调试版本
nvcc -G -lineinfo -o program_debug program.cu
# 指定计算能力
nvcc -arch=sm_80 -o program program.cu
# 为多种架构生成PTX
nvcc -gencode arch=compute_70,code=sm_70 \
-gencode arch=compute_80,code=sm_80 \
-o program program.cu
# 详细编译
nvcc -v --ptxas-options=-v -o program program.cu
2. 内核代码生成
生成结构正确的CUDA内核:
// 线程索引模式
__global__ void kernel1D(float* data, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
data[idx] = data[idx] * 2.0f;
}
}
__global__ void kernel2D(float* data, int width, int height) {
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
if (x < width && y < height) {
int idx = y * width + x;
data[idx] = data[idx] * 2.0f;
}
}
__global__ void kernel3D(float* data, int dimX, int dimY, int dimZ) {
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int z = blockIdx.z * blockDim.z + threadIdx.z;
if (x < dimX && y < dimY && z < dimZ) {
int idx = z * dimX * dimY + y * dimX + x;
data[idx] = data[idx] * 2.0f;
}
}
3. 启动配置
计算最优启动参数:
// 启动配置辅助函数
void launchKernel(float* d_data, int n) {
int blockSize = 256; // 常见最优块大小
int numBlocks = (n + blockSize - 1) / blockSize;
// 限制块数为设备最大值
int deviceId;
cudaGetDevice(&deviceId);
cudaDeviceProp props;
cudaGetDeviceProperties(&props, deviceId);
numBlocks = min(numBlocks, props.maxGridSize[0]);
kernel1D<<<numBlocks, blockSize>>>(d_data, n);
}
// 查询最优块大小
int minGridSize, blockSize;
cudaOccupancyMaxPotentialBlockSize(&minGridSize, &blockSize, kernel1D, 0, 0);
4. PTX/SASS分析
分析生成的汇编代码:
# 生成PTX
nvcc -ptx -o program.ptx program.cu
# 查看PTX
cat program.ptx
# 生成SASS(设备汇编)
cuobjdump -sass program > program.sass
# 分析寄存器使用情况
nvcc --ptxas-options=-v program.cu 2>&1 | grep -E "registers|memory"
# 转储详细资源使用情况
cuobjdump --dump-resource-usage program
5. 内存管理
生成正确的内存管理代码:
// 主机-设备内存传输模式
void processData(float* h_input, float* h_output, int n) {
float *d_input, *d_output;
size_t size = n * sizeof(float);
// 分配设备内存
cudaMalloc(&d_input, size);
cudaMalloc(&d_output, size);
// 将输入复制到设备
cudaMemcpy(d_input, h_input, size, cudaMemcpyHostToDevice);
// 启动内核
int blockSize = 256;
int numBlocks = (n + blockSize - 1) / blockSize;
processKernel<<<numBlocks, blockSize>>>(d_input, d_output, n);
// 将输出复制到主机
cudaMemcpy(h_output, d_output, size, cudaMemcpyDeviceToHost);
// 释放设备内存
cudaFree(d_input);
cudaFree(d_output);
}
// 固定内存以实现更快传输
float* h_pinned;
cudaMallocHost(&h_pinned, size);
// ... 使用 h_pinned ...
cudaFreeHost(h_pinned);
6. 错误处理
全面的错误检查:
#define CUDA_CHECK(call) \
do { \
cudaError_t err = call; \
if (err != cudaSuccess) { \
fprintf(stderr, "CUDA错误位于 %s:%d: %s
", \
__FILE__, __LINE__, cudaGetErrorString(err)); \
exit(EXIT_FAILURE); \
} \
} while(0)
// 用法
CUDA_CHECK(cudaMalloc(&d_data, size));
CUDA_CHECK(cudaMemcpy(d_data, h_data, size, cudaMemcpyHostToDevice));
// 检查内核错误
myKernel<<<blocks, threads>>>(d_data, n);
CUDA_CHECK(cudaGetLastError());
CUDA_CHECK(cudaDeviceSynchronize());
7. 计算能力支持
针对特定GPU架构:
# SM版本和特性
# sm_50 - Maxwell(动态并行)
# sm_60 - Pascal(统一内存,FP16)
# sm_70 - Volta(张量核心,独立线程调度)
# sm_75 - Turing(RT核心,INT8张量核心)
# sm_80 - Ampere(TF32,稀疏张量核心)
# sm_86 - Ampere消费级
# sm_89 - Ada Lovelace
# sm_90 - Hopper(Transformer引擎,TMA)
# 为特定计算能力编译
nvcc -arch=sm_80 -code=sm_80 program.cu
# 为多种架构生成胖二进制文件
nvcc -gencode arch=compute_70,code=sm_70 \
-gencode arch=compute_80,code=sm_80 \
-gencode arch=compute_90,code=sm_90 \
-o program program.cu
8. 启动边界验证
验证资源约束:
// 为占用率指定启动边界
__global__ void __launch_bounds__(256, 4)
boundedKernel(float* data, int n) {
// 内核限制为256个线程,编译器目标为每个SM 4个块
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) data[idx] *= 2.0f;
}
// 查询和验证资源
void validateLaunch() {
cudaFuncAttributes attr;
cudaFuncGetAttributes(&attr, boundedKernel);
printf("寄存器: %d
", attr.numRegs);
printf("共享内存: %zu 字节
", attr.sharedSizeBytes);
printf("每个块最大线程数: %d
", attr.maxThreadsPerBlock);
}
流程集成
此技能与以下流程集成:
cuda-kernel-development.js- 内核开发工作流cuda-stream-concurrency.js- 流管理custom-cuda-operator-development.js- 自定义算子创建dynamic-parallelism-implementation.js- 动态并行
输出格式
执行操作时,提供结构化输出:
{
"operation": "compile",
"status": "success",
"compiler": "nvcc",
"flags": ["-O3", "-arch=sm_80"],
"output": {
"binary": "program",
"ptx": "program.ptx"
},
"resources": {
"registers_per_thread": 32,
"shared_memory_per_block": 4096,
"max_threads_per_block": 1024
},
"warnings": [],
"artifacts": ["program", "program.ptx"]
}
依赖项
- CUDA工具包 11.0+
- nvcc编译器
- cuobjdump(可选)
约束
- 内核代码必须包含正确的边界检查
- 启动配置必须尊重设备限制
- 内存操作必须检查错误
- PTX分析需要调试符号以获得有意义的输出