decuda 0.1.1

CUDA to HIP, SYCL, OpenCL, and Rust GPU migration tool — automatic source-code translator for porting CUDA C++ kernels to AMD ROCm HIP, Intel oneAPI SYCL, Khronos OpenCL, and Rust GPU (cust / rust-gpu)
Documentation
// Generated by decuda.
// OpenCL device code is the bulk of this file. The host-side calls
// (`cudaXxx`) have been rewritten to OpenCL equivalents inline; the
// surrounding host program still needs a cl_context + cl_queue, not
// included here. Look for TODO(decuda) markers for items requiring
// manual attention.

// Richer fixture exercising atomics, shared memory, syncthreads, warp
// intrinsics, 2D launches, and a constant-memory global.
#include <CL/cl.h> /* was: cuda_runtime.h */

#define N 1024

__constant float kCoefficients[8];

__kernel void increment_atomic(int* counter, int delta) {
    int prev = atomicAdd(counter, delta);
    if (get_local_id(0) == 0) {
        atomicCAS(counter, prev, prev + 1);
    }
}

__kernel void warp_scan(const int* in, int* out) {
    __local int buf[32];
    int lane = get_sub_group_id() * get_sub_group_size() + get_sub_group_local_id()();
    int wid = get_local_id(0) / 32;
    buf[lane] = in[get_local_id(0)];
    barrier(CLK_LOCAL_MEM_FENCE) /* approx */;
    if (lane == 0) {
        int s = 0;
        for (int i = 0; i < 32; ++i) s += buf[i];
        out[wid] = s;
    }
    barrier(CLK_LOCAL_MEM_FENCE);
}

__kernel void matmul(const float* a, const float* b, float* c,
                       int m, int n, int k) {
    int row = get_group_id(0) * get_local_size(0) + get_local_id(0);
    int col = get_group_id(0) * get_local_size(0) + get_local_id(0);
    if (row < m && col < n) {
        float s = kCoefficients[0] * a[row * k] * b[col];
        c[row * n + col] = s;
    }
}

void launch_examples(int* counter, float* a, float* b, float* c) {
    dim3 grid(N / 32, N / 16);
    dim3 block(32, 16);
    clEnqueueNDRangeKernel(queue, increment_atomic_kernel, 1, NULL, (size_t[1]){grid}, (size_t[1]){block}, 0, NULL, NULL) /* args: counter, 1 */;
    clEnqueueNDRangeKernel(queue, warp_scan_kernel, 1, NULL, (size_t[1]){1}, (size_t[1]){32}, 0, NULL, NULL) /* args: counter, a */;
    clEnqueueNDRangeKernel(queue, matmul_kernel, 1, NULL, (size_t[1]){grid}, (size_t[1]){block}, 0, NULL, NULL) /* args: a, b, c, N, N, N */;
}