Implement a CUDA kernel for naive 3D cross-correlation on a single-channel input volume with a single-channel kernel. There is no kernel flip and no zero padding. Stride is fixed at 1.
For each output position (d,i,j):
output[d,i,j]=a=0∑kD−1b=0∑kH−1c=0∑kW−1input[d+a,i+b,j+c]⋅kernel[a,b,c]The input volume has shape (D,H,W) and the kernel has shape (kD,kH,kW). With valid padding and stride 1, the output shape is (D−kD+1)×(H−kH+1)×(W−kW+1).
All tensors are row-major flat. The input is D⋅H⋅W floats indexed as d⋅H⋅W+i⋅W+j. The kernel is kD⋅kH⋅kW floats indexed as a⋅kH⋅kW+b⋅kW+c. The output is outD⋅outH⋅outW floats indexed as d⋅outH⋅outW+i⋅outW+j. The kernel writes one element of output per thread.
Input: D = 2, H = 2, W = 2, kD = 2, kH = 2, kW = 2, input = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]], kernel = [[[1, 0], [0, 1]], [[0, 1], [1, 0]]]
Output: [[[18]]]
Single scalar output. Matching the four nonzero kernel positions gives 1⋅1+4⋅1+6⋅1+7⋅1=18.
Input: D = 2, H = 3, W = 3, kD = 1, kH = 2, kW = 2, input = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]], kernel = [[[1, 1], [1, 1]]]
Output: [[[12, 16], [24, 28]], [[48, 52], [60, 64]]]
Output shape is 2×2×2. Each entry sums a 2×2 window from one depth slice.
Use a 3D thread block so each thread maps to one (d,i,j) in the output volume. Recover indices from blockIdx and threadIdx along all three axes.
Inside the kernel, run a triple-nested loop over (a,b,c) in (kD,kH,kW) to accumulate input[d+a,i+b,j+c]⋅kernel[a,b,c] into a local float before writing once to global memory.
Remember row-major flatten: indexing input uses H⋅W stride along depth and W stride along height; output uses outH⋅outW and outW.
Accepts: array
Accepts: array
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Submit a correct solution to see your kernel performance.
Implement a CUDA kernel for naive 3D cross-correlation on a single-channel input volume with a single-channel kernel. There is no kernel flip and no zero padding. Stride is fixed at 1.
For each output position (d,i,j):
output[d,i,j]=a=0∑kD−1b=0∑kH−1c=0∑kW−1input[d+a,i+b,j+c]⋅kernel[a,b,c]The input volume has shape (D,H,W) and the kernel has shape (kD,kH,kW). With valid padding and stride 1, the output shape is (D−kD+1)×(H−kH+1)×(W−kW+1).
All tensors are row-major flat. The input is D⋅H⋅W floats indexed as d⋅H⋅W+i⋅W+j. The kernel is kD⋅kH⋅kW floats indexed as a⋅kH⋅kW+b⋅kW+c. The output is outD⋅outH⋅outW floats indexed as d⋅outH⋅outW+i⋅outW+j. The kernel writes one element of output per thread.
Input: D = 2, H = 2, W = 2, kD = 2, kH = 2, kW = 2, input = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]], kernel = [[[1, 0], [0, 1]], [[0, 1], [1, 0]]]
Output: [[[18]]]
Single scalar output. Matching the four nonzero kernel positions gives 1⋅1+4⋅1+6⋅1+7⋅1=18.
Input: D = 2, H = 3, W = 3, kD = 1, kH = 2, kW = 2, input = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]], kernel = [[[1, 1], [1, 1]]]
Output: [[[12, 16], [24, 28]], [[48, 52], [60, 64]]]
Output shape is 2×2×2. Each entry sums a 2×2 window from one depth slice.
Use a 3D thread block so each thread maps to one (d,i,j) in the output volume. Recover indices from blockIdx and threadIdx along all three axes.
Inside the kernel, run a triple-nested loop over (a,b,c) in (kD,kH,kW) to accumulate input[d+a,i+b,j+c]⋅kernel[a,b,c] into a local float before writing once to global memory.
Remember row-major flatten: indexing input uses H⋅W stride along depth and W stride along height; output uses outH⋅outW and outW.
Accepts: array
Accepts: array
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Submit a correct solution to see your kernel performance.