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.
// SYCL kernels replace CUDA kernels with parallel_for lambdas; this
// output is a *starting point* and almost always requires manual
// follow-up. Look for the `TODO(decuda)` markers in this file.

#include <sycl/sycl.hpp>

// Complex fixture: asynchronous pipeline using CUDA streams and events.
//
// Exercises:
//   - cudaStreamCreate / cudaStreamDestroy / cudaStreamSynchronize
//   - cudaEventCreate / cudaEventRecord / cudaEventSynchronize / cudaEventDestroy
//   - cudaMemcpyAsync (async memcpy on a stream)
//   - Multiple kernels launched on different streams
//   - Launch with shared-memory size argument: kernel<<<grid, block, smem, stream>>>
//   - __global__ kernels with __syncthreads
//   - cuda_runtime.h header
#include <sycl/sycl.hpp> /* was: cuda_runtime.h */

// TODO(decuda): rewrite as SYCL kernel lambda
 void scale(float a, float* x, int n) {
    int i = item.get_group(0) * item.get_local_range() + item.get_local_id();
    if (i < n) {
        x[i] *= a;
    }
}

// TODO(decuda): rewrite as SYCL kernel lambda
 void add(const float* x, const float* y, float* out, int n) {
    int i = item.get_group(0) * item.get_local_range() + item.get_local_id();
    if (i < n) {
        out[i] = x[i] + y[i];
    }
    item.barrier(sycl::access::fence_space::global_space);
}

int main(void) {
    const int N = 1 << 16;
    float *dx = nullptr, *dy = nullptr, *dz = nullptr;

    cudaMalloc((void**)&dx, N * sizeof(float));
    cudaMalloc((void**)&dy, N * sizeof(float));
    cudaMalloc((void**)&dz, N * sizeof(float));

    sycl::queue() s1, s2;
    cudaStreamCreate(&s1);
    cudaStreamCreate(&s2);

    sycl::event() e1, e2;
    cudaEventCreate(&e1);
    cudaEventCreate(&e2);

    dim3 grid(N / 256);
    dim3 block(256);

    // Async memcpy on stream s1.
    cudaMemcpyAsync(dx, dy, N * sizeof(float), cudaMemcpyDeviceToDevice, s1);

    // Launch with explicit shared-memory size and stream.
    { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{grid}, [=](sycl::item<3> it) { /* kernel `scale` body with thread indices from it.get_*() */ }); }); smem=0 stream=s1 args=2.0f, dx, N */ };
    cudaEventRecord(e1, s1);

    // Second stream waits on event e1 via host-side synchronize.
    cudaEventSynchronize(e1);
    { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{grid}, [=](sycl::item<3> it) { /* kernel `add` body with thread indices from it.get_*() */ }); }); smem=128 stream=s2 args=dx, dy, dz, N */ };
    cudaEventRecord(e2, s2);

    cudaStreamSynchronize(s1);
    cudaStreamSynchronize(s2);

    cudaEventDestroy(e1);
    cudaEventDestroy(e2);
    cudaStreamDestroy(s1);
    cudaStreamDestroy(s2);

    cudaFree(dx);
    cudaFree(dy);
    cudaFree(dz);
    return 0;
}