runmat_runtime/builtins/common/
gpu_helpers.rs1use runmat_accelerate_api::{AccelProvider, GpuTensorHandle, GpuTensorStorage, HostTensorView};
2use runmat_builtins::{ComplexTensor, Tensor, Value};
3
4use crate::build_runtime_error;
5
6pub async fn gather_tensor_async(
11 handle: &runmat_accelerate_api::GpuTensorHandle,
12) -> crate::BuiltinResult<Tensor> {
13 let value = Value::GpuTensor(handle.clone());
14 let gathered = crate::dispatcher::gather_if_needed_async(&value).await?;
15 match gathered {
16 Value::Tensor(t) => Ok(t),
17 Value::Num(n) => Tensor::new(vec![n], vec![1, 1])
18 .map_err(|e| build_runtime_error(format!("gather: {e}")).build()),
19 Value::LogicalArray(la) => {
20 let data: Vec<f64> = la
21 .data
22 .iter()
23 .map(|&b| if b != 0 { 1.0 } else { 0.0 })
24 .collect();
25 Tensor::new(data, la.shape.clone())
26 .map_err(|e| build_runtime_error(format!("gather: {e}")).build())
27 }
28 other => {
29 Err(build_runtime_error(format!("gather: unexpected value kind {other:?}")).build())
30 }
31 }
32}
33
34pub async fn gather_value_async(value: &Value) -> crate::BuiltinResult<Value> {
36 crate::dispatcher::gather_if_needed_async(value).await
37}
38
39pub fn upload_complex_tensor(
42 provider: &dyn AccelProvider,
43 tensor: &ComplexTensor,
44) -> crate::BuiltinResult<GpuTensorHandle> {
45 let mut interleaved = Vec::with_capacity(tensor.data.len() * 2);
46 for &(re, im) in &tensor.data {
47 interleaved.push(re);
48 interleaved.push(im);
49 }
50 let view = HostTensorView {
51 data: &interleaved,
52 shape: &tensor.shape,
53 };
54 let handle = provider
55 .upload(&view)
56 .map_err(|e| build_runtime_error(format!("gpu upload: {e}")).build())?;
57 runmat_accelerate_api::set_handle_logical(&handle, false);
58 runmat_accelerate_api::set_handle_storage(&handle, GpuTensorStorage::ComplexInterleaved);
59 runmat_accelerate_api::set_handle_precision(&handle, provider.precision());
60 Ok(handle)
61}
62
63pub fn resident_gpu_value(handle: GpuTensorHandle) -> Value {
66 runmat_accelerate_api::mark_residency(&handle);
67 Value::GpuTensor(handle)
68}
69
70pub fn logical_gpu_value(handle: GpuTensorHandle) -> Value {
73 runmat_accelerate_api::set_handle_logical(&handle, true);
74 resident_gpu_value(handle)
75}
76
77pub fn complex_gpu_value(handle: GpuTensorHandle) -> Value {
79 runmat_accelerate_api::set_handle_logical(&handle, false);
80 runmat_accelerate_api::set_handle_storage(&handle, GpuTensorStorage::ComplexInterleaved);
81 resident_gpu_value(handle)
82}