sinatras/pmpp-eval huggingface dataset:
Task: ch02-vecadd-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include <cuda_runtime.h>

__global__ void vecAddKernel(const float* A, const float* B, float* C, int n) {
    // TODO: Implement vector addition
    // Hints:
    // - Calculate global thread index i from blockIdx.x, blockDim.x, and threadIdx.x
    // - Add bounds check to ensure i < n
    // - Compute C[i] = A[i] + B[i]
}
```
Task: ch02-vecmul-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include <cuda_runtime.h>

__global__ void vecMulKernel(const float* A, const float* B, float* C, int n) {
    // TODO: Each thread i computes: C[i] = A[i] * B[i]  (if i < n)
    // Hints:
    //  - Derive global index i from block and thread indices
    //  - Guard against i >= n
}
```
Task: ch03-ex1a-matmul-row-per-thread
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include <cuda_runtime.h>

extern "C" __global__
void matrixMulRowKernel(const float* __restrict__ M,
                        const float* __restrict__ N,
                        float* __restrict__ P,
                        int size) {
    // TODO:
    // - Each thread computes ONE output row 'row'
    // - Guard: if (row < size)
    // - For each column 'col', compute dot(M[row, :], N[:, col])
    // - Write P[row * size + col]
    // Hints:
    //   int row = blockIdx.x * blockDim.x + threadIdx.x;
    //   for (int col = 0; col < size; ++col) { ... }
}
```
Task: ch03-ex1b-matmul-col-per-thread
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include <cuda_runtime.h>

extern "C" __global__
void matrixMulColKernel(const float* __restrict__ M,
                        const float* __restrict__ N,
                        float* __restrict__ P,
                        int size) {
    // TODO:
    // - Each thread computes ONE output column 'col'
    // - Guard: if (col < size)  
    // - For each row 'row', compute dot(M[row, :], N[:, col])
    // - Write P[row * size + col]
    // Hints:
    //   int col = blockIdx.x * blockDim.x + threadIdx.x;
    //   for (int row = 0; row < size; ++row) { ... }
}
```
Task: ch03-rgb2gray-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include <cuda_runtime.h>
#include <math.h>

__device__ __forceinline__ unsigned char clamp_u8(int v) {
    return (unsigned char)(v < 0 ? 0 : (v > 255 ? 255 : v));
}

__global__ void rgb2grayKernel(const unsigned char* R,
                               const unsigned char* G,
                               const unsigned char* B,
                               unsigned char* gray,
                               int n) {
    // TODO:
    // - Compute global index i
    // - If (i < n), compute:
    //     float y = 0.299f*R[i] + 0.587f*G[i] + 0.114f*B[i];
    //     int yi = (int)floorf(y + 0.5f);   // round to nearest
    //     gray[i] = clamp_u8(yi);
}
```
Task: ch04-device-props-eval
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
#include "student_kernel.cuh"
#include <cuda_runtime.h>
#include <string.h>

int collect_device_info(DeviceInfo* out, int max_out, int* out_count) {
    // TODO: Implement using CUDA Runtime API
    // Required calls:
    //   - cudaGetDeviceCount(&count)
    //   - For each device id in [0, count): cudaGetDeviceProperties(&prop, id)
    //
    // Required fields to fill in for each DeviceInfo (from cudaDeviceProp prop):
    //   name -> prop.name (ensure null-terminated)
    //   major -> prop.major
    //   minor -> prop.minor
    //   totalGlobalMem -> prop.totalGlobalMem
    //   multiProcessorCount -> prop.multiProcessorCount
    //   totalConstMem -> prop.totalConstMem
    //   sharedMemPerBlock -> prop.sharedMemPerBlock
    //   regsPerBlock -> prop.regsPerBlock
    //   warpSize -> prop.warpSize
    //   maxThreadsPerBlock -> prop.maxThreadsPerBlock
    //   maxThreadsDim{0,1,2} -> prop.maxThreadsDim[0..2]
    //   maxGridSize{0,1,2} -> prop.maxGridSize[0..2]
    //   clockRate -> prop.clockRate
    //   memoryClockRate -> prop.memoryClockRate
    //   memoryBusWidth -> prop.memoryBusWidth
    //   l2CacheSize -> prop.l2CacheSize
    //
    // Return 0 on success, non-zero on failure.

    (void)out; (void)max_out; (void)out_count; // remove after implementing
    return 1; // placeholder: non-zero means "not implemented"
}
```
Task: ch05-matmul-tiled-multiturn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
// Implement a shared-memory tiled matrix multiply kernel:
//   C[M x K] = A[M x N] * B[N x K]
// TILE size is 16x16. Handle non-multiple sizes and out-of-bounds safely.

#include <cuda_runtime.h>

extern "C" void launch_student(const float* A, const float* B, float* C,
                               int M, int N, int K, int blockSize);

// TODO: Implement this kernel
__global__ void matmul_tiled_student(const float* __restrict__ A,
                                     const float* __restrict__ B,
                                     float* __restrict__ C,
                                     int M, int N, int K)
{
    // TODO: Implement shared-memory tiled matrix multiplication
    // REQUIRED: TILE = 16
    // 
    // Steps to implement:
    // 1. Define TILE size (16)
    // 2. Calculate 2D thread coordinates (row, col) in output matrix C
    // 3. Declare shared memory tiles for A and B submatrices  
    // 4. Initialize accumulator
    // 5. Loop over tiles along the inner dimension N:
    //    a. Cooperatively load A tile and B tile into shared memory
    //    b. Guard against out-of-bounds accesses (pad with zeros)
    //    c. Synchronize threads (__syncthreads())
    //    d. Compute partial products using shared memory tiles
    //    e. Synchronize threads again
    // 6. Write final result to global memory (with bounds checking)
}

extern "C" void launch_student(const float* A, const float* B, float* C,
                               int M, int N, int K, int /*blockSize*/)
{
    // TODO: Set up proper grid and block dimensions
    // Hint: Use 16x16 thread blocks, calculate grid size based on output dimensions
    
    dim3 block(16, 16);
    dim3 grid((K + 15) / 16, (M + 15) / 16);
    matmul_tiled_student<<<grid, block>>>(A, B, C, M, N, K);
}
```
Task: ch05-matmul-tiled-speed
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <cstdio>

#ifndef TILE
#define TILE 16
#endif

// Students implement this kernel: C[M x K] = A[M x N] * B[N x K]
// One thread computes one C element; shared-memory tiled load of A and B.
__global__ void matmul_tiled_student_kernel(const float* __restrict__ A,
                                            const float* __restrict__ B,
                                            float* __restrict__ C,
                                            int M, int N, int K) {
    // TODO:
    // - Compute (row, col) from blockIdx/threadIdx
    // - Loop over tiles of N dimension
    // - Use shared memory tiles for A (TILE x TILE) and B (TILE x TILE)
    // - Guard for out-of-bounds loads/stores
    // - Accumulate sum into a register and store to C[row*K + col]

    // Hints (remove after implementing):
    // extern __shared__ float smem[]; // or static shared tiles
    // __shared__ float As[TILE][TILE], Bs[TILE][TILE];
    // int row = blockIdx.y * blockDim.y + threadIdx.y;
    // int col = blockIdx.x * blockDim.x + threadIdx.x;

    // --- your code here ---

    // Placeholder stub (compiles but gives wrong results):
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;

    if (row < M && col < K) {
        C[row * K + col] = 0.0f; // TODO: replace with proper tiled computation
    }
}

// Host wrapper called by test harness
extern "C" void matmul_student(const float* dA, const float* dB, float* dC,
                               int M, int N, int K, int tile) {
    dim3 block(TILE, TILE);
    dim3 grid((K + TILE - 1)/TILE, (M + TILE - 1)/TILE);
    // You may ignore `tile` and use TILE macro; the harness passes TILE=16.
    matmul_tiled_student_kernel<<<grid, block>>>(dA, dB, dC, M, N, K);
}
```
Task: ch07-conv2d-tiled-constant
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// students edit only this file
#include <cuda_runtime.h>
#include <cstdio>

#ifndef TILE
#define TILE 16
#endif

#ifndef MAX_RADIUS
#define MAX_RADIUS 8   // supports up to (2*8+1)=17x17 filters
#endif

// 1D constant buffer for filter coefficients (row-major)
// Size = (2*MAX_RADIUS+1)^2
__constant__ float c_filter[(2*MAX_RADIUS+1)*(2*MAX_RADIUS+1)];

extern "C" __host__ void setFilterConstant(const float* h_filter, int r) {
    const int K = 2*r + 1;
    cudaMemcpyToSymbol(c_filter, h_filter, K*K*sizeof(float), 0, cudaMemcpyHostToDevice);
}

// Students must implement this kernel.
// Requirements:
// - Shared-memory tiling with halo of +/-r (use zero padding for out-of-bounds loads)
// - Use c_filter (in constant memory) for filter coefficients
// - Each thread computes one output pixel (if in bounds)
// - Grid/block: 2D, blockDim=(TILE,TILE), gridDim=ceil(W/TILE) x ceil(H/TILE)
// - Inputs/outputs are float* (grayscale), shapes: in/out = H*W
// - r is runtime radius (<= MAX_RADIUS)
__global__ void conv2d_tiled_constant_kernel(const float* __restrict__ in,
                                             float* __restrict__ out,
                                             int H, int W, int r)
{
    // TODO: Implement tiled 2D convolution with constant memory
    //
    // Key steps:
    // 1) Compute global (x,y) coordinates for this thread
    // 2) Declare shared memory tile with halo: extern __shared__ float smem[];
    //    Size needed: (TILE+2*r) * (TILE+2*r) * sizeof(float)
    // 3) Compute the tile's coverage region including halo
    // 4) Cooperatively load the entire tile+halo region into shared memory
    //    - Use zero padding for out-of-bounds pixels
    //    - May need nested loops for threads to cover entire shared memory region
    // 5) __syncthreads() to ensure all data is loaded
    // 6) If this thread's output pixel is in bounds, compute convolution:
    //    - Access input pixels from shared memory (with proper offsets)
    //    - Access filter coefficients from c_filter constant memory
    //    - Accumulate weighted sum
    // 7) Write result to global output memory
    //
    // Hints:
    // - Filter coefficients in c_filter are stored row-major: c_filter[(dy+r)*(2*r+1) + (dx+r)]
    // - Shared memory indexing: smem[sy * tileWidth + sx] where tileWidth = TILE+2*r
    // - Global input indexing: in[gy * W + gx]
    // - Consider boundary conditions carefully for both image edges and tile edges

    // Placeholder implementation (will fail until properly implemented):
    int x = blockIdx.x * blockDim.x + threadIdx.x;
    int y = blockIdx.y * blockDim.y + threadIdx.y;

    if (x < W && y < H) {
        // This is incorrect - just copies input to output
        out[y * W + x] = in[y * W + x];
    }
}
```
Task: ch08-heat-3d-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <cstdio>

// Implement a single explicit 7-point heat step.
// in  : N*N*N input (flattened, row-major: i*N*N + j*N + k)
// out : N*N*N output (same layout)
// N   : grid dimension
// alpha, dt, dx: physical parameters; r = alpha*dt/(dx*dx)
// Boundary policy: copy boundary through (out = in) if any neighbor would be OOB.
__global__ void heat_step_kernel(const float* __restrict__ in,
                                 float* __restrict__ out,
                                 unsigned int N,
                                 float alpha, float dt, float dx)
{
    // TODO:
    // 1) Compute (i,j,k) from block and thread indices
    // 2) If any of i,j,k is 0 or N-1 => boundary: out = in and return
    // 3) Else compute r = alpha*dt/(dx*dx) and 7-point update:
    //    out = in + r*(sum six neighbors - 6*in)
    // Guard small N (N<3) by simply copying (no interior exists).
}
```
Task: ch08-stencil3d-basic-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <cstdio>

__global__ void stencil3d_basic_student(
    const float* __restrict__ in,
    float* __restrict__ out,
    int N,
    float c0, float c1, float c2, float c3, float c4, float c5, float c6)
{
    // TODO:
    // - Each thread computes OUT(i,j,k) for one grid point
    // - Use 7-point stencil on INTERIOR points: (1..N-2) in each dim
    // - For boundary points (i==0 || i==N-1 || ...), copy through: out = in
    // - Guard for N==0 or N==1 safely
    // Hints:
    //   int i = blockIdx.z * blockDim.z + threadIdx.z;
    //   int j = blockIdx.y * blockDim.y + threadIdx.y;
    //   int k = blockIdx.x * blockDim.x + threadIdx.x;
    //   int idx = (i * N + j) * N + k;
    //   int L = ((i) * N + j) * N + (k-1); // k-1, etc.
}
```
Task: ch08-stencil3d-sharedmem-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <cstdio>

// Tile parameters for this task
#ifndef IN_TILE_DIM
#define IN_TILE_DIM 8          // threads per dim that load (with halo)
#endif
#define OUT_TILE_DIM (IN_TILE_DIM-2)

__global__ void stencil3d_shared_student(
    const float* __restrict__ in,
    float* __restrict__ out,
    int N,
    float c0, float c1, float c2, float c3, float c4, float c5, float c6)
{
    // TODO:
    // - Launch with block=(IN_TILE_DIM,IN_TILE_DIM,IN_TILE_DIM)
    // - Each block loads a IN_TILE_DIM^3 tile (with halo) into shared memory
    // - Only threads with local coords in [1..IN_TILE_DIM-2] compute outputs
    //   for the corresponding global interior coordinates
    // - Copy-through boundary cells (same rule as basic)
    // Hints:
    //   Shared array: __shared__ float tile[IN_TILE_DIM][IN_TILE_DIM][IN_TILE_DIM];
    //   Global coords start at (blockIdx * OUT_TILE_DIM) - 1 (to include halo)
    //   Guard global loads (row/col/depth) that fall outside [0..N-1]
}
```
Task: ch09-histogram-naive-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <cstddef>

// TODO: Implement naive global-atomic histogram.
//
// Requirements:
// - Use global-memory atomicAdd(&hist[bin], 1u)
// - Grid-stride loop over N
// - Ignore out-of-range bin indices
// - Do not write to 'in'
// - No shared memory
//
// Signature must not change.
__global__ void histogram_kernel(const int* in, unsigned int* hist,
                                 size_t N, int num_bins)
{
    // TODO:
    // size_t i = ...
    // size_t stride = ...
    // for (; i < N; i += stride) {
    //   int bin = in[i];
    //   if (0 <= bin && bin < num_bins) atomicAdd(&hist[bin], 1u);
    // }
}
```
Task: ch09-histogram-shared-single-turn
            Target file: student_kernel.cu

            Implementation requirements:
- Use extern __shared__ unsigned int s_hist[] with num_bins elements.
- Cooperatively zero the shared histogram before processing data.
- Iterate over the input with a grid-stride loop and accumulate counts into shared memory (no atomics within the block).
- Synchronize threads before and after shared-memory accumulation.
- Cooperatively merge shared counts to global hist with atomicAdd, handling num_bins > blockDim.x.
- Do not modify the input array and avoid out-of-bounds accesses.

            Here is the current student_kernel.cu:

            ```cuda
            // student_kernel.cu
#include <cuda_runtime.h>
#include <cstddef>

// TODO: Implement shared-memory privatized histogram
//
// Requirements:
//  - Use shared memory to reduce global atomic contention
//  - Each block maintains its own private histogram in shared memory
//  - Accumulate counts into shared histogram using atomicAdd
//  - Flush shared histogram to global histogram at the end
//  - Process all N input elements across the grid
//
// Algorithm steps:
//  1. Initialize shared memory histogram to zero (cooperative initialization)
//     - Each thread zeros multiple bins if num_bins > blockDim.x
//     - Use loop: for (int bin = threadIdx.x; bin < num_bins; bin += blockDim.x)
//     - Synchronize after initialization
//
//  2. Accumulate input values into shared histogram
//     - Use grid-stride loop to process input elements
//     - Read input value, treat it as bin index
//     - Validate bin is in range [0, num_bins)
//     - Use atomicAdd to increment shared histogram bin
//     - Synchronize after accumulation
//
//  3. Merge shared histogram into global histogram
//     - Each thread handles multiple bins if needed
//     - Use atomicAdd to add shared counts to global histogram
//
// Hints:
//  - Shared memory is declared: extern __shared__ unsigned int s_hist[];
//  - Grid-stride loop: for (size_t i = blockIdx.x*blockDim.x + threadIdx.x; i < N; i += blockDim.x*gridDim.x)
//  - Atomic operations: atomicAdd(&s_hist[bin], 1u) for shared, atomicAdd(&hist[bin], count) for global
//  - Synchronization required between phases: __syncthreads()

__global__ void histogram_kernel(const int* in, unsigned int* hist,
                                 size_t N, int num_bins)
{
    extern __shared__ unsigned int s_hist[];

    // TODO: Implement 3-phase histogram: init shared  accumulate  flush to global
    (void)in; (void)hist; (void)N; (void)num_bins; (void)s_hist;
}
            ```
Task: ch10-reduction-max-arbitrary
Target file: student_kernel.cu

Goal: Implement an arbitrary-length maximum reduction that scans the input with grid-stride loops, performs a shared-memory tree reduction per block, and emits the final maximum via a race-free CAS-based atomic max on floats.

Key requirements:
- Kernel signature: `__global__ void reduce_max_arbitrary(const float* in, float* out, int n)`
- Initialize each thread's local maximum to `-INFINITY` when it sees no elements.
- Use grid-stride loops to cover the full array and reduce into shared memory before the atomic.
- Implement `atomicMaxFloat` using `atomicCAS` on the integer bit pattern and update only `out[0]`.

Skeleton:
```cuda
// student_kernel.cu
#include <cuda_runtime.h>
#include <limits>

// TODO: Implement arbitrary-length maximum reduction with grid-stride, shared
// memory, and a CAS-loop atomicMax for float. Initialize per-thread local max
// to -INFINITY when n==0 or no elements in its stride.
//
// IMPORTANT: Use the -INFINITY macro (not std::numeric_limits<float>::infinity())
// Example: float local_max = -INFINITY;
__device__ inline
void atomicMaxFloat(float* addr, float val) {
    // TODO: Implement via atomicCAS on int bit patterns
}

extern "C" __global__
void reduce_max_arbitrary(const float* in, float* out, int n) {
    // TODO
}
```
Task: ch10-reduction-sum-2048
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>

// TODO: Implement convergent shared-memory reduction for exactly 2048 elements.
// Contract:
//  - gridDim.x == 1, blockDim.x == 1024
//  - Each thread loads two elements: in[tid] and in[tid + 1024]
//  - Reduce in shared memory (convergent pattern), write out[0] only.
extern "C" __global__
void reduce_sum_2048(const float* in, float* out) {
    // TODO
    // Suggested shape:
    // __shared__ float s[1024];
    // unsigned t = threadIdx.x;
    // float v = in[t] + in[t + 1024];
    // s[t] = v;
    // __syncthreads();
    // for (unsigned stride = blockDim.x/2; stride >= 1; stride >>= 1) { ... }
    // if (t == 0) out[0] = s[0];
}
```
Task: ch10-reduction-sum-arbitrary
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>

// TODO: Implement arbitrary-length sum with grid-stride loads, shared-memory
// reduction per block, and atomicAdd(out, block_sum). Use dynamic shared memory.
extern "C" __global__
void reduce_sum_arbitrary(const float* in, float* out, int n) {
    // TODO
    // Suggested shape:
    // extern __shared__ float s[];
    // int tid = threadIdx.x;
    // long long idx = blockIdx.x * (long long)blockDim.x * 2 + tid;
    // long long stride = (long long)gridDim.x * blockDim.x * 2;
    // float sum = 0.f;
    // for (; idx < n; idx += stride) {
    //   sum += in[idx];
    //   long long idx2 = idx + blockDim.x;
    //   if (idx2 < n) sum += in[idx2];
    // }
    // s[tid] = sum; __syncthreads();
    // for (int step = blockDim.x/2; step >= 1; step >>= 1) { ... }
    // if (tid==0) atomicAdd(out, s[0]);
}
```
Task: ch12-merge-path-single-turn
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// student_kernel.cu
#include <cuda_runtime.h>

// TODO: Implement parallel merge using merge-path (diagonal partition).
// Contract summary:
//  - Stable: on ties, choose A first
//  - Partition per thread using diagonals; then sequentially merge that slice
//  - Inputs A,B are sorted ascending; write C of length nA+nB

__device__ inline int clampi(int x, int lo, int hi) {
    return x < lo ? lo : (x > hi ? hi : x);
}

// Find (i,j) on diagonal d (i+j = d) satisfying merge-path conditions.
// Returns i; j = d - i.
// Invariants:
//   lo = max(0, d - nB), hi = min(d, nA)
// Stable tie-breaking: A[i-1] <= B[j]  (and B[j-1] < A[i])
__device__ __forceinline__
int merge_path_search(const int* __restrict__ A, int nA,
                      const int* __restrict__ B, int nB,
                      int d)
{
    // TODO: Implement binary search to find merge-path coordinates
    // Return i such that (i, d-i) satisfies merge-path conditions
    return 0; // placeholder
}

extern "C" __global__
void merge_path_kernel(const int* __restrict__ A, int nA,
                       const int* __restrict__ B, int nB,
                       int* __restrict__ C)
{
    // TODO: Implement merge-path parallel merge
    // 1. Calculate thread's diagonal range [d0, d1)
    // 2. Find merge coordinates (i0,j0) and (i1,j1) using merge_path_search
    // 3. Sequentially merge A[i0..i1) and B[j0..j1) into C[d0..d1)
}
```
Task: ch13-merge-path-fullsort-single
Target file: student_kernel.cu

Here is the current skeleton you must complete:

```cuda
// ch13-merge-path-fullsort-single / student_kernel.cu
#include <cuda_runtime.h>
#include <stdint.h>

// CONTRACT:
// Implement stable GPU merge sort using iterative merge passes.
// You must implement:
//   - merge_path_search (device): diagonal search
//   - merge_path_kernel (global): merges a slice [d0,d1)
//   - gpu_merge_sort (host): doubles width and ping-pongs buffers until sorted

__device__ int merge_path_search(const uint32_t* A, int nA,
                                 const uint32_t* B, int nB,
                                 int d)
{
    // TODO: diagonal binary search; return i (then j=d-i)
    return 0;
}

__global__ void merge_path_kernel(const uint32_t* __restrict__ A, int nA,
                                  const uint32_t* __restrict__ B, int nB,
                                  uint32_t* __restrict__ C)
{
    // TODO:
    //  - P = total threads
    //  - segment size seg = ceil((nA+nB)/P)
    //  - each thread t merges its slice [d0,d1)
    //  - compute (i0,j0) & (i1,j1) via merge_path_search
    //  - sequentially merge into C[d0..d1)
}

extern "C" void gpu_merge_sort(const uint32_t* d_in, uint32_t* d_out, int n)
{
    // TODO:
    //  - width = 1; ping-pong buffers
    //  - for width < n:
    //      * launch merges of adjacent runs [k..k+width) and [k+width..k+2*width)
    //  - final result copied to d_out
    (void)d_in; (void)d_out; (void)n;
}
```