diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-19 22:18:33 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-19 22:18:33 +0000 |
| commit | 3af5dcf34d705cc52c1ffe5b85c2a90b5104e4c9 (patch) | |
| tree | 8ad5b61b2818baf1af80c0a725622cda2c3fa1b8 /std | |
| parent | 959a27fd763e2e960ef31adf891118a261bad1c7 (diff) | |
Improve 'std/cuda.zc' and 'std/vec.zc' + iteration...
Diffstat (limited to 'std')
| -rw-r--r-- | std/cuda.zc | 85 | ||||
| -rw-r--r-- | std/vec.zc | 109 |
2 files changed, 181 insertions, 13 deletions
diff --git a/std/cuda.zc b/std/cuda.zc index 851acb3..dbb1fe6 100644 --- a/std/cuda.zc +++ b/std/cuda.zc @@ -1,5 +1,7 @@ include <cuda_runtime.h> +import "./string.zc" +import "./mem.zc" // Memory Management. @@ -97,3 +99,86 @@ fn cuda_last_error() -> int { fn cuda_ok() -> bool { return cuda_last_error() == 0; } + + +raw { + void _z_cuda_get_props(int dev, char* name, size_t* total_mem, int* sm_count, int* major, int* minor, int* max_threads, int* warp_size) { + struct cudaDeviceProp prop; + if (cudaGetDeviceProperties(&prop, dev) == 0) { + strcpy(name, prop.name); + *total_mem = prop.totalGlobalMem; + *sm_count = prop.multiProcessorCount; + *major = prop.major; + *minor = prop.minor; + *max_threads = prop.maxThreadsPerBlock; + *warp_size = prop.warpSize; + } + } +} + +extern fn _z_cuda_get_props(dev: int, name: char*, mem: usize*, sm: int*, maj: int*, min: int*, max_t: int*, warp: int*); + +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 { + var mem: usize = 0; + var sm: int = 0; + var maj: int = 0; + var min: int = 0; + var max_t: int = 0; + var warp: int = 0; + + var 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); + + var s = String::new(name_ptr); + free(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 { + var d: int = 0; + cudaDriverGetVersion(&d); + return d; +} + +fn cuda_runtime_version() -> int { + var r: int = 0; + cudaRuntimeGetVersion(&r); + return r; +} + +fn cuda_mem_info() -> CudaMemInfo { + var f: usize = 0; + var t: usize = 0; + cudaMemGetInfo(&f, &t); + return CudaMemInfo { free: f, total: t }; +} + +fn cuda_device_reset() { + cudaDeviceReset(); +} @@ -14,6 +14,30 @@ struct VecIter<T> { idx: usize; } +struct VecIterResult<T> { + ptr: T*; +} + +impl VecIterResult<T> { + fn is_none(self) -> bool { + return self.ptr == 0; + } + + fn unwrap(self) -> T* { + if (self.ptr == 0) { + !"Panic: unwrap called on null VecIterResult"; + exit(1); + } + return self.ptr; + } +} + +struct VecIterRef<T> { + data: T*; + count: usize; + idx: usize; +} + impl VecIter<T> { fn next(self) -> Option<T> { if (self.idx < self.count) { @@ -23,6 +47,25 @@ impl VecIter<T> { } return Option<T>::None(); } + + fn iterator(self) -> VecIter<T> { + return *self; + } +} + +impl VecIterRef<T> { + fn next(self) -> VecIterResult<T> { + if (self.idx < self.count) { + var item = &self.data[self.idx]; + self.idx = self.idx + 1; + return VecIterResult<T> { ptr: item }; + } + return VecIterResult<T> { ptr: 0 }; + } + + fn iterator(self) -> VecIterRef<T> { + return *self; + } } impl Vec<T> { @@ -30,6 +73,23 @@ impl Vec<T> { return Vec<T> { data: 0, len: 0, cap: 0 }; } + fn with_capacity(cap: usize) -> Vec<T> { + if (cap == 0) { + return Vec<T> { data: 0, len: 0, cap: 0 }; + } + return Vec<T> { + data: (T*)malloc(cap * sizeof(T)), + len: 0, + cap: cap + }; + } + + fn grow(self) { + if (self.cap == 0) { self.cap = 8; } + else { self.cap = self.cap * 2; } + self.data = (T*)realloc(self.data, self.cap * sizeof(T)); + } + fn iterator(self) -> VecIter<T> { return VecIter<T> { data: self.data, @@ -37,16 +97,21 @@ impl Vec<T> { idx: 0 }; } + + fn iter_ref(self) -> VecIterRef<T> { + return VecIterRef<T> { + data: self.data, + count: self.len, + idx: 0 + }; + } fn push(self, item: T) { if (self.len >= self.cap) { - if (self.cap == 0) { self.cap = 8; - } - else { self.cap = self.cap * 2; - } - self.data = realloc(self.data, self.cap * sizeof(T)); + self.grow(); } self.data[self.len] = item; + self.data[self.len] = item; self.len = self.len + 1; } @@ -56,11 +121,7 @@ impl Vec<T> { exit(1); } if (self.len >= self.cap) { - if (self.cap == 0) { self.cap = 8; - } - else { self.cap = self.cap * 2; - } - self.data = realloc(self.data, self.cap * sizeof(T)); + self.grow(); } // Shift elements right if (idx < self.len) { @@ -79,6 +140,14 @@ impl Vec<T> { return self.data[self.len]; } + fn pop_opt(self) -> Option<T> { + if (self.len == 0) { + return Option<T>::None(); + } + self.len = self.len - 1; + return Option<T>::Some(self.data[self.len]); + } + fn remove(self, idx: usize) -> T { if (idx >= self.len) { !"Panic: Remove index out of bounds"; @@ -176,12 +245,26 @@ impl Vec<T> { } fn clone(self) -> Vec<T> { - var new_vec: Vec<T> = Vec<T>::new(); + if (self.len == 0) { + return Vec<T> { data: 0, len: 0, cap: 0 }; + } + var new_data = (T*)malloc(self.len * sizeof(T)); var i: usize = 0; while i < self.len { - new_vec.push(self.data[i]); + new_data[i] = self.data[i]; i = i + 1; } - return new_vec; + return Vec<T> { + data: new_data, + len: self.len, + cap: self.len // Set capacity to exact length + }; + // No local Vec variable means no Drop is called here. + } +} + +impl Drop for Vec { + fn drop(self) { + self.free(); } } |
