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.
// Host-side runtime calls are translated to the `cust` crate. Kernels
// are emitted as `TODO(decuda)` blocks: rust-gpu translation requires
// the kernel to be authored as a Rust fn. See `examples/` for a
// scaffolded SPIR-V kernel module you can flesh out.
//
// Add to your Cargo.toml:
//   [dependencies]
//   cust = "0.3"

// 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
// was: #include cuda_runtime.h  ->  cust::cuda_build_setup() /* TODO: import cust crate */
#include <stdio.h>

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

// TODO(decuda): rewrite as rust-gpu kernel fn
 void fill_kernel(float* data, float value, int n) {
    int i = block_idx * block_dim + thread_idx;
    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 cust launch */ let _kernel = modules.get_function("fill_kernel"); unsafe { let _ = launch!( _kernel<<<grid as grid_size, block as block_size, 0 as usize, default>>>(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;
}