burn_cubecl/ops/
transaction.rs1use burn_backend::{
2 DType, TensorData,
3 backend::ExecutionError,
4 ops::{TransactionOps, TransactionPrimitive, TransactionPrimitiveData},
5};
6use burn_std::{Shape, Strides};
7use cubecl::server::{CopyDescriptor, Handle};
8
9use crate::CubeBackend;
10
11impl TransactionOps<Self> for CubeBackend {
12 async fn tr_execute(
13 transaction: TransactionPrimitive<Self>,
14 ) -> Result<TransactionPrimitiveData, ExecutionError> {
15 let mut client = None;
16
17 enum Kind {
18 Float,
19 Int,
20 Bool,
21 }
22
23 #[derive(new)]
24 struct BindingData {
25 index: usize,
26 kind: Kind,
27 handle: Option<Handle>,
28 shape: Shape,
29 strides: Strides,
30 dtype: DType,
31 }
32
33 let mut num_bindings = 0;
34
35 let mut kinds = Vec::new();
36
37 for t in transaction.read_floats.into_iter() {
38 if client.is_none() {
39 client = Some(t.client.clone());
40 }
41
42 let t = crate::kernel::into_contiguous_aligned(t);
43 let binding = BindingData::new(
44 num_bindings,
45 Kind::Float,
46 Some(t.handle.clone()),
47 t.meta.shape.clone(),
48 t.meta.strides.clone(),
49 t.dtype,
50 );
51
52 kinds.push(binding);
53 num_bindings += 1;
54 }
55 for t in transaction.read_ints.into_iter() {
56 if client.is_none() {
57 client = Some(t.client.clone());
58 }
59
60 let t = crate::kernel::into_contiguous_aligned(t);
61 let binding = BindingData::new(
62 num_bindings,
63 Kind::Int,
64 Some(t.handle.clone()),
65 t.meta.shape.clone(),
66 t.meta.strides.clone(),
67 t.dtype,
68 );
69
70 kinds.push(binding);
71 num_bindings += 1;
72 }
73 for t in transaction.read_bools.into_iter() {
74 if client.is_none() {
75 client = Some(t.client.clone());
76 }
77
78 let t = crate::kernel::into_contiguous_aligned(t);
79 let binding = BindingData::new(
80 num_bindings,
81 Kind::Bool,
82 Some(t.handle.clone()),
83 t.meta.shape.clone(),
84 t.meta.strides.clone(),
85 t.dtype,
86 );
87
88 kinds.push(binding);
89 num_bindings += 1;
90 }
91
92 let client = client.unwrap();
93
94 let bindings = kinds
95 .iter_mut()
96 .map(|b| {
97 CopyDescriptor::new(
98 b.handle.take().unwrap().binding(),
99 b.shape.clone(),
100 b.strides.clone(),
101 b.dtype.size(),
102 )
103 })
104 .collect();
105
106 let mut data: Vec<Option<_>> = client
107 .read_tensor_async(bindings)
108 .await
109 .map_err(crate::backend::server_err)?
110 .into_iter()
111 .map(Some)
112 .collect::<Vec<Option<_>>>();
113
114 let mut result = TransactionPrimitiveData::default();
115
116 for binding in kinds {
117 let bytes = data.get_mut(binding.index).unwrap().take().unwrap();
118 let t_data = TensorData::from_bytes(bytes, binding.shape, binding.dtype);
119
120 match binding.kind {
121 Kind::Float => {
122 result.read_floats.push(t_data);
123 }
124 Kind::Int => {
125 result.read_ints.push(t_data);
126 }
127 Kind::Bool => {
128 result.read_bools.push(t_data);
129 }
130 }
131 }
132
133 Ok(result)
134 }
135}