std/cuda.zc
Rama main · réplica de lectura del repositorio original.
include <cuda_runtime.h>
import "./string.zc"
import "./mem.zc"
extern fn cudaMalloc(ptr: void**, size: usize) -> int;
extern fn cudaFree(ptr: void*) -> int;
extern fn cudaMemcpy(dst: void*, src: void*, count: usize, kind: int) -> int;
extern fn cudaMemset(ptr: void*, value: int, count: usize) -> int;
extern fn cudaDeviceSynchronize() -> int;
extern fn cudaGetDeviceCount(count: int*) -> int;
extern fn cudaSetDevice(device: int) -> int;
extern fn cudaGetLastError() -> int;
extern fn cudaDriverGetVersion(version: int*) -> int;
extern fn cudaRuntimeGetVersion(version: int*) -> int;
extern fn cudaMemGetInfo(free: usize*, total: usize*) -> int;
extern fn cudaDeviceReset() -> int;
// CUDA Constants (from cuda_runtime.h)
def cudaMemcpyHostToDevice = 1;
def cudaMemcpyDeviceToHost = 2;
def cudaMemcpyDeviceToDevice = 3;
@crepr("struct cudaDeviceProp")
struct cudaDeviceProp {
name: char[256];
totalGlobalMem: usize;
multiProcessorCount: int;
major: int;
minor: int;
maxThreadsPerBlock: int;
warpSize: int;
}
extern fn cudaGetDeviceProperties(prop: cudaDeviceProp*, device: int) -> int;
fn _z_cuda_get_props(dev: int, name: char*, mem: usize*, sm: int*, maj: int*, min: int*, max_t: int*, warp: int*) {
let prop: cudaDeviceProp;
if (cudaGetDeviceProperties(&prop, dev) == 0) {
strcpy(name, prop.name);
*mem = prop.totalGlobalMem;
*sm = prop.multiProcessorCount;
*maj = prop.major;
*min = prop.minor;
*max_t = prop.maxThreadsPerBlock;
*warp = prop.warpSize;
}
}
// Memory Management.
/// Allocate device memory for n elements of type T.
fn cuda_alloc<T>(n: usize) -> T* {
let ptr: T* = NULL;
cudaMalloc((void**)&ptr, n * sizeof(T));
return ptr;
}
/// Free device memory.
fn cuda_free(ptr: void*) {
cudaFree(ptr);
}
/// Copy bytes from host to device.
fn cuda_copy_to_device(dst: void*, src: void*, bytes: usize) {
cudaMemcpy(dst, src, bytes, cudaMemcpyHostToDevice);
}
/// Copy bytes from device to host.
fn cuda_copy_to_host(dst: void*, src: void*, bytes: usize) {
cudaMemcpy(dst, src, bytes, cudaMemcpyDeviceToHost);
}
/// Copy bytes between device buffers.
fn cuda_copy_device(dst: void*, src: void*, bytes: usize) {
cudaMemcpy(dst, src, bytes, cudaMemcpyDeviceToDevice);
}
/// Set device memory to zero.
fn cuda_zero(ptr: void*, bytes: usize) {
cudaMemset(ptr, 0, bytes);
}
// Synchronization.
/// Synchronize the device (wait for all kernels to complete).
fn cuda_sync() {
cudaDeviceSynchronize();
}
// Thread Indexing.
@device @inline fn grid_dim_x() -> int { return gridDim.x; }
@device @inline fn grid_dim_y() -> int { return gridDim.y; }
@device @inline fn grid_dim_z() -> int { return gridDim.z; }
@device @inline fn block_dim_x() -> int { return blockDim.x; }
@device @inline fn block_dim_y() -> int { return blockDim.y; }
@device @inline fn block_dim_z() -> int { return blockDim.z; }
@device @inline fn block_id_x() -> int { return blockIdx.x; }
@device @inline fn block_id_y() -> int { return blockIdx.y; }
@device @inline fn block_id_z() -> int { return blockIdx.z; }
@device @inline fn thread_id_x() -> int { return threadIdx.x; }
@device @inline fn thread_id_y() -> int { return threadIdx.y; }
@device @inline fn thread_id_z() -> int { return threadIdx.z; }
@device @inline fn thread_id() -> int { return blockIdx.x * blockDim.x + threadIdx.x; }
@device @inline fn block_id() -> int { return blockIdx.x; }
@device @inline fn local_id() -> int { return threadIdx.x; }
@device @inline fn block_size() -> int { return blockDim.x; }
@device @inline fn grid_size() -> int { return gridDim.x; }
// Device Info.
fn cuda_device_count() -> int {
let count: int = 0;
cudaGetDeviceCount(&count);
return count;
}
fn cuda_set_device(id: int) {
cudaSetDevice(id);
}
// Error Handling.
fn cuda_last_error() -> int {
let err: int;
err = (int)cudaGetLastError();
return err;
}
fn cuda_ok() -> bool {
return cuda_last_error() == 0;
}
struct CudaDeviceProp {
name: String;
total_global_mem: usize;
multi_processor_count: int;
major: int;
minor: int;
max_threads_per_block: int;
warp_size: int;
}
struct CudaMemInfo {
free: usize;
total: usize;
}
fn cuda_device_properties(device_id: int) -> CudaDeviceProp {
let mem: usize = 0;
let sm: int = 0;
let maj: int = 0;
let min: int = 0;
let max_t: int = 0;
let warp: int = 0;
let name_ptr = alloc_n<char>(256);
name_ptr[0] = 0;
_z_cuda_get_props(device_id, name_ptr, &mem, &sm, &maj, &min, &max_t, &warp);
let s = String::new(name_ptr);
dealloc<char>(name_ptr);
return CudaDeviceProp {
name: s,
total_global_mem: mem,
multi_processor_count: sm,
major: maj,
minor: min,
max_threads_per_block: max_t,
warp_size: warp
};
}
fn cuda_driver_version() -> int {
let d: int = 0;
cudaDriverGetVersion(&d);
return d;
}
fn cuda_runtime_version() -> int {
let r: int = 0;
cudaRuntimeGetVersion(&r);
return r;
}
fn cuda_mem_info() -> CudaMemInfo {
let f: usize = 0;
let t: usize = 0;
cudaMemGetInfo(&f, &t);
return CudaMemInfo { free: f, total: t };
}
fn cuda_device_reset() {
cudaDeviceReset();
}