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: inline PTX assembly constructs.
//
// Exercises:
//   - asm("...") with output/input operands
//   - asm volatile("...") with no operands
//   - asm with memory clobber
//   - All PTX constructs are flagged as warnings (NVIDIA-specific, no
//     equivalent in HIP/SYCL/OpenCL/Rust — manual rewrite required)
//   - __global__ kernel, threadIdx.x, blockIdx.x, blockDim.x
//   - cuda_runtime.h header
#include <sycl/sycl.hpp> /* was: cuda_runtime.h */

// TODO(decuda): rewrite as SYCL kernel lambda
 void ptx_bswap(int* data, int n) {
    int i = item.get_group(0) * item.get_local_range() + item.get_local_id();
    if (i >= n) return;

    int x = data[i];

    // Byte-swap via PTX `prmt` instruction.
    int result;
    asm("prmt.b32 %0, %1, 0, 0x0123;" : "=r"(result) : "r"(x));
    data[i] = result;
}

// TODO(decuda): rewrite as SYCL kernel lambda
 void ptx_membar(int* data, int n) {
    int i = item.get_group(0) * item.get_local_range() + item.get_local_id();
    if (i >= n) return;

    // Memory barrier via PTX.
    asm volatile("membar.gl;");
    data[i] += 1;
}

// TODO(decuda): rewrite as SYCL kernel lambda
 void ptx_clock(unsigned long long* cycles) {
    // Read the GPU clock counter via PTX.
    unsigned long long c;
    asm volatile("mov.u64 %0, %%clock64;" : "=l"(c));
    if (item.get_group(0) * item.get_local_range() + item.get_local_id() == 0) {
        *cycles = c;
    }
}

// TODO(decuda): rewrite as SYCL kernel lambda
 void ptx_lanemask(unsigned int* mask) {
    // Get the active lane mask via PTX.
    unsigned int m;
    asm volatile("activemask.b32 %0;" : "=r"(m));
    if (item.get_group(0) * item.get_local_range() + item.get_local_id() == 0) {
        *mask = m;
    }
}

int main(void) {
    const int N = 1024;
    int* d_data = nullptr;
    unsigned long long* d_cycles = nullptr;
    unsigned int* d_mask = nullptr;

    cudaMalloc((void**)&d_data, N * sizeof(int));
    cudaMalloc((void**)&d_cycles, sizeof(unsigned long long));
    cudaMalloc((void**)&d_mask, sizeof(unsigned int));

    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 `ptx_bswap` body with thread indices from it.get_*() */ }); }); smem=none stream=default args=d_data, N */ };
    { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{grid}, [=](sycl::item<3> it) { /* kernel `ptx_membar` body with thread indices from it.get_*() */ }); }); smem=none stream=default args=d_data, N */ };
    { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{1}, [=](sycl::item<3> it) { /* kernel `ptx_clock` body with thread indices from it.get_*() */ }); }); smem=none stream=default args=d_cycles */ };
    { /* decuda SYCL launch: queue.submit([&](sycl::handler& h) { h.parallel_for(sycl::range<3>{1}, [=](sycl::item<3> it) { /* kernel `ptx_lanemask` body with thread indices from it.get_*() */ }); }); smem=none stream=default args=d_mask */ };

    cudaDeviceSynchronize();
    cudaFree(d_data);
    cudaFree(d_cycles);
    cudaFree(d_mask);
    return 0;
}