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. Edit with care.
// HIP is mostly source-compatible with CUDA at the kernel level.
// Compare against the original .cu file for sanity.

// 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 <hip/hip_runtime.h> /* was: cuda_runtime.h */
#include <stdio.h>

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

__global__ void fill_kernel(float* data, float value, int n) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < n) {
        data[i] = value;
    }
}

int main(void) {
    int device_count = 0;
    CUDA_CHECK(hipGetDeviceCount(&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(hipSetDevice(dev));

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

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

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

        dim3 grid(N / 256);
        dim3 block(256);
        hipLaunchKernelGGL(fill_kernel, dim3(grid), dim3(block), 0, 0, 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.
        hipDeviceSynchronize();

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

        CUDA_CHECK(hipFree(d_data));
        hipFreeHost(h_data);
    }

    return 0;
}