#![allow(unused_imports, dead_code, unused_variables)]
use mumu::parser::types::{Value, TensorValue, ElemType};
use mumu::parser::interpreter::Interpreter;
pub fn gpu_to_tensor_bridge(
_interp: &mut Interpreter,
args: Vec<Value>
) -> Result<Value, String> {
if args.len() != 1 {
return Err(format!("gpu:to_tensor => expected 1 argument, got {}", args.len()));
}
let array_val = &args[0];
let (rows, cols, float_bytes) = match array_val {
Value::Int2DArray(mat) => {
if mat.is_empty() {
return Err("gpu:to_tensor => got empty 2D int array".to_string());
}
let r_count = mat.len();
let c_count = mat[0].len();
for row_i in mat {
if row_i.len() != c_count {
return Err("gpu:to_tensor => inconsistent row lengths".to_string());
}
}
let mut bytes = Vec::new();
for row in mat {
for &iv in row {
let fv = iv as f32;
bytes.extend_from_slice(&fv.to_le_bytes());
}
}
(r_count, c_count, bytes)
}
Value::Float2DArray(mat) => {
if mat.is_empty() {
return Err("gpu:to_tensor => got empty 2D float array".to_string());
}
let r_count = mat.len();
let c_count = mat[0].len();
for row_i in mat {
if row_i.len() != c_count {
return Err("gpu:to_tensor => inconsistent row lengths".to_string());
}
}
let mut bytes = Vec::new();
for row in mat {
for &fv in row {
let f32v = fv as f32;
bytes.extend_from_slice(&f32v.to_le_bytes());
}
}
(r_count, c_count, bytes)
}
other => {
return Err(format!(
"gpu:to_tensor => argument must be Int2DArray or Float2DArray, got {:?}",
other
));
}
};
let shape = vec![rows, cols];
let tv = TensorValue {
elem_type: ElemType::Float32,
shape,
data: float_bytes,
};
#[cfg(debug_assertions)]
{
crate::debug::set_last_call_info("to_tensor", false);
}
Ok(Value::Tensor(tv))
}
pub fn gpu_to_array_bridge(
_interp: &mut Interpreter,
args: Vec<Value>
) -> Result<Value, String> {
if args.len() != 1 {
return Err(format!("gpu:to_array => expected 1 argument, got {}", args.len()));
}
let v = &args[0];
let t = match v {
Value::Tensor(tv) => tv,
other => {
return Err(format!("gpu:to_array => argument must be a Tensor, got {:?}", other));
}
};
if t.shape.len() != 2 {
return Err("gpu:to_array => only rank=2 supported".to_string());
}
if t.elem_type != ElemType::Float32 {
return Err("gpu:to_array => tensor must be Float32".to_string());
}
let rows = t.shape[0];
let cols = t.shape[1];
let needed = rows * cols * 4;
if t.data.len() != needed {
return Err("gpu:to_array => data length mismatch".to_string());
}
let mut offset = 0;
let mut out = Vec::with_capacity(rows);
for _r in 0..rows {
let mut rowf = Vec::with_capacity(cols);
for _c in 0..cols {
let chunk = &t.data[offset..offset+4];
offset += 4;
let val = f32::from_le_bytes(chunk.try_into().unwrap());
rowf.push(val as f64);
}
out.push(rowf);
}
#[cfg(debug_assertions)]
{
crate::debug::set_last_call_info("to_array", false);
}
Ok(Value::Float2DArray(out))
}