Skip to main content

burn_dispatch/ops/
int_tensor.rs

1use alloc::vec::Vec;
2use burn_backend::{
3    BoolDType, ExecutionError, FloatDType, IntDType, Scalar, Shape, Slice, TensorData,
4    ops::IntTensorOps,
5    tensor::{BoolTensor, FloatTensor, IntTensor},
6};
7
8use crate::{Dispatch, DispatchDevice};
9
10impl IntTensorOps<Self> for Dispatch {
11    fn int_empty(shape: Shape, device: &DispatchDevice, dtype: IntDType) -> IntTensor<Self> {
12        creation_op!(Int, device, |device| B::int_empty(shape, device, dtype))
13    }
14
15    async fn int_into_data(tensor: IntTensor<Self>) -> Result<TensorData, ExecutionError> {
16        unary_op!(tensor, int, |tensor| B::int_into_data(tensor).await)
17    }
18
19    fn int_from_data(data: TensorData, device: &DispatchDevice) -> IntTensor<Self> {
20        creation_op!(Int, device, |device| B::int_from_data(data, device))
21    }
22
23    fn int_to_device(tensor: IntTensor<Self>, device: &DispatchDevice) -> IntTensor<Self> {
24        to_device!(Int, int, tensor, device, int_to_device, |inner, device| {
25            let data = burn_backend::read_sync(B1::int_into_data(inner)).expect("Should read data");
26            B2::int_from_data(data, device)
27        })
28    }
29
30    fn int_reshape(tensor: IntTensor<Self>, shape: Shape) -> IntTensor<Self> {
31        unary_op!(tensor, int, |tensor| B::int_reshape(tensor, shape) => Int)
32    }
33
34    fn int_slice(tensor: IntTensor<Self>, slices: &[Slice]) -> IntTensor<Self> {
35        unary_op!(tensor, int, |tensor| B::int_slice(tensor, slices) => Int)
36    }
37
38    fn int_slice_assign(
39        tensor: IntTensor<Self>,
40        slices: &[Slice],
41        value: IntTensor<Self>,
42    ) -> IntTensor<Self> {
43        binary_op!((tensor, int), (value, int), |tensor, value| B::int_slice_assign(tensor, slices, value) => Int)
44    }
45
46    fn int_into_float(tensor: IntTensor<Self>, out_dtype: FloatDType) -> FloatTensor<Self> {
47        unary_op!(tensor, int, |tensor| B::int_into_float(tensor, out_dtype) => Float)
48    }
49
50    fn int_mask_where(
51        tensor: IntTensor<Self>,
52        mask: BoolTensor<Self>,
53        value: IntTensor<Self>,
54    ) -> IntTensor<Self> {
55        multi_op!(
56            inputs[(tensor, int), (mask, bool), (value, int)], => Int,
57            B::int_mask_where(tensor, mask, value)
58        )
59    }
60
61    fn int_mask_fill(
62        tensor: IntTensor<Self>,
63        mask: BoolTensor<Self>,
64        value: Scalar,
65    ) -> IntTensor<Self> {
66        binary_op!((tensor, int), (mask, bool), |tensor, mask| B::int_mask_fill(tensor, mask, value) => Int)
67    }
68
69    fn int_gather(
70        dim: usize,
71        tensor: IntTensor<Self>,
72        indices: IntTensor<Self>,
73    ) -> IntTensor<Self> {
74        binary_op!((tensor, int), (indices, int), |tensor, indices| B::int_gather(dim, tensor, indices) => Int)
75    }
76
77    fn int_scatter_add(
78        dim: usize,
79        tensor: IntTensor<Self>,
80        indices: IntTensor<Self>,
81        value: IntTensor<Self>,
82    ) -> IntTensor<Self> {
83        multi_op!(
84            inputs[(tensor, int), (indices, int), (value, int)], => Int,
85            B::int_scatter_add(dim, tensor, indices, value)
86        )
87    }
88
89    fn int_scatter_nd(
90        data: IntTensor<Self>,
91        indices: IntTensor<Self>,
92        values: IntTensor<Self>,
93        reduction: burn_backend::tensor::IndexingUpdateOp,
94    ) -> IntTensor<Self> {
95        multi_op!(
96            inputs[(data, int), (indices, int), (values, int)], => Int,
97            B::int_scatter_nd(data, indices, values, reduction)
98        )
99    }
100
101    fn int_gather_nd(data: IntTensor<Self>, indices: IntTensor<Self>) -> IntTensor<Self> {
102        binary_op!((data, int), (indices, int), |data, indices| B::int_gather_nd(data, indices) => Int)
103    }
104
105    fn int_select(
106        tensor: IntTensor<Self>,
107        dim: usize,
108        indices: IntTensor<Self>,
109    ) -> IntTensor<Self> {
110        binary_op!((tensor, int), (indices, int), |tensor, indices| B::int_select(tensor, dim, indices) => Int)
111    }
112
113    fn int_select_add(
114        tensor: IntTensor<Self>,
115        dim: usize,
116        indices: IntTensor<Self>,
117        value: IntTensor<Self>,
118    ) -> IntTensor<Self> {
119        multi_op!(
120            inputs[(tensor, int), (indices, int), (value, int)], => Int,
121            B::int_select_add(tensor, dim, indices, value)
122        )
123    }
124
125    fn int_equal(
126        lhs: IntTensor<Self>,
127        rhs: IntTensor<Self>,
128        out_dtype: BoolDType,
129    ) -> BoolTensor<Self> {
130        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_equal(lhs, rhs, out_dtype) => Bool)
131    }
132
133    fn int_equal_elem(lhs: IntTensor<Self>, rhs: Scalar, out_dtype: BoolDType) -> BoolTensor<Self> {
134        unary_op!(lhs, int, |lhs| B::int_equal_elem(lhs, rhs, out_dtype) => Bool)
135    }
136
137    fn int_greater(
138        lhs: IntTensor<Self>,
139        rhs: IntTensor<Self>,
140        out_dtype: BoolDType,
141    ) -> BoolTensor<Self> {
142        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_greater(lhs, rhs, out_dtype) => Bool)
143    }
144
145    fn int_greater_elem(
146        lhs: IntTensor<Self>,
147        rhs: Scalar,
148        out_dtype: BoolDType,
149    ) -> BoolTensor<Self> {
150        unary_op!(lhs, int, |lhs| B::int_greater_elem(lhs, rhs, out_dtype) => Bool)
151    }
152
153    fn int_greater_equal(
154        lhs: IntTensor<Self>,
155        rhs: IntTensor<Self>,
156        out_dtype: BoolDType,
157    ) -> BoolTensor<Self> {
158        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_greater_equal(lhs, rhs, out_dtype) => Bool)
159    }
160
161    fn int_greater_equal_elem(
162        lhs: IntTensor<Self>,
163        rhs: Scalar,
164        out_dtype: BoolDType,
165    ) -> BoolTensor<Self> {
166        unary_op!(lhs, int, |lhs| B::int_greater_equal_elem(lhs, rhs, out_dtype) => Bool)
167    }
168
169    fn int_lower(
170        lhs: IntTensor<Self>,
171        rhs: IntTensor<Self>,
172        out_dtype: BoolDType,
173    ) -> BoolTensor<Self> {
174        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_lower(lhs, rhs, out_dtype) => Bool)
175    }
176
177    fn int_lower_elem(lhs: IntTensor<Self>, rhs: Scalar, out_dtype: BoolDType) -> BoolTensor<Self> {
178        unary_op!(lhs, int, |lhs| B::int_lower_elem(lhs, rhs, out_dtype) => Bool)
179    }
180
181    fn int_lower_equal(
182        lhs: IntTensor<Self>,
183        rhs: IntTensor<Self>,
184        out_dtype: BoolDType,
185    ) -> BoolTensor<Self> {
186        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_lower_equal(lhs, rhs, out_dtype) => Bool)
187    }
188
189    fn int_lower_equal_elem(
190        lhs: IntTensor<Self>,
191        rhs: Scalar,
192        out_dtype: BoolDType,
193    ) -> BoolTensor<Self> {
194        unary_op!(lhs, int, |lhs| B::int_lower_equal_elem(lhs, rhs, out_dtype) => Bool)
195    }
196
197    fn int_add(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
198        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_add(lhs, rhs) => Int)
199    }
200
201    fn int_add_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
202        unary_op!(lhs, int, |lhs| B::int_add_scalar(lhs, rhs) => Int)
203    }
204
205    fn int_sub(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
206        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_sub(lhs, rhs) => Int)
207    }
208
209    fn int_sub_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
210        unary_op!(lhs, int, |lhs| B::int_sub_scalar(lhs, rhs) => Int)
211    }
212
213    fn int_mul(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
214        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_mul(lhs, rhs) => Int)
215    }
216
217    fn int_mul_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
218        unary_op!(lhs, int, |lhs| B::int_mul_scalar(lhs, rhs) => Int)
219    }
220
221    fn int_div(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
222        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_div(lhs, rhs) => Int)
223    }
224
225    fn int_div_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
226        unary_op!(lhs, int, |lhs| B::int_div_scalar(lhs, rhs) => Int)
227    }
228
229    fn int_remainder(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
230        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_remainder(lhs, rhs) => Int)
231    }
232
233    fn int_remainder_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
234        unary_op!(lhs, int, |lhs| B::int_remainder_scalar(lhs, rhs) => Int)
235    }
236
237    fn int_matmul(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
238        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_matmul(lhs, rhs) => Int)
239    }
240
241    fn int_sum(tensor: IntTensor<Self>) -> IntTensor<Self> {
242        unary_op!(tensor, int, |tensor| B::int_sum(tensor) => Int)
243    }
244
245    fn int_sum_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
246        unary_op!(tensor, int, |tensor| B::int_sum_dim(tensor, dim) => Int)
247    }
248
249    fn int_prod(tensor: IntTensor<Self>) -> IntTensor<Self> {
250        unary_op!(tensor, int, |tensor| B::int_prod(tensor) => Int)
251    }
252
253    fn int_prod_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
254        unary_op!(tensor, int, |tensor| B::int_prod_dim(tensor, dim) => Int)
255    }
256
257    fn int_mean_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
258        unary_op!(tensor, int, |tensor| B::int_mean_dim(tensor, dim) => Int)
259    }
260
261    fn int_cumsum(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
262        unary_op!(tensor, int, |tensor| B::int_cumsum(tensor, dim) => Int)
263    }
264
265    fn int_cumprod(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
266        unary_op!(tensor, int, |tensor| B::int_cumprod(tensor, dim) => Int)
267    }
268
269    fn int_cummin(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
270        unary_op!(tensor, int, |tensor| B::int_cummin(tensor, dim) => Int)
271    }
272
273    fn int_cummax(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
274        unary_op!(tensor, int, |tensor| B::int_cummax(tensor, dim) => Int)
275    }
276
277    fn int_argmax(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
278        unary_op!(tensor, int, |tensor| B::int_argmax(tensor, dim) => Int)
279    }
280
281    fn int_argtopk(tensor: IntTensor<Self>, dim: usize, k: usize) -> IntTensor<Self> {
282        unary_op!(tensor, int, |tensor| B::int_argtopk(tensor, dim, k) => Int)
283    }
284
285    fn int_topk(tensor: IntTensor<Self>, dim: usize, k: usize) -> IntTensor<Self> {
286        unary_op!(tensor, int, |tensor| B::int_topk(tensor, dim, k) => Int)
287    }
288
289    fn int_topk_with_indices(
290        tensor: IntTensor<Self>,
291        dim: usize,
292        k: usize,
293    ) -> (IntTensor<Self>, IntTensor<Self>) {
294        multi_op!(
295            inputs[(tensor, int)],
296            outputs[(out, Int), (indices, Int)],
297            B::int_topk_with_indices(tensor, dim, k)
298        )
299    }
300
301    fn int_argmin(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
302        unary_op!(tensor, int, |tensor| B::int_argmin(tensor, dim) => Int)
303    }
304
305    fn int_abs(tensor: IntTensor<Self>) -> IntTensor<Self> {
306        unary_op!(tensor, int, |tensor| B::int_abs(tensor) => Int)
307    }
308
309    fn int_swap_dims(tensor: IntTensor<Self>, dim1: usize, dim2: usize) -> IntTensor<Self> {
310        unary_op!(tensor, int, |tensor| B::int_swap_dims(tensor, dim1, dim2) => Int)
311    }
312
313    fn int_permute(tensor: IntTensor<Self>, axes: &[usize]) -> IntTensor<Self> {
314        unary_op!(tensor, int, |tensor| B::int_permute(tensor, axes) => Int)
315    }
316
317    fn int_flip(tensor: IntTensor<Self>, axes: &[usize]) -> IntTensor<Self> {
318        unary_op!(tensor, int, |tensor| B::int_flip(tensor, axes) => Int)
319    }
320
321    fn int_random(
322        shape: Shape,
323        distribution: burn_backend::Distribution,
324        device: &DispatchDevice,
325        dtype: IntDType,
326    ) -> IntTensor<Self> {
327        creation_op!(Int, device, |device| {
328            B::int_random(shape, distribution, device, dtype)
329        })
330    }
331
332    fn int_expand(tensor: IntTensor<Self>, shape: Shape) -> IntTensor<Self> {
333        unary_op!(tensor, int, |tensor| B::int_expand(tensor, shape) => Int)
334    }
335
336    fn bitwise_and(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
337        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_and(lhs, rhs) => Int)
338    }
339
340    fn bitwise_and_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
341        unary_op!(lhs, int, |lhs| B::bitwise_and_scalar(lhs, rhs) => Int)
342    }
343
344    fn bitwise_or(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
345        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_or(lhs, rhs) => Int)
346    }
347
348    fn bitwise_or_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
349        unary_op!(lhs, int, |lhs| B::bitwise_or_scalar(lhs, rhs) => Int)
350    }
351
352    fn bitwise_xor(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
353        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_xor(lhs, rhs) => Int)
354    }
355
356    fn bitwise_xor_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
357        unary_op!(lhs, int, |lhs| B::bitwise_xor_scalar(lhs, rhs) => Int)
358    }
359
360    fn bitwise_not(tensor: IntTensor<Self>) -> IntTensor<Self> {
361        unary_op!(tensor, int, |tensor| B::bitwise_not(tensor) => Int)
362    }
363
364    fn bitwise_left_shift(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
365        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_left_shift(lhs, rhs) => Int)
366    }
367
368    fn bitwise_left_shift_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
369        unary_op!(lhs, int, |lhs| B::bitwise_left_shift_scalar(lhs, rhs) => Int)
370    }
371
372    fn bitwise_right_shift(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
373        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_right_shift(lhs, rhs) => Int)
374    }
375
376    fn bitwise_right_shift_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
377        unary_op!(lhs, int, |lhs| B::bitwise_right_shift_scalar(lhs, rhs) => Int)
378    }
379
380    fn int_cast(tensor: IntTensor<Self>, dtype: IntDType) -> IntTensor<Self> {
381        unary_op!(tensor, int, |tensor| B::int_cast(tensor, dtype) => Int)
382    }
383
384    fn int_unfold(
385        tensor: IntTensor<Self>,
386        dim: usize,
387        size: usize,
388        step: usize,
389    ) -> IntTensor<Self> {
390        unary_op!(tensor, int, |tensor| B::int_unfold(tensor, dim, size, step) => Int)
391    }
392
393    fn int_repeat_dim(tensor: IntTensor<Self>, dim: usize, times: usize) -> IntTensor<Self> {
394        unary_op!(tensor, int, |tensor| B::int_repeat_dim(tensor, dim, times) => Int)
395    }
396
397    fn int_cat(tensors: Vec<IntTensor<Self>>, dim: usize) -> IntTensor<Self> {
398        vec_op!(tensors, int, |tensors| B::int_cat(tensors, dim) => Int)
399    }
400
401    fn int_not_equal(
402        lhs: IntTensor<Self>,
403        rhs: IntTensor<Self>,
404        out_dtype: BoolDType,
405    ) -> BoolTensor<Self> {
406        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_not_equal(lhs, rhs, out_dtype) => Bool)
407    }
408
409    fn int_not_equal_elem(
410        lhs: IntTensor<Self>,
411        rhs: Scalar,
412        out_dtype: BoolDType,
413    ) -> BoolTensor<Self> {
414        unary_op!(lhs, int, |lhs| B::int_not_equal_elem(lhs, rhs, out_dtype) => Bool)
415    }
416
417    fn int_powi(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
418        binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_powi(lhs, rhs) => Int)
419    }
420
421    fn int_powi_scalar_impl(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
422        unary_op!(lhs, int, |lhs| B::int_powi_scalar_impl(lhs, rhs) => Int)
423    }
424
425    fn int_clamp_min(tensor: IntTensor<Self>, min: Scalar) -> IntTensor<Self> {
426        unary_op!(tensor, int, |tensor| B::int_clamp_min(tensor, min) => Int)
427    }
428
429    fn int_clamp_max(tensor: IntTensor<Self>, max: Scalar) -> IntTensor<Self> {
430        unary_op!(tensor, int, |tensor| B::int_clamp_max(tensor, max) => Int)
431    }
432
433    fn int_clamp(tensor: IntTensor<Self>, min: Scalar, max: Scalar) -> IntTensor<Self> {
434        unary_op!(tensor, int, |tensor| B::int_clamp(tensor, min, max) => Int)
435    }
436
437    fn int_neg(tensor: IntTensor<Self>) -> IntTensor<Self> {
438        unary_op!(tensor, int, |tensor| B::int_neg(tensor) => Int)
439    }
440
441    fn int_zeros(shape: Shape, device: &DispatchDevice, dtype: IntDType) -> IntTensor<Self> {
442        creation_op!(Int, device, |device| B::int_zeros(shape, device, dtype))
443    }
444
445    fn int_ones(shape: Shape, device: &DispatchDevice, dtype: IntDType) -> IntTensor<Self> {
446        creation_op!(Int, device, |device| B::int_ones(shape, device, dtype))
447    }
448
449    fn int_full(
450        shape: Shape,
451        fill_value: Scalar,
452        device: &DispatchDevice,
453        dtype: IntDType,
454    ) -> IntTensor<Self> {
455        creation_op!(Int, device, |device| B::int_full(
456            shape, fill_value, device, dtype
457        ))
458    }
459
460    fn int_mean(tensor: IntTensor<Self>) -> IntTensor<Self> {
461        unary_op!(tensor, int, |tensor| B::int_mean(tensor) => Int)
462    }
463
464    fn int_max(tensor: IntTensor<Self>) -> IntTensor<Self> {
465        unary_op!(tensor, int, |tensor| B::int_max(tensor) => Int)
466    }
467
468    fn int_max_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
469        unary_op!(tensor, int, |tensor| B::int_max_dim(tensor, dim) => Int)
470    }
471
472    fn int_max_dim_with_indices(
473        tensor: IntTensor<Self>,
474        dim: usize,
475    ) -> (IntTensor<Self>, IntTensor<Self>) {
476        multi_op!(
477            inputs[(tensor, int)],
478            outputs[(out, Int), (indices, Int)],
479            B::int_max_dim_with_indices(tensor, dim)
480        )
481    }
482
483    fn int_max_abs(tensor: IntTensor<Self>) -> IntTensor<Self> {
484        unary_op!(tensor, int, |tensor| B::int_max_abs(tensor) => Int)
485    }
486
487    fn int_max_abs_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
488        unary_op!(tensor, int, |tensor| B::int_max_abs_dim(tensor, dim) => Int)
489    }
490
491    fn int_min(tensor: IntTensor<Self>) -> IntTensor<Self> {
492        unary_op!(tensor, int, |tensor| B::int_min(tensor) => Int)
493    }
494
495    fn int_min_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
496        unary_op!(tensor, int, |tensor| B::int_min_dim(tensor, dim) => Int)
497    }
498
499    fn int_min_dim_with_indices(
500        tensor: IntTensor<Self>,
501        dim: usize,
502    ) -> (IntTensor<Self>, IntTensor<Self>) {
503        multi_op!(
504            inputs[(tensor, int)],
505            outputs[(out, Int), (indices, Int)],
506            B::int_min_dim_with_indices(tensor, dim)
507        )
508    }
509
510    fn int_transpose(tensor: IntTensor<Self>) -> IntTensor<Self> {
511        unary_op!(tensor, int, |tensor| B::int_transpose(tensor) => Int)
512    }
513
514    fn int_arange_step(
515        range: core::ops::Range<i64>,
516        step: usize,
517        device: &DispatchDevice,
518        dtype: IntDType,
519    ) -> IntTensor<Self> {
520        creation_op!(Int, device, |device| B::int_arange_step(
521            range, step, device, dtype
522        ))
523    }
524
525    fn int_arange(
526        range: core::ops::Range<i64>,
527        device: &DispatchDevice,
528        dtype: IntDType,
529    ) -> IntTensor<Self> {
530        creation_op!(Int, device, |device| B::int_arange(range, device, dtype))
531    }
532
533    fn int_any(tensor: IntTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
534        unary_op!(tensor, int, |tensor| B::int_any(tensor, out_dtype) => Bool)
535    }
536
537    fn int_any_dim(tensor: IntTensor<Self>, dim: usize, out_dtype: BoolDType) -> BoolTensor<Self> {
538        unary_op!(tensor, int, |tensor| B::int_any_dim(tensor, dim, out_dtype) => Bool)
539    }
540
541    fn int_all(tensor: IntTensor<Self>, out_dtype: BoolDType) -> BoolTensor<Self> {
542        unary_op!(tensor, int, |tensor| B::int_all(tensor, out_dtype) => Bool)
543    }
544
545    fn int_all_dim(tensor: IntTensor<Self>, dim: usize, out_dtype: BoolDType) -> BoolTensor<Self> {
546        unary_op!(tensor, int, |tensor| B::int_all_dim(tensor, dim, out_dtype) => Bool)
547    }
548
549    fn int_sign(tensor: IntTensor<Self>) -> IntTensor<Self> {
550        unary_op!(tensor, int, |tensor| B::int_sign(tensor) => Int)
551    }
552
553    fn int_sort(tensor: IntTensor<Self>, dim: usize, descending: bool) -> IntTensor<Self> {
554        unary_op!(tensor, int, |tensor| B::int_sort(tensor, dim, descending) => Int)
555    }
556
557    fn int_sort_with_indices(
558        tensor: IntTensor<Self>,
559        dim: usize,
560        descending: bool,
561    ) -> (IntTensor<Self>, IntTensor<Self>) {
562        multi_op!(
563            inputs[(tensor, int)],
564            outputs[(out, Int), (indices, Int)],
565            B::int_sort_with_indices(tensor, dim, descending)
566        )
567    }
568
569    fn int_argsort(tensor: IntTensor<Self>, dim: usize, descending: bool) -> IntTensor<Self> {
570        unary_op!(tensor, int, |tensor| B::int_argsort(tensor, dim, descending) => Int)
571    }
572}