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