summaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
Diffstat (limited to 'std')
-rw-r--r--std/cuda.zc85
-rw-r--r--std/vec.zc109
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();
+}
diff --git a/std/vec.zc b/std/vec.zc
index 1d9e6e1..be4dc05 100644
--- a/std/vec.zc
+++ b/std/vec.zc
@@ -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();
}
}