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>

// Advanced fixture: multi-GPU device management with error handling and
// pinned host memory.
//
// Exercises:
//   - cudaGetDeviceCount, cudaSetDevice, cudaGetDevice (in DB -> renamed for HIP)
//   - cudaGetLastError, cudaGetErrorString (in DB -> renamed for HIP)
//   - cudaDeviceSynchronize (in DB -> hipDeviceSynchronize for HIP; flagged for SYCL/Rust/OpenCL)
//   - cudaHostAlloc (in DB -> renamed for HIP)
//   - Error-checking macro pattern (preserved verbatim)
//   - __global__ kernel
//   - threadIdx.x, blockIdx.x, blockDim.x
//   - cuda_runtime.h header
#include <sycl/sycl.hpp> /* was: cuda_runtime.h */
#include <stdio.h>

#define CUDA_CHECK(call) do { \
    sycl::errc() err = (call); \
    if (err != cudaSuccess) { \
        printf("CUDA error: %s at %s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__); \
        cudaGetLastError(); \
    } \
} while (0)

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

int main(void) {
    int device_count = 0;
    CUDA_CHECK(cudaGetDeviceCount(&device_count));
    if (device_count == 0) {
        printf("No CUDA devices found.\n");
        return 1;
    }

    // Run on each device.
    for (int dev = 0; dev < device_count; dev++) {
        CUDA_CHECK(cudaSetDevice(dev));

        int current = 0;
        CUDA_CHECK(cudaGetDevice(&current));
        printf("Using device %d\n", current);

        const int N = 1024;
        float* d_data = nullptr;
        CUDA_CHECK(cudaMalloc((void**)&d_data, N * sizeof(float)));

        // Pinned host memory for faster transfers.
        float* h_data = nullptr;
        CUDA_CHECK(cudaHostAlloc((void**)&h_data, N * sizeof(float), 0));

        dim3 grid(N / 256);
        dim3 block(256);
        { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{grid}, [=](sycl::item<3> it) { /* kernel `fill_kernel` body with thread indices from it.get_*() */ }); }); smem=none stream=default args=d_data, 3.14f, N */ };

        // cudaDeviceSynchronize is NOT in the DB — it is preserved verbatim
        // and flagged in the migration report for non-HIP targets.
        cudaDeviceSynchronize();

        CUDA_CHECK(cudaMemcpy(h_data, d_data, N * sizeof(float), cudaMemcpyDeviceToHost));
        printf("device %d: h_data[0] = %f\n", dev, h_data[0]);

        CUDA_CHECK(cudaFree(d_data));
        cudaFreeHost(h_data);
    }

    return 0;
}