Function attributes / cache config / occupancy#

Defined in code/simulator.h.

This page documents 7 symbols: 2 enums, 5 functions.

Enums#

Signature

Description

Availability

Location

Example

enum cudaFuncAttribute

sim only

simulator.h:2336

enum cudaFuncCache

sim only

simulator.h:2334

Functions#

Signature

Description

Availability

Location

Example

inline cudaError_t cudaFuncGetAttributes(cudaFuncAttributes* a, F )

sim only

simulator.h:2343

View

inline cudaError_t cudaFuncSetAttribute(F , cudaFuncAttribute , int )

sim only

simulator.h:2351

View

inline cudaError_t cudaFuncSetCacheConfig(F , cudaFuncCache )

sim only

simulator.h:2350

View

inline cudaError_t cudaOccupancyMaxActiveBlocksPerMultiprocessor( int* numBlocks, F , int , size_t )

sim only

simulator.h:2352

View

inline cudaError_t cudaOccupancyMaxPotentialBlockSize( int* minGridSize, int* blockSize, F , size_t = 0, int = 0)

sim only

simulator.h:2354

Examples#

Code from the repository’s example corpus (code\*.cu); the highlighted line is the call site. These blocks are what the View links above open.

cudaFuncGetAttributes (test_web_cs_cppoverload.cu:138)
128    void (*func1)(const int *, int *, int);
129    void (*func2)(const int2 *, int *, int);
130    void (*func3)(const int *, const int *, int *, int);
131    struct cudaFuncAttributes attr;
132
133    // overload 1: simple_kernel(const int*, int*, int)
134    func1 = simple_kernel;
135    memset(&attr, 0, sizeof(attr));
136    CHECK(cudaFuncSetCacheConfig(*func1, cudaFuncCachePreferShared));
137    CHECK(cudaFuncGetAttributes(&attr, *func1));
138    OUTPUT_ATTR(attr);
139    LAUNCH(func1, DIV_UP(N, THREAD_N), THREAD_N, dInput, dOutput, a);
140    CHECK(cudaMemcpy(hOutput.data(), dOutput, sizeof(int) * N, cudaMemcpyDeviceToHost));
141    funcResult = check_func1(hInput.data(), hOutput.data(), a);
142    printf("simple_kernel(const int *pIn, int *pOut, int a) %s\n\n",
143           funcResult ? "PASSED" : "FAILED");
144    testResult &= funcResult;
145
146    // overload 2: simple_kernel(const int2*, int*, int)
147    func2 = simple_kernel;
148    memset(&attr, 0, sizeof(attr));
cudaFuncSetAttribute (test_llmc_fused_residual_forward_full.cu:314)
304void fused_residual_forward5(floatX* residual, floatX* normed, floatX* mean, floatX* rstd,
305                             const floatX* inp1, const floatX* inp2,
306                             const floatX* weight, const floatX* bias,
307                             int N, int C, const int block_size) {
308    int block_y = block_size / 32;
309    const int grid_size = ceil_div(N, block_y);
310    size_t smem = (2 + block_y) * C * sizeof(floatX);
311
312    // in order to use more than 48 KiB of smem, need to call cudaFuncSetAttribute
313    cudaCheck(cudaGetLastError());
314    auto status = cudaFuncSetAttribute(fused_residual_forward_kernel5,
315                                       cudaFuncAttributeMaxDynamicSharedMemorySize, (int)smem);
316    cudaGetLastError();
317    cudaCheck(status);   // [SIM] no kernel-4 fallback here; kernel 4 lives in the sibling test
318    LAUNCH_DYN(fused_residual_forward_kernel5, grid_size, dim3(32, block_y), smem,
319               residual, normed, mean, rstd, inp1, inp2, weight, bias, N, C);
320    cudaCheck(cudaGetLastError());
321}
322
323void fused_residual_forward6(floatX* residual, floatX* normed, floatX* mean, floatX* rstd,
324                             const floatX* inp1, const floatX* inp2,
325                             const floatX* weight, const floatX* bias,
cudaFuncSetCacheConfig (test_web_cs_cppoverload.cu:137)
127    int a = 1;
128
129    void (*func1)(const int *, int *, int);
130    void (*func2)(const int2 *, int *, int);
131    void (*func3)(const int *, const int *, int *, int);
132    struct cudaFuncAttributes attr;
133
134    // overload 1: simple_kernel(const int*, int*, int)
135    func1 = simple_kernel;
136    memset(&attr, 0, sizeof(attr));
137    CHECK(cudaFuncSetCacheConfig(*func1, cudaFuncCachePreferShared));
138    CHECK(cudaFuncGetAttributes(&attr, *func1));
139    OUTPUT_ATTR(attr);
140    LAUNCH(func1, DIV_UP(N, THREAD_N), THREAD_N, dInput, dOutput, a);
141    CHECK(cudaMemcpy(hOutput.data(), dOutput, sizeof(int) * N, cudaMemcpyDeviceToHost));
142    funcResult = check_func1(hInput.data(), hOutput.data(), a);
143    printf("simple_kernel(const int *pIn, int *pOut, int a) %s\n\n",
144           funcResult ? "PASSED" : "FAILED");
145    testResult &= funcResult;
146
147    // overload 2: simple_kernel(const int2*, int*, int)
148    func2 = simple_kernel;
cudaOccupancyMaxActiveBlocksPerMultiprocessor (test_web_olcf_hw9_task2.cu:119)
109    cudaMemset(d_odata, 0, tsize);
110    cudaMalloc(&d_idxs, test_dsize * sizeof(unsigned));
111
112    cudaDeviceProp prop{};
113    cudaError_t err = cudaGetDeviceProperties(&prop, 0);
114    if (err != cudaSuccess) { std::printf("cuda error: %s\n", cudaGetErrorString(err)); return 1; }
115    if (prop.cooperativeLaunch == 0) { std::printf("cooperative launch not supported\n"); return 0; }
116    std::printf("Device 0: %s — number of SMs = %d\n", prop.name, prop.multiProcessorCount);
117
118    int numBlkPerSM = 0;
119    cudaOccupancyMaxActiveBlocksPerMultiprocessor(&numBlkPerSM, my_remove_if<mytype>, nTPB, 0);
120    std::printf("number of blocks per SM = %d\n", numBlkPerSM);
121
122    // [SIM] cap the cooperative grid (see the header note); the kernel is a
123    // grid-stride loop so any grid size gives the same answer.
124    int nBlocks = numBlkPerSM * prop.multiProcessorCount;
125    if (nBlocks > 8) nBlocks = 8;
126    dim3 grid((unsigned)nBlocks), block(nTPB);
127    std::printf("cooperative grid: %d blocks of %d threads\n", nBlocks, nTPB);
128
129    bool ok = true;