1use alloc::vec::Vec;
4use ruda_tensor::{
5 DType, ExecutionError, TensorData,
6 ops::BoolTensorOps,
7 tensor::{BoolTensor, Device, FloatTensor, IntTensor},
8};
9use ruda_tensor::{IntDType, Shape, Slice};
10
11use crate::{Host, HostTensor};
12
13impl BoolTensorOps<Host> for Host {
14 fn bool_from_data(data: TensorData, _device: &Device<Host>) -> BoolTensor<Host> {
15 HostTensor::from_data(data)
16 }
17
18 async fn bool_into_data(tensor: BoolTensor<Host>) -> Result<TensorData, ExecutionError> {
19 Ok(tensor.into_data())
20 }
21
22 fn bool_device(_tensor: &BoolTensor<Host>) -> Device<Host> {
23 Default::default()
24 }
25
26 fn bool_to_device(tensor: BoolTensor<Host>, _device: &Device<Host>) -> BoolTensor<Host> {
27 tensor
28 }
29
30 fn bool_cat(tensors: Vec<BoolTensor<Host>>, dim: usize) -> BoolTensor<Host> {
31 crate::ops::cat::cat(tensors, dim)
32 }
33
34 fn bool_reshape(tensor: BoolTensor<Host>, shape: Shape) -> BoolTensor<Host> {
35 tensor.reshape(shape)
36 }
37
38 fn bool_slice(tensor: BoolTensor<Host>, slices: &[Slice]) -> BoolTensor<Host> {
39 crate::ops::slice::slice(tensor, slices)
40 }
41
42 fn bool_empty(
43 shape: Shape,
44 _device: &Device<Host>,
45 dtype: ruda_tensor::BoolDType,
46 ) -> BoolTensor<Host> {
47 HostTensor::empty(shape, DType::from(dtype))
48 }
49
50 fn bool_slice_assign(
51 tensor: BoolTensor<Host>,
52 slices: &[Slice],
53 value: BoolTensor<Host>,
54 ) -> BoolTensor<Host> {
55 crate::ops::slice::slice_assign(tensor, slices, value)
56 }
57
58 fn bool_into_int(tensor: BoolTensor<Host>, out_dtype: ruda_tensor::IntDType) -> IntTensor<Host> {
59 ruprim_host::cast::bool_into_int(tensor, out_dtype)
60 }
61
62 fn bool_into_float(
63 tensor: BoolTensor<Host>,
64 out_dtype: ruda_tensor::FloatDType,
65 ) -> FloatTensor<Host> {
66 ruprim_host::cast::bool_into_float(tensor, out_dtype)
67 }
68
69 fn bool_swap_dims(tensor: BoolTensor<Host>, dim1: usize, dim2: usize) -> BoolTensor<Host> {
70 tensor.transpose(dim1, dim2)
71 }
72
73 fn bool_permute(tensor: BoolTensor<Host>, axes: &[usize]) -> BoolTensor<Host> {
74 tensor.permute(axes)
75 }
76
77 fn bool_flip(tensor: BoolTensor<Host>, axes: &[usize]) -> BoolTensor<Host> {
78 crate::ops::flip::flip(tensor, axes)
79 }
80
81 fn bool_equal(lhs: BoolTensor<Host>, rhs: BoolTensor<Host>) -> BoolTensor<Host> {
82 ruprim_host::boolean::bool_equal(lhs, rhs)
83 }
84
85 fn bool_not(mut tensor: BoolTensor<Host>) -> BoolTensor<Host> {
86 ruprim_host::boolean::bool_not(tensor)
87 }
88
89 fn bool_and(lhs: BoolTensor<Host>, rhs: BoolTensor<Host>) -> BoolTensor<Host> {
90 ruprim_host::boolean::bool_and(lhs, rhs)
91 }
92
93 fn bool_or(lhs: BoolTensor<Host>, rhs: BoolTensor<Host>) -> BoolTensor<Host> {
94 ruprim_host::boolean::bool_or(lhs, rhs)
95 }
96
97 fn bool_xor(lhs: BoolTensor<Host>, rhs: BoolTensor<Host>) -> BoolTensor<Host> {
98 ruprim_host::boolean::bool_xor(lhs, rhs)
99 }
100
101 fn bool_expand(tensor: BoolTensor<Host>, shape: Shape) -> BoolTensor<Host> {
102 crate::ops::expand::expand(tensor, shape)
103 }
104
105 fn bool_zeros(
107 shape: Shape,
108 device: &Device<Host>,
109 dtype: ruda_tensor::BoolDType,
110 ) -> BoolTensor<Host> {
111 Self::bool_empty(shape, device, dtype)
112 }
113
114 fn bool_ones(
115 shape: Shape,
116 _device: &Device<Host>,
117 dtype: ruda_tensor::BoolDType,
118 ) -> BoolTensor<Host> {
119 ruprim_host::boolean::bool_ones(shape, dtype)
120 }
121
122 fn bool_mask_where(
123 tensor: BoolTensor<Host>,
124 mask: BoolTensor<Host>,
125 value: BoolTensor<Host>,
126 ) -> BoolTensor<Host> {
127 crate::ops::mask::mask_where_bool(tensor, mask, value)
128 }
129
130 fn bool_mask_fill(
131 tensor: BoolTensor<Host>,
132 mask: BoolTensor<Host>,
133 value: ruda_tensor::Scalar,
134 ) -> BoolTensor<Host> {
135 let value: bool = value.elem();
136 crate::ops::mask::mask_fill_bool(tensor, mask, value)
137 }
138
139 fn bool_gather(
140 dim: usize,
141 tensor: BoolTensor<Host>,
142 indices: IntTensor<Host>,
143 ) -> BoolTensor<Host> {
144 crate::ops::gather_scatter::gather_bool(tensor, dim, indices)
145 }
146
147 fn bool_scatter_or(
148 dim: usize,
149 tensor: BoolTensor<Host>,
150 indices: IntTensor<Host>,
151 value: BoolTensor<Host>,
152 ) -> BoolTensor<Host> {
153 crate::ops::gather_scatter::scatter_or(tensor, dim, indices, value)
154 }
155
156 fn bool_equal_elem(lhs: BoolTensor<Host>, rhs: ruda_tensor::Scalar) -> BoolTensor<Host> {
157 ruprim_host::boolean::bool_equal_elem(lhs, rhs)
158 }
159
160 fn bool_unfold(
161 tensor: BoolTensor<Host>,
162 dim: usize,
163 size: usize,
164 step: usize,
165 ) -> BoolTensor<Host> {
166 crate::ops::unfold::unfold_bool(tensor, dim, size, step)
167 }
168
169 fn bool_not_equal(lhs: BoolTensor<Host>, rhs: BoolTensor<Host>) -> BoolTensor<Host> {
170 let out_dtype = ruda_tensor::BoolDType::from(lhs.dtype());
171 crate::ops::comparison::bool_not_equal(lhs, rhs, out_dtype)
172 }
173
174 fn bool_not_equal_elem(lhs: BoolTensor<Host>, rhs: ruda_tensor::Scalar) -> BoolTensor<Host> {
175 let out_dtype = ruda_tensor::BoolDType::from(lhs.dtype());
176 let rhs: bool = rhs.elem();
177 crate::ops::comparison::bool_not_equal_elem(lhs, rhs, out_dtype)
178 }
179
180 fn bool_any(tensor: BoolTensor<Host>) -> BoolTensor<Host> {
181 let out_dtype = ruda_tensor::BoolDType::from(tensor.dtype());
182 crate::ops::comparison::any_bool(tensor, out_dtype)
183 }
184
185 fn bool_any_dim(tensor: BoolTensor<Host>, dim: usize) -> BoolTensor<Host> {
186 let out_dtype = ruda_tensor::BoolDType::from(tensor.dtype());
187 crate::ops::comparison::any_bool_dim(tensor, dim, out_dtype)
188 }
189
190 fn bool_all(tensor: BoolTensor<Host>) -> BoolTensor<Host> {
191 let out_dtype = ruda_tensor::BoolDType::from(tensor.dtype());
192 crate::ops::comparison::all_bool(tensor, out_dtype)
193 }
194
195 fn bool_all_dim(tensor: BoolTensor<Host>, dim: usize) -> BoolTensor<Host> {
196 let out_dtype = ruda_tensor::BoolDType::from(tensor.dtype());
197 crate::ops::comparison::all_bool_dim(tensor, dim, out_dtype)
198 }
199
200 fn bool_select(
201 tensor: BoolTensor<Host>,
202 dim: usize,
203 indices: IntTensor<Host>,
204 ) -> BoolTensor<Host> {
205 crate::ops::gather_scatter::select::<u8>(tensor, dim, indices)
206 }
207
208 fn bool_select_or(
209 tensor: BoolTensor<Host>,
210 dim: usize,
211 indices: IntTensor<Host>,
212 value: BoolTensor<Host>,
213 ) -> BoolTensor<Host> {
214 ruprim_host::boolean::bool_select_or(tensor, dim, indices, value)
215 }
216
217 fn bool_transpose(tensor: BoolTensor<Host>) -> BoolTensor<Host> {
218 let ndims = tensor.layout().num_dims();
219 if ndims < 2 {
220 return tensor;
221 }
222 tensor.transpose(ndims - 2, ndims - 1)
223 }
224
225 fn bool_repeat_dim(tensor: BoolTensor<Host>, dim: usize, times: usize) -> BoolTensor<Host> {
226 crate::ops::repeat_dim::repeat_dim(tensor, dim, times)
227 }
228
229 async fn bool_argwhere(tensor: BoolTensor<Host>, out_dtype: IntDType) -> IntTensor<Host> {
230 ruprim_host::boolean::bool_argwhere(tensor, out_dtype).await
231 }
232}
233
234#[cfg(test)]
242mod tests {
243 use alloc::vec;
244 use ruda_tensor::TensorData;
245 use ruda_tensor::ops::BoolTensorOps;
246 use ruda_tensor::{FloatDType, IntDType};
247
248 use crate::{Host, HostTensor};
249
250 #[test]
251 fn test_bool_into_int_u8() {
252 let t = HostTensor::from_data(TensorData::from([true, false, true]));
253 let result = Host::bool_into_int(t, IntDType::U8);
254 assert_eq!(result.dtype(), ruda_tensor::DType::U8);
255 let data: Vec<u8> = result.into_data().to_vec().unwrap();
256 assert_eq!(data, vec![1u8, 0, 1]);
257 }
258
259 #[test]
260 fn test_bool_into_float_f64() {
261 let t = HostTensor::from_data(TensorData::from([true, false, true]));
262 let result = Host::bool_into_float(t, FloatDType::F64);
263 assert_eq!(result.dtype(), ruda_tensor::DType::F64);
264 let data: Vec<f64> = result.into_data().to_vec().unwrap();
265 assert_eq!(data, vec![1.0f64, 0.0, 1.0]);
266 }
267}