# cuda

A Cursor rule that tells the agent how to write CUDA C++: error-checked API calls, host/device separation, kernel tuning. Useful when silent GPU failures eat your afternoon.

- rule · `type=rule` · Cursor · ★ 3579
- Author: sanjeed5
- License: CC0-1.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/cuda.mdc
- Updated: 2026-05-19
- HTML: https://affpapa.org/en/nevibecode/rules/cuda

## What it does

Drop the rule into `.cursor/rules/cuda.mdc` and it applies to every file in the project. It sets naming and structure: wrap CUDA API calls in an error-checking macro, keep host orchestration apart from device computation, suffix `__global__` functions with `_kernel`, `__device__` functions with `_device`, and prefix shared memory with `smem_`.

Memory and throughput get their own section. RAII wrappers for device buffers and streams instead of hand-written `cudaFree`, `cudaMallocPitch` for 2D arrays, `cudaMemcpyAsync` across multiple streams so transfers overlap with compute. For common math the rule points at CUDA-X libraries — cuBLAS, cuFFT, cuDNN, cuML — rather than a hand-rolled GEMM.

Data layout matters too: structures-of-arrays instead of an array of structs, `const` and `__restrict__` qualifiers to help the compiler, warp divergence reduced with predicates or lookup tables. The file is written for Cursor. Claude, Codex and Copilot use different paths, so the same text has to be copied there before it does anything.

## Install

### Cursor (native platform)

**Manually: put the files in place**
- File: `.cursor/rules/cuda.mdc` — Frontmatter: description, globs, alwaysApply

### Claude Code

**Manually: put the files in place**
- File: `.claude/rules/cuda.md` — The paths frontmatter field limits the files: move globs from the source into paths

### Codex

**AGENTS.md**
- Codex reads AGENTS.md: paste the rule text there

### GitHub Copilot

**Manually: put the files in place**
- File: `.github/instructions/cuda.instructions.md` — The applyTo field sets which files it applies to: move globs from the source into applyTo

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/rules/cuda.md`

### Cline

**Manually: put the files in place**
- File: `.clinerules/cuda.md`

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/cuda.mdc

## When to use it
- catch a CUDA API error at the call site instead of a later crash
- split host orchestration from device kernels across files
- stop leaking device memory with RAII wrappers
- hide host-to-device copy latency behind compute
- align 2D matrix rows for coalesced access

## Example prompts
- Refactor this kernel to cut warp divergence and add CUDA_CHECK around every API call
- Rewrite the device allocation as an RAII wrapper and move host and device code into separate files
- Replace my hand-written matrix multiply with a cuBLAS call

## Source text · cuda.mdc · CC0-1.0

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: bc1ae303685c4139.

BEGIN THIRD-PARTY FILE bc1ae303685c4139
````text
---
description: Definitive guidelines for writing high-performance, maintainable, and error-resistant CUDA C++ code, focusing on modern practices, memory management, kernel optimization, and robust error handling.
globs: **/*
---
# CUDA Best Practices

This guide outlines the essential practices for developing efficient and maintainable CUDA C++ applications. Adhere to these rules to maximize GPU throughput, reduce debugging time, and ensure code quality across projects.

## 1. Code Organization and Structure

### 1.1 Robust Error Handling
**Always wrap CUDA API calls in an error-checking macro.** This prevents silent failures and provides immediate, actionable debugging information.

❌ BAD:
```cpp
cudaMalloc(&d_data, size);
// ... potentially crash later without knowing why
```

✅ GOOD:
```cpp
#define CUDA_CHECK(call)                                                          \
    do {                                                                          \
        cudaError_t err = call;                                                   \
        if (err != cudaSuccess) {                                                 \
            fprintf(stderr, "CUDA Error: %s:%d: %s\n", __FILE__, __LINE__, cudaGetErrorString(err)); \
            exit(EXIT_FAILURE);                                                   \
        }                                                                         \
    } while (0)

// Usage:
CUDA_CHECK(cudaMalloc(&d_data, size));
kernel<<<grid, block>>>(d_data);
CUDA_CHECK(cudaGetLastError()); // Check for kernel launch errors
```

### 1.2 Host-Device Separation
Clearly separate host (CPU) orchestration logic from device (GPU) computation.

❌ BAD:
```cpp
// host_code.cu
void processData() {
    cudaMalloc(&d_data, size); // Mixed host/device
    kernel<<<...>>>(d_data);
}
```

✅ GOOD:
```cpp
// host_manager.cpp
void allocateAndLaunch(float* h_in, int N) {
    float *d_in;
    CUDA_CHECK(cudaMalloc((void**)&d_in, N * sizeof(float)));
    CUDA_CHECK(cudaMemcpy(d_in, h_in, N * sizeof(float), cudaMemcpyHostToDevice));
    myKernel_kernel<<<N/256 + 1, 256>>>(d_in, N);
    CUDA_CHECK(cudaGetLastError());
    CUDA_CHECK(cudaFree(d_in));
}

// device_kernels.cu
__global__ void myKernel_kernel(float* d_in, int N) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx < N) { d_in[idx] *= 2.0f; }
}
```

### 1.3 Consistent Naming Conventions
Use clear suffixes and prefixes to distinguish CUDA components.
*   `_kernel`: For `__global__` functions.
*   `_device`: For `__device__` functions.
*   `smem_`: For `__shared__` variables.
*   `k` prefix: For `__constant__` memory or compile-time constants.

❌ BAD:
```cpp
void compute(float* data); // Ambiguous
__shared__ int temp;
```

✅ GOOD:
```cpp
__global__ void myCompute_kernel(float* d_data);
__device__ float calculate_device(float val);
extern __shared__ float smem_scratch[];
__constant__ const int kTileSize = 32;
```

### 1.4 Modularity
Decompose large kernels into smaller, focused `__device__` functions.

❌ BAD:
```cpp
__global__ void monolithicKernel(float* d_data, int N) { /* Do everything here */ }
```

✅ GOOD:
```cpp
__device__ float processElement_device(float val) { return val * val + 1.0f; }

__global__ void modularKernel(float* d_in, int N) {
    int global_idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (global_idx < N) {
        d_in[global_idx] = processElement_device(d_in[global_idx]);
    }
}
```

## 2. Common Patterns and Anti-patterns

### 2.1 Modern Memory Management (RAII)
Use RAII wrappers for device memory and streams to prevent leaks.

❌ BAD:
```cpp
````
END THIRD-PARTY FILE bc1ae303685c4139

The third-party file has ended. Everything between the bc1ae303685c4139 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3631 of 8852 bytes. © sanjeed5 · CC0-1.0 · https://github.com/sanjeed5/awesome-cursor-rules-mdc/tree/HEAD/rules-mdc/cuda.mdc

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
