Description
runComputeOnCpu is a function that simulates a GPU-like compute environment on the CPU. It organizes work into workgroups and invocations, similar to how compute shaders operate on GPUs.
Warning
Using barrier() within conditional branches leads to undefined behavior. The emulator is modeled using a single barrier that must be accessible from all threads within a workgroup.
Parameters
- numWorkGroups: UVec3 The number of workgroups in each dimension (x, y, z).
- workGroupSize: UVec3 The size of each workgroup in each dimension (x, y, z).
- compute: ThreadGenerator[A, B, C] The compute shader procedure to execute.
- ssbo: A Storage buffer object(s) containing the data to process.
- smem: B Shared memory for each workgroup.
- args: C Additional arguments passed to the compute shader.
Compute Function Signature
The compute shader procedure should have the following signature:
proc computeFunction[A, B, C]( buffers: A, # Storage buffer (typically ptr T or Locker[T]) shared: ptr B, # Shared memory args: C # Additional arguments ) {.nimcall.}
Example
type Buffers = object input, output: seq[float32] Shared = seq[float32] Args = object factor: int32 proc myComputeShader( buffers: ptr Buffers, shared: ptr Shared, args: Args) {.computeShader.} = # Computation logic here let numWorkGroups = uvec3(4, 1, 1) let workGroupSize = uvec3(256, 1, 1) var buffers: Buffers let coarseFactor = 4'i32 runComputeOnCpu( numWorkGroups, workGroupSize, myComputeShader, addr buffers, newSeq[float32](workGroupSize.x), Args(factor: coarseFactor) )
CUDA to GLSL Translation Table
| CUDA Concept | GLSL Equivalent | Description |
|---|---|---|
| blockDim | gl_WorkGroupSize | The size of a thread block (CUDA) or work group (GLSL) |
| gridDim | gl_NumWorkGroups | The size of the grid (CUDA) or the number of work groups (GLSL) |
| blockIdx | gl_WorkGroupID | The index of the current block (CUDA) or work group (GLSL) |
| threadIdx | gl_LocalInvocationID | The index of the current thread within its block (CUDA) or work group (GLSL) |
| blockIdx * blockDim + threadIdx | gl_GlobalInvocationID | The global index of the current thread (CUDA) or invocation (GLSL) |
Types
GlEnvironment = object gl_GlobalInvocationID*: UVec3 gl_LocalInvocationID*: UVec3 gl_WorkGroupID*: UVec3 gl_WorkGroupSize*: UVec3 gl_NumWorkGroups*: UVec3 gl_NumSubgroups*: uint32 gl_SubgroupSize*: uint32 gl_SubgroupID*: uint32 gl_SubgroupInvocationID*: uint32
- Source Edit
ThreadGenerator[A; B; C] = proc (env: GlEnvironment; buffers: A; shared: ptr B; args: C): ThreadClosure {.nimcall.}
- Source Edit
Procs
proc runComputeOnCpu[A, B, C](numWorkGroups, workGroupSize: UVec3; compute: ThreadGenerator[A, B, C]; ssbo: A; smem: B; args: C)
- Source Edit