Skip to main content

burn_dispatch/ops/
tensor.rs

1use alloc::vec::Vec;
2use burn_backend::{
3    BoolDType, ExecutionError, FloatDType, IntDType, Scalar, Shape, Slice, TensorData,
4    ops::FloatTensorOps,
5    tensor::{BoolTensor, FloatTensor, IndexingUpdateOp, IntTensor},
6};
7
8use crate::{Dispatch, DispatchDevice};
9
10impl FloatTensorOps<Self> for Dispatch {
11    fn float_from_data(
12        data: burn_backend::TensorData,
13        device: &DispatchDevice,
14    ) -> FloatTensor<Self> {
15        creation_op!(Float, device, |device| B::float_from_data(data, device))
16    }
17
18    fn float_random(
19        shape: Shape,
20        distribution: burn_backend::Distribution,
21        device: &DispatchDevice,
22        dtype: FloatDType,
23    ) -> FloatTensor<Self> {
24        creation_op!(Float, device, |device| {
25            B::float_random(shape, distribution, device, dtype)
26        })
27    }
28
29    async fn float_into_data(tensor: FloatTensor<Self>) -> Result<TensorData, ExecutionError> {
30        unary_float!(tensor, float, |tensor| B::float_into_data(tensor).await)
31    }
32
33    fn float_to_device(tensor: FloatTensor<Self>, device: &DispatchDevice) -> FloatTensor<Self> {
34        // Relocating a non-tracked float tensor onto an autodiff device is a plain data move:
35        // place it on the underlying hardware device and leave the tensor non-tracked. The
36        // int/bool `to_device` paths already handle this case; only the float path used to
37        // panic. This is what lets gradient tensors — which are never autodiff-tracked — be
38        // moved onto the autodiff `device_main` during multi-device training.
39        #[cfg(feature = "autodiff")]
40        if let DispatchDevice::Autodiff(device_ad) = device
41            && !matches!(&tensor.kind, crate::DispatchTensorKind::Autodiff(_))
42        {
43            return Self::float_to_device(tensor, &device_ad.inner);
44        }
45
46        float_to_device!(
47            Float,
48            float,
49            tensor,
50            device,
51            float_to_device,
52            |inner, device| {
53                let data =
54                    burn_backend::read_sync(B1::float_into_data(inner)).expect("Should read data");
55                B2::float_from_data(data, device)
56            }
57        )
58    }
59
60    fn float_into_int(tensor: FloatTensor<Self>, dtype: burn_backend::IntDType) -> IntTensor<Self> {
61        unary_float!(tensor, float, |tensor| B::float_into_int(tensor, dtype) => Int)
62    }
63
64    fn float_empty(shape: Shape, device: &DispatchDevice, dtype: FloatDType) -> FloatTensor<Self> {
65        creation_op!(Float, device, |device| B::float_empty(shape, device, dtype))
66    }
67
68    fn float_add(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
69        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_add(lhs, rhs) => Float)
70    }
71
72    fn float_add_scalar(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
73        unary_float!(lhs, float, |lhs| B::float_add_scalar(lhs, rhs) => Float)
74    }
75
76    fn float_sub(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
77        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_sub(lhs, rhs) => Float)
78    }
79
80    fn float_sub_scalar(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
81        unary_float!(lhs, float, |lhs| B::float_sub_scalar(lhs, rhs) => Float)
82    }
83
84    fn float_mul(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
85        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_mul(lhs, rhs) => Float)
86    }
87
88    fn float_mul_scalar(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
89        unary_float!(lhs, float, |lhs| B::float_mul_scalar(lhs, rhs) => Float)
90    }
91
92    fn float_div(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
93        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_div(lhs, rhs) => Float)
94    }
95
96    fn float_div_scalar(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
97        unary_float!(lhs, float, |lhs| B::float_div_scalar(lhs, rhs) => Float)
98    }
99
100    fn float_remainder(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
101        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_remainder(lhs, rhs) => Float)
102    }
103
104    fn float_remainder_scalar(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
105        unary_float!(lhs, float, |lhs| B::float_remainder_scalar(lhs, rhs) => Float)
106    }
107
108    fn float_matmul(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
109        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_matmul(lhs, rhs) => Float)
110    }
111
112    fn float_cross(
113        lhs: FloatTensor<Self>,
114        rhs: FloatTensor<Self>,
115        dim: usize,
116    ) -> FloatTensor<Self> {
117        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_cross(lhs, rhs, dim) => Float)
118    }
119
120    fn float_recip(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
121        unary_float!(tensor, float, |tensor| B::float_recip(tensor) => Float)
122    }
123
124    fn float_swap_dims(tensor: FloatTensor<Self>, dim1: usize, dim2: usize) -> FloatTensor<Self> {
125        unary_float!(tensor, float, |tensor| B::float_swap_dims(tensor, dim1, dim2) => Float)
126    }
127
128    fn float_permute(tensor: FloatTensor<Self>, axes: &[usize]) -> FloatTensor<Self> {
129        unary_float!(tensor, float, |tensor| B::float_permute(tensor, axes) => Float)
130    }
131
132    fn float_flip(tensor: FloatTensor<Self>, axes: &[usize]) -> FloatTensor<Self> {
133        unary_float!(tensor, float, |tensor| B::float_flip(tensor, axes) => Float)
134    }
135
136    fn float_reshape(tensor: FloatTensor<Self>, shape: Shape) -> FloatTensor<Self> {
137        unary_float!(tensor, float, |tensor| B::float_reshape(tensor, shape) => Float)
138    }
139
140    fn float_gather(
141        dim: usize,
142        tensor: FloatTensor<Self>,
143        indices: IntTensor<Self>,
144    ) -> FloatTensor<Self> {
145        binary_float!((tensor, float), (indices, int), |tensor, indices| B::float_gather(dim, tensor, indices) => Float)
146    }
147
148    fn float_scatter_add(
149        dim: usize,
150        tensor: FloatTensor<Self>,
151        indices: IntTensor<Self>,
152        value: FloatTensor<Self>,
153    ) -> FloatTensor<Self> {
154        multi_op!(
155            inputs[(tensor, float), (indices, int), (value, float)], => Float,
156            B::float_scatter_add(dim, tensor, indices, value)
157        )
158    }
159
160    fn float_scatter(
161        dim: usize,
162        tensor: FloatTensor<Self>,
163        indices: IntTensor<Self>,
164        value: FloatTensor<Self>,
165        update: IndexingUpdateOp,
166    ) -> FloatTensor<Self> {
167        multi_op!(
168            inputs[(tensor, float), (indices, int), (value, float)], => Float,
169            B::float_scatter(dim, tensor, indices, value, update)
170        )
171    }
172
173    fn float_scatter_nd(
174        data: FloatTensor<Self>,
175        indices: IntTensor<Self>,
176        values: FloatTensor<Self>,
177        reduction: burn_backend::tensor::IndexingUpdateOp,
178    ) -> FloatTensor<Self> {
179        multi_op!(
180            inputs[(data, float), (indices, int), (values, float)], => Float,
181            B::float_scatter_nd(data, indices, values, reduction)
182        )
183    }
184
185    fn float_gather_nd(data: FloatTensor<Self>, indices: IntTensor<Self>) -> FloatTensor<Self> {
186        binary_float!((data, float), (indices, int), |data, indices| B::float_gather_nd(data, indices) => Float)
187    }
188
189    fn float_select(
190        tensor: FloatTensor<Self>,
191        dim: usize,
192        indices: IntTensor<Self>,
193    ) -> FloatTensor<Self> {
194        binary_float!((tensor, float), (indices, int), |tensor, indices| B::float_select(tensor, dim, indices) => Float)
195    }
196
197    fn float_select_add(
198        tensor: FloatTensor<Self>,
199        dim: usize,
200        indices: IntTensor<Self>,
201        value: FloatTensor<Self>,
202    ) -> FloatTensor<Self> {
203        multi_op!(
204            inputs[(tensor, float), (indices, int), (value, float)], => Float,
205            B::float_select_add(tensor, dim, indices, value)
206        )
207    }
208
209    fn float_select_assign(
210        tensor: FloatTensor<Self>,
211        dim: usize,
212        indices: IntTensor<Self>,
213        value: FloatTensor<Self>,
214        update: IndexingUpdateOp,
215    ) -> FloatTensor<Self> {
216        multi_op!(
217            inputs[(tensor, float), (indices, int), (value, float)], => Float,
218            B::float_select_assign(tensor, dim, indices, value, update)
219        )
220    }
221
222    fn float_slice(tensor: FloatTensor<Self>, slices: &[Slice]) -> FloatTensor<Self> {
223        unary_float!(tensor, float, |tensor| B::float_slice(tensor, slices) => Float)
224    }
225
226    fn float_slice_assign(
227        tensor: FloatTensor<Self>,
228        slices: &[Slice],
229        value: FloatTensor<Self>,
230    ) -> FloatTensor<Self> {
231        binary_float!((tensor, float), (value, float), |tensor, value| B::float_slice_assign(tensor, slices, value) => Float)
232    }
233
234    fn float_mask_where(
235        tensor: FloatTensor<Self>,
236        mask: BoolTensor<Self>,
237        value: FloatTensor<Self>,
238    ) -> FloatTensor<Self> {
239        multi_op!(
240            inputs[(tensor, float), (mask, bool), (value, float)], => Float,
241            B::float_mask_where(tensor, mask, value)
242        )
243    }
244
245    fn float_mask_fill(
246        tensor: FloatTensor<Self>,
247        mask: BoolTensor<Self>,
248        value: Scalar,
249    ) -> FloatTensor<Self> {
250        binary_float!((tensor, float), (mask, bool), |tensor, mask| B::float_mask_fill(tensor, mask, value) => Float)
251    }
252
253    async fn float_mask_select(
254        tensor: FloatTensor<Self>,
255        mask: BoolTensor<Self>,
256    ) -> FloatTensor<Self> {
257        binary_float!((tensor, float), (mask, bool), |tensor, mask| B::float_mask_select(tensor, mask).await => Float)
258    }
259
260    fn float_equal(
261        lhs: FloatTensor<Self>,
262        rhs: FloatTensor<Self>,
263        out_dtype: BoolDType,
264    ) -> BoolTensor<Self> {
265        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_equal(lhs, rhs, out_dtype) => Bool)
266    }
267
268    fn float_equal_elem(
269        lhs: FloatTensor<Self>,
270        rhs: Scalar,
271        out_dtype: BoolDType,
272    ) -> BoolTensor<Self> {
273        unary_float!(lhs, float, |lhs| B::float_equal_elem(lhs, rhs, out_dtype) => Bool)
274    }
275
276    fn float_greater(
277        lhs: FloatTensor<Self>,
278        rhs: FloatTensor<Self>,
279        out_dtype: BoolDType,
280    ) -> BoolTensor<Self> {
281        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_greater(lhs, rhs, out_dtype) => Bool)
282    }
283
284    fn float_greater_elem(
285        lhs: FloatTensor<Self>,
286        rhs: Scalar,
287        out_dtype: BoolDType,
288    ) -> BoolTensor<Self> {
289        unary_float!(lhs, float, |lhs| B::float_greater_elem(lhs, rhs, out_dtype) => Bool)
290    }
291
292    fn float_greater_equal(
293        lhs: FloatTensor<Self>,
294        rhs: FloatTensor<Self>,
295        out_dtype: BoolDType,
296    ) -> BoolTensor<Self> {
297        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_greater_equal(lhs, rhs, out_dtype) => Bool)
298    }
299
300    fn float_greater_equal_elem(
301        lhs: FloatTensor<Self>,
302        rhs: Scalar,
303        out_dtype: BoolDType,
304    ) -> BoolTensor<Self> {
305        unary_float!(lhs, float, |lhs| B::float_greater_equal_elem(lhs, rhs, out_dtype) => Bool)
306    }
307
308    fn float_lower(
309        lhs: FloatTensor<Self>,
310        rhs: FloatTensor<Self>,
311        out_dtype: BoolDType,
312    ) -> BoolTensor<Self> {
313        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_lower(lhs, rhs, out_dtype) => Bool)
314    }
315
316    fn float_lower_elem(
317        lhs: FloatTensor<Self>,
318        rhs: Scalar,
319        out_dtype: BoolDType,
320    ) -> BoolTensor<Self> {
321        unary_float!(lhs, float, |lhs| B::float_lower_elem(lhs, rhs, out_dtype) => Bool)
322    }
323
324    fn float_lower_equal(
325        lhs: FloatTensor<Self>,
326        rhs: FloatTensor<Self>,
327        out_dtype: BoolDType,
328    ) -> BoolTensor<Self> {
329        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_lower_equal(lhs, rhs, out_dtype) => Bool)
330    }
331
332    fn float_lower_equal_elem(
333        lhs: FloatTensor<Self>,
334        rhs: Scalar,
335        out_dtype: BoolDType,
336    ) -> BoolTensor<Self> {
337        unary_float!(lhs, float, |lhs| B::float_lower_equal_elem(lhs, rhs, out_dtype) => Bool)
338    }
339
340    fn float_sum(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
341        unary_float!(tensor, float, |tensor| B::float_sum(tensor) => Float)
342    }
343
344    fn float_sum_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
345        unary_float!(tensor, float, |tensor| B::float_sum_dim(tensor, dim) => Float)
346    }
347
348    fn float_mean_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
349        unary_float!(tensor, float, |tensor| B::float_mean_dim(tensor, dim) => Float)
350    }
351
352    fn float_cumsum(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
353        unary_float!(tensor, float, |tensor| B::float_cumsum(tensor, dim) => Float)
354    }
355
356    fn float_cumprod(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
357        unary_float!(tensor, float, |tensor| B::float_cumprod(tensor, dim) => Float)
358    }
359
360    fn float_cummin(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
361        unary_float!(tensor, float, |tensor| B::float_cummin(tensor, dim) => Float)
362    }
363
364    fn float_cummax(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
365        unary_float!(tensor, float, |tensor| B::float_cummax(tensor, dim) => Float)
366    }
367
368    fn float_cast(tensor: FloatTensor<Self>, dtype: FloatDType) -> FloatTensor<Self> {
369        unary_float!(tensor, float, |tensor| B::float_cast(tensor, dtype) => Float)
370    }
371
372    fn float_exp(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
373        unary_float!(tensor, float, |tensor| B::float_exp(tensor) => Float)
374    }
375
376    fn float_log(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
377        unary_float!(tensor, float, |tensor| B::float_log(tensor) => Float)
378    }
379
380    fn float_log1p(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
381        unary_float!(tensor, float, |tensor| B::float_log1p(tensor) => Float)
382    }
383
384    fn float_powf(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
385        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_powf(lhs, rhs) => Float)
386    }
387
388    fn float_powf_scalar_impl(tensor: FloatTensor<Self>, value: Scalar) -> FloatTensor<Self> {
389        unary_float!(tensor, float, |tensor| B::float_powf_scalar_impl(tensor, value) => Float)
390    }
391
392    fn float_sqrt(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
393        unary_float!(tensor, float, |tensor| B::float_sqrt(tensor) => Float)
394    }
395
396    fn float_abs(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
397        unary_float!(tensor, float, |tensor| B::float_abs(tensor) => Float)
398    }
399
400    fn float_cos(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
401        unary_float!(tensor, float, |tensor| B::float_cos(tensor) => Float)
402    }
403
404    fn float_sin(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
405        unary_float!(tensor, float, |tensor| B::float_sin(tensor) => Float)
406    }
407
408    fn float_tan(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
409        unary_float!(tensor, float, |tensor| B::float_tan(tensor) => Float)
410    }
411
412    fn float_cosh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
413        unary_float!(tensor, float, |tensor| B::float_cosh(tensor) => Float)
414    }
415
416    fn float_sinh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
417        unary_float!(tensor, float, |tensor| B::float_sinh(tensor) => Float)
418    }
419
420    fn float_tanh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
421        unary_float!(tensor, float, |tensor| B::float_tanh(tensor) => Float)
422    }
423
424    fn float_acos(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
425        unary_float!(tensor, float, |tensor| B::float_acos(tensor) => Float)
426    }
427
428    fn float_acosh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
429        unary_float!(tensor, float, |tensor| B::float_acosh(tensor) => Float)
430    }
431
432    fn float_asin(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
433        unary_float!(tensor, float, |tensor| B::float_asin(tensor) => Float)
434    }
435
436    fn float_asinh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
437        unary_float!(tensor, float, |tensor| B::float_asinh(tensor) => Float)
438    }
439
440    fn float_atan(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
441        unary_float!(tensor, float, |tensor| B::float_atan(tensor) => Float)
442    }
443
444    fn float_atanh(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
445        unary_float!(tensor, float, |tensor| B::float_atanh(tensor) => Float)
446    }
447
448    fn float_atan2(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
449        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_atan2(lhs, rhs) => Float)
450    }
451
452    fn float_round(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
453        unary_float!(tensor, float, |tensor| B::float_round(tensor) => Float)
454    }
455
456    fn float_floor(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
457        unary_float!(tensor, float, |tensor| B::float_floor(tensor) => Float)
458    }
459
460    fn float_ceil(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
461        unary_float!(tensor, float, |tensor| B::float_ceil(tensor) => Float)
462    }
463
464    fn float_trunc(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
465        unary_float!(tensor, float, |tensor| B::float_trunc(tensor) => Float)
466    }
467
468    fn float_erf(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
469        unary_float!(tensor, float, |tensor| B::float_erf(tensor) => Float)
470    }
471
472    fn float_argmax(tensor: FloatTensor<Self>, dim: usize, out_dtype: IntDType) -> IntTensor<Self> {
473        unary_float!(tensor, float, |tensor| B::float_argmax(tensor, dim, out_dtype) => Int)
474    }
475
476    fn float_argtopk(
477        tensor: FloatTensor<Self>,
478        dim: usize,
479        k: usize,
480        out_dtype: IntDType,
481    ) -> IntTensor<Self> {
482        unary_float!(tensor, float, |tensor| B::float_argtopk(tensor, dim, k, out_dtype) => Int)
483    }
484
485    fn float_topk(tensor: FloatTensor<Self>, dim: usize, k: usize) -> FloatTensor<Self> {
486        unary_float!(tensor, float, |tensor| B::float_topk(tensor, dim, k) => Float)
487    }
488
489    fn float_topk_with_indices(
490        tensor: FloatTensor<Self>,
491        dim: usize,
492        k: usize,
493        out_dtype: IntDType,
494    ) -> (FloatTensor<Self>, IntTensor<Self>) {
495        multi_op!(
496            inputs[(tensor, float)],
497            outputs[(out, Float), (indices, Int)],
498            B::float_topk_with_indices(tensor, dim, k, out_dtype)
499        )
500    }
501
502    fn float_argmin(tensor: FloatTensor<Self>, dim: usize, out_dtype: IntDType) -> IntTensor<Self> {
503        unary_float!(tensor, float, |tensor| B::float_argmin(tensor, dim, out_dtype) => Int)
504    }
505
506    fn float_expand(tensor: FloatTensor<Self>, shape: Shape) -> FloatTensor<Self> {
507        unary_float!(tensor, float, |tensor| B::float_expand(tensor, shape) => Float)
508    }
509
510    fn float_unfold(
511        tensor: FloatTensor<Self>,
512        dim: usize,
513        size: usize,
514        step: usize,
515    ) -> FloatTensor<Self> {
516        unary_float!(tensor, float, |tensor| {
517            B::float_unfold(tensor, dim, size, step)
518        } => Float)
519    }
520
521    fn float_detach(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
522        unary_float!(tensor, float, |tensor| B::float_detach(tensor) => Float)
523    }
524
525    fn float_set_require_grad(tensor: FloatTensor<Self>, require_grad: bool) -> FloatTensor<Self> {
526        unary_float!(tensor, float, |tensor| B::float_set_require_grad(tensor, require_grad) => Float)
527    }
528
529    fn float_is_require_grad(tensor: &FloatTensor<Self>) -> bool {
530        unary_float!(ref tensor, float, |tensor| B::float_is_require_grad(tensor))
531    }
532
533    // Default implementation
534    fn float_zeros(shape: Shape, device: &DispatchDevice, dtype: FloatDType) -> FloatTensor<Self> {
535        creation_op!(Float, device, |device| B::float_zeros(shape, device, dtype))
536    }
537
538    fn float_ones(shape: Shape, device: &DispatchDevice, dtype: FloatDType) -> FloatTensor<Self> {
539        creation_op!(Float, device, |device| B::float_ones(shape, device, dtype))
540    }
541
542    fn float_full(
543        shape: Shape,
544        fill_value: Scalar,
545        device: &DispatchDevice,
546        dtype: FloatDType,
547    ) -> FloatTensor<Self> {
548        creation_op!(Float, device, |device| B::float_full(
549            shape, fill_value, device, dtype
550        ))
551    }
552
553    fn float_repeat_dim(tensor: FloatTensor<Self>, dim: usize, times: usize) -> FloatTensor<Self> {
554        unary_float!(tensor, float, |tensor| B::float_repeat_dim(tensor, dim, times) => Float)
555    }
556
557    fn float_clamp_min(tensor: FloatTensor<Self>, min: Scalar) -> FloatTensor<Self> {
558        unary_float!(tensor, float, |tensor| B::float_clamp_min(tensor, min) => Float)
559    }
560
561    fn float_clamp_max(tensor: FloatTensor<Self>, max: Scalar) -> FloatTensor<Self> {
562        unary_float!(tensor, float, |tensor| B::float_clamp_max(tensor, max) => Float)
563    }
564
565    fn float_clamp(tensor: FloatTensor<Self>, min: Scalar, max: Scalar) -> FloatTensor<Self> {
566        unary_float!(tensor, float, |tensor| B::float_clamp(tensor, min, max) => Float)
567    }
568
569    fn float_neg(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
570        unary_float!(tensor, float, |tensor| B::float_neg(tensor) => Float)
571    }
572
573    fn float_transpose(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
574        unary_float!(tensor, float, |tensor| B::float_transpose(tensor) => Float)
575    }
576
577    fn float_not_equal(
578        lhs: FloatTensor<Self>,
579        rhs: FloatTensor<Self>,
580        out_dtype: BoolDType,
581    ) -> BoolTensor<Self> {
582        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_not_equal(lhs, rhs, out_dtype) => Bool)
583    }
584
585    fn float_not_equal_elem(
586        lhs: FloatTensor<Self>,
587        rhs: Scalar,
588        out_dtype: BoolDType,
589    ) -> BoolTensor<Self> {
590        unary_float!(lhs, float, |lhs| B::float_not_equal_elem(lhs, rhs, out_dtype) => Bool)
591    }
592
593    fn float_prod(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
594        unary_float!(tensor, float, |tensor| B::float_prod(tensor) => Float)
595    }
596
597    fn float_prod_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
598        unary_float!(tensor, float, |tensor| B::float_prod_dim(tensor, dim) => Float)
599    }
600
601    fn float_mean(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
602        unary_float!(tensor, float, |tensor| B::float_mean(tensor) => Float)
603    }
604
605    fn float_powi(lhs: FloatTensor<Self>, rhs: IntTensor<Self>) -> FloatTensor<Self> {
606        binary_float!((lhs, float), (rhs, int), |lhs, rhs| B::float_powi(lhs, rhs) => Float)
607    }
608
609    fn float_powi_scalar_impl(lhs: FloatTensor<Self>, rhs: Scalar) -> FloatTensor<Self> {
610        unary_float!(lhs, float, |lhs| B::float_powi_scalar_impl(lhs, rhs) => Float)
611    }
612
613    fn float_powf_scalar(tensor: FloatTensor<Self>, value: Scalar) -> FloatTensor<Self> {
614        unary_float!(tensor, float, |tensor| B::float_powf_scalar(tensor, value) => Float)
615    }
616
617    fn float_cat(tensors: Vec<FloatTensor<Self>>, dim: usize) -> FloatTensor<Self> {
618        vec_op!(tensors, float, |tensors| B::float_cat(tensors, dim) => Float)
619    }
620
621    fn float_max(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
622        unary_float!(tensor, float, |tensor| B::float_max(tensor) => Float)
623    }
624
625    fn float_max_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
626        unary_float!(tensor, float, |tensor| B::float_max_dim(tensor, dim) => Float)
627    }
628
629    fn float_max_dim_with_indices(
630        tensor: FloatTensor<Self>,
631        dim: usize,
632        indices_dtype: IntDType,
633    ) -> (FloatTensor<Self>, IntTensor<Self>) {
634        multi_op!(
635            inputs[(tensor, float)],
636            outputs[(out, Float), (indices, Int)],
637            B::float_max_dim_with_indices(tensor, dim, indices_dtype)
638        )
639    }
640
641    fn float_min(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
642        unary_float!(tensor, float, |tensor| B::float_min(tensor) => Float)
643    }
644
645    fn float_min_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
646        unary_float!(tensor, float, |tensor| B::float_min_dim(tensor, dim) => Float)
647    }
648
649    fn float_min_dim_with_indices(
650        tensor: FloatTensor<Self>,
651        dim: usize,
652        indices_dtype: IntDType,
653    ) -> (FloatTensor<Self>, IntTensor<Self>) {
654        multi_op!(
655            inputs[(tensor, float)],
656            outputs[(out, Float), (indices, Int)],
657            B::float_min_dim_with_indices(tensor, dim, indices_dtype)
658        )
659    }
660
661    fn float_max_abs(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
662        unary_float!(tensor, float, |tensor| B::float_max_abs(tensor) => Float)
663    }
664
665    fn float_max_abs_dim(tensor: FloatTensor<Self>, dim: usize) -> FloatTensor<Self> {
666        unary_float!(tensor, float, |tensor| B::float_max_abs_dim(tensor, dim) => Float)
667    }
668
669    fn float_any(tensor: FloatTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
670        unary_float!(tensor, float, |tensor| B::float_any(tensor, out_dtype) => Bool)
671    }
672
673    fn float_any_dim(
674        tensor: FloatTensor<Self>,
675        dim: usize,
676        out_dtype: BoolDType,
677    ) -> BoolTensor<Self> {
678        unary_float!(tensor, float, |tensor| B::float_any_dim(tensor, dim, out_dtype) => Bool)
679    }
680
681    fn float_all(tensor: FloatTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
682        unary_float!(tensor, float, |tensor| B::float_all(tensor, out_dtype) => Bool)
683    }
684
685    fn float_all_dim(
686        tensor: FloatTensor<Self>,
687        dim: usize,
688        out_dtype: BoolDType,
689    ) -> BoolTensor<Self> {
690        unary_float!(tensor, float, |tensor| B::float_all_dim(tensor, dim, out_dtype) => Bool)
691    }
692
693    fn float_sign(tensor: FloatTensor<Self>) -> FloatTensor<Self> {
694        unary_float!(tensor, float, |tensor| B::float_sign(tensor) => Float)
695    }
696
697    fn float_sort(tensor: FloatTensor<Self>, dim: usize, descending: bool) -> FloatTensor<Self> {
698        unary_float!(tensor, float, |tensor| B::float_sort(tensor, dim, descending) => Float)
699    }
700
701    fn float_sort_with_indices(
702        tensor: FloatTensor<Self>,
703        dim: usize,
704        descending: bool,
705        indices_dtype: IntDType,
706    ) -> (FloatTensor<Self>, IntTensor<Self>) {
707        multi_op!(
708            inputs[(tensor, float)],
709            outputs[(out, Float), (indices, Int)],
710            B::float_sort_with_indices(tensor, dim, descending, indices_dtype)
711        )
712    }
713
714    fn float_argsort(
715        tensor: FloatTensor<Self>,
716        dim: usize,
717        descending: bool,
718        out_dtype: IntDType,
719    ) -> IntTensor<Self> {
720        unary_float!(tensor, float, |tensor| B::float_argsort(tensor, dim, descending, out_dtype) => Int)
721    }
722
723    fn float_grid_sample_2d(
724        tensor: FloatTensor<Self>,
725        grid: FloatTensor<Self>,
726        options: burn_backend::ops::GridSampleOptions,
727    ) -> FloatTensor<Self> {
728        binary_float!((tensor, float), (grid, float), |tensor, grid| B::float_grid_sample_2d(tensor, grid, options) => Float)
729    }
730
731    fn float_is_nan(tensor: FloatTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
732        unary_float!(tensor, float, |tensor| B::float_is_nan(tensor, out_dtype) => Bool)
733    }
734
735    fn float_is_inf(tensor: FloatTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
736        unary_float!(tensor, float, |tensor| B::float_is_inf(tensor, out_dtype) => Bool)
737    }
738
739    fn float_hypot(lhs: FloatTensor<Self>, rhs: FloatTensor<Self>) -> FloatTensor<Self> {
740        binary_float!((lhs, float), (rhs, float), |lhs, rhs| B::float_hypot(lhs, rhs) => Float)
741    }
742}