1use burn_backend::{
2 ExecutionError, Scalar, TensorData,
3 ops::IntTensorOps,
4 tensor::{BoolTensor, FloatTensor, IntTensor},
5};
6use burn_std::{IntDType, Shape, Slice};
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>) -> FloatTensor<Self> {
52 unary_op!(tensor, int, |tensor| B::int_into_float(tensor) => 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(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
115 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_equal(lhs, rhs) => Bool)
116 }
117
118 fn int_equal_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
119 unary_op!(lhs, int, |lhs| B::int_equal_elem(lhs, rhs) => Bool)
120 }
121
122 fn int_greater(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
123 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_greater(lhs, rhs) => Bool)
124 }
125
126 fn int_greater_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
127 unary_op!(lhs, int, |lhs| B::int_greater_elem(lhs, rhs) => Bool)
128 }
129
130 fn int_greater_equal(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
131 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_greater_equal(lhs, rhs) => Bool)
132 }
133
134 fn int_greater_equal_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
135 unary_op!(lhs, int, |lhs| B::int_greater_equal_elem(lhs, rhs) => Bool)
136 }
137
138 fn int_lower(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
139 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_lower(lhs, rhs) => Bool)
140 }
141
142 fn int_lower_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
143 unary_op!(lhs, int, |lhs| B::int_lower_elem(lhs, rhs) => Bool)
144 }
145
146 fn int_lower_equal(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
147 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_lower_equal(lhs, rhs) => Bool)
148 }
149
150 fn int_lower_equal_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
151 unary_op!(lhs, int, |lhs| B::int_lower_equal_elem(lhs, rhs) => Bool)
152 }
153
154 fn int_add(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
155 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_add(lhs, rhs) => Int)
156 }
157
158 fn int_add_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
159 unary_op!(lhs, int, |lhs| B::int_add_scalar(lhs, rhs) => Int)
160 }
161
162 fn int_sub(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
163 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_sub(lhs, rhs) => Int)
164 }
165
166 fn int_sub_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
167 unary_op!(lhs, int, |lhs| B::int_sub_scalar(lhs, rhs) => Int)
168 }
169
170 fn int_mul(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
171 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_mul(lhs, rhs) => Int)
172 }
173
174 fn int_mul_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
175 unary_op!(lhs, int, |lhs| B::int_mul_scalar(lhs, rhs) => Int)
176 }
177
178 fn int_div(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
179 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_div(lhs, rhs) => Int)
180 }
181
182 fn int_div_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
183 unary_op!(lhs, int, |lhs| B::int_div_scalar(lhs, rhs) => Int)
184 }
185
186 fn int_remainder(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
187 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_remainder(lhs, rhs) => Int)
188 }
189
190 fn int_remainder_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
191 unary_op!(lhs, int, |lhs| B::int_remainder_scalar(lhs, rhs) => Int)
192 }
193
194 fn int_matmul(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
195 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_matmul(lhs, rhs) => Int)
196 }
197
198 fn int_sum(tensor: IntTensor<Self>) -> IntTensor<Self> {
199 unary_op!(tensor, int, |tensor| B::int_sum(tensor) => Int)
200 }
201
202 fn int_sum_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
203 unary_op!(tensor, int, |tensor| B::int_sum_dim(tensor, dim) => Int)
204 }
205
206 fn int_prod(tensor: IntTensor<Self>) -> IntTensor<Self> {
207 unary_op!(tensor, int, |tensor| B::int_prod(tensor) => Int)
208 }
209
210 fn int_prod_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
211 unary_op!(tensor, int, |tensor| B::int_prod_dim(tensor, dim) => Int)
212 }
213
214 fn int_mean_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
215 unary_op!(tensor, int, |tensor| B::int_mean_dim(tensor, dim) => Int)
216 }
217
218 fn int_cumsum(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
219 unary_op!(tensor, int, |tensor| B::int_cumsum(tensor, dim) => Int)
220 }
221
222 fn int_cumprod(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
223 unary_op!(tensor, int, |tensor| B::int_cumprod(tensor, dim) => Int)
224 }
225
226 fn int_cummin(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
227 unary_op!(tensor, int, |tensor| B::int_cummin(tensor, dim) => Int)
228 }
229
230 fn int_cummax(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
231 unary_op!(tensor, int, |tensor| B::int_cummax(tensor, dim) => Int)
232 }
233
234 fn int_argmax(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
235 unary_op!(tensor, int, |tensor| B::int_argmax(tensor, dim) => Int)
236 }
237
238 fn int_argmin(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
239 unary_op!(tensor, int, |tensor| B::int_argmin(tensor, dim) => Int)
240 }
241
242 fn int_abs(tensor: IntTensor<Self>) -> IntTensor<Self> {
243 unary_op!(tensor, int, |tensor| B::int_abs(tensor) => Int)
244 }
245
246 fn int_swap_dims(tensor: IntTensor<Self>, dim1: usize, dim2: usize) -> IntTensor<Self> {
247 unary_op!(tensor, int, |tensor| B::int_swap_dims(tensor, dim1, dim2) => Int)
248 }
249
250 fn int_permute(tensor: IntTensor<Self>, axes: &[usize]) -> IntTensor<Self> {
251 unary_op!(tensor, int, |tensor| B::int_permute(tensor, axes) => Int)
252 }
253
254 fn int_flip(tensor: IntTensor<Self>, axes: &[usize]) -> IntTensor<Self> {
255 unary_op!(tensor, int, |tensor| B::int_flip(tensor, axes) => Int)
256 }
257
258 fn int_random(
259 shape: Shape,
260 distribution: burn_backend::Distribution,
261 device: &DispatchDevice,
262 ) -> IntTensor<Self> {
263 creation_op!(Int, device, |device| {
264 B::int_random(shape, distribution, device)
265 })
266 }
267
268 fn int_expand(tensor: IntTensor<Self>, shape: Shape) -> IntTensor<Self> {
269 unary_op!(tensor, int, |tensor| B::int_expand(tensor, shape) => Int)
270 }
271
272 fn bitwise_and(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
273 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_and(lhs, rhs) => Int)
274 }
275
276 fn bitwise_and_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
277 unary_op!(lhs, int, |lhs| B::bitwise_and_scalar(lhs, rhs) => Int)
278 }
279
280 fn bitwise_or(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
281 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_or(lhs, rhs) => Int)
282 }
283
284 fn bitwise_or_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
285 unary_op!(lhs, int, |lhs| B::bitwise_or_scalar(lhs, rhs) => Int)
286 }
287
288 fn bitwise_xor(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
289 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_xor(lhs, rhs) => Int)
290 }
291
292 fn bitwise_xor_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
293 unary_op!(lhs, int, |lhs| B::bitwise_xor_scalar(lhs, rhs) => Int)
294 }
295
296 fn bitwise_not(tensor: IntTensor<Self>) -> IntTensor<Self> {
297 unary_op!(tensor, int, |tensor| B::bitwise_not(tensor) => Int)
298 }
299
300 fn bitwise_left_shift(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
301 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_left_shift(lhs, rhs) => Int)
302 }
303
304 fn bitwise_left_shift_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
305 unary_op!(lhs, int, |lhs| B::bitwise_left_shift_scalar(lhs, rhs) => Int)
306 }
307
308 fn bitwise_right_shift(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
309 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::bitwise_right_shift(lhs, rhs) => Int)
310 }
311
312 fn bitwise_right_shift_scalar(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
313 unary_op!(lhs, int, |lhs| B::bitwise_right_shift_scalar(lhs, rhs) => Int)
314 }
315
316 fn int_cast(tensor: IntTensor<Self>, dtype: IntDType) -> IntTensor<Self> {
317 unary_op!(tensor, int, |tensor| B::int_cast(tensor, dtype) => Int)
318 }
319
320 fn int_unfold(
321 tensor: IntTensor<Self>,
322 dim: usize,
323 size: usize,
324 step: usize,
325 ) -> IntTensor<Self> {
326 unary_op!(tensor, int, |tensor| B::int_unfold(tensor, dim, size, step) => Int)
327 }
328
329 fn int_repeat_dim(tensor: IntTensor<Self>, dim: usize, times: usize) -> IntTensor<Self> {
330 unary_op!(tensor, int, |tensor| B::int_repeat_dim(tensor, dim, times) => Int)
331 }
332
333 fn int_cat(tensors: Vec<IntTensor<Self>>, dim: usize) -> IntTensor<Self> {
334 vec_op!(tensors, int, |tensors| B::int_cat(tensors, dim) => Int)
335 }
336
337 fn int_not_equal(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> BoolTensor<Self> {
338 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_not_equal(lhs, rhs) => Bool)
339 }
340
341 fn int_not_equal_elem(lhs: IntTensor<Self>, rhs: Scalar) -> BoolTensor<Self> {
342 unary_op!(lhs, int, |lhs| B::int_not_equal_elem(lhs, rhs) => Bool)
343 }
344
345 fn int_powi(lhs: IntTensor<Self>, rhs: IntTensor<Self>) -> IntTensor<Self> {
346 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_powi(lhs, rhs) => Int)
347 }
348
349 fn int_powf(lhs: IntTensor<Self>, rhs: FloatTensor<Self>) -> IntTensor<Self> {
350 binary_op!((lhs, int), (rhs, int), |lhs, rhs| B::int_powf(lhs, rhs) => Int)
351 }
352
353 fn int_powi_scalar_impl(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
354 unary_op!(lhs, int, |lhs| B::int_powi_scalar_impl(lhs, rhs) => Int)
355 }
356
357 fn int_powf_scalar_impl(lhs: IntTensor<Self>, rhs: Scalar) -> IntTensor<Self> {
358 unary_op!(lhs, int, |lhs| B::int_powf_scalar_impl(lhs, rhs) => Int)
359 }
360
361 fn int_clamp_min(tensor: IntTensor<Self>, min: Scalar) -> IntTensor<Self> {
362 unary_op!(tensor, int, |tensor| B::int_clamp_min(tensor, min) => Int)
363 }
364
365 fn int_clamp_max(tensor: IntTensor<Self>, max: Scalar) -> IntTensor<Self> {
366 unary_op!(tensor, int, |tensor| B::int_clamp_max(tensor, max) => Int)
367 }
368
369 fn int_clamp(tensor: IntTensor<Self>, min: Scalar, max: Scalar) -> IntTensor<Self> {
370 unary_op!(tensor, int, |tensor| B::int_clamp(tensor, min, max) => Int)
371 }
372
373 fn int_neg(tensor: IntTensor<Self>) -> IntTensor<Self> {
374 unary_op!(tensor, int, |tensor| B::int_neg(tensor) => Int)
375 }
376
377 fn int_zeros(shape: Shape, device: &DispatchDevice, dtype: IntDType) -> IntTensor<Self> {
378 creation_op!(Int, device, |device| B::int_zeros(shape, device, dtype))
379 }
380
381 fn int_ones(shape: Shape, device: &DispatchDevice, dtype: IntDType) -> IntTensor<Self> {
382 creation_op!(Int, device, |device| B::int_ones(shape, device, dtype))
383 }
384
385 fn int_full(
386 shape: Shape,
387 fill_value: Scalar,
388 device: &DispatchDevice,
389 dtype: IntDType,
390 ) -> IntTensor<Self> {
391 creation_op!(Int, device, |device| B::int_full(
392 shape, fill_value, device, dtype
393 ))
394 }
395
396 fn int_mean(tensor: IntTensor<Self>) -> IntTensor<Self> {
397 unary_op!(tensor, int, |tensor| B::int_mean(tensor) => Int)
398 }
399
400 fn int_max(tensor: IntTensor<Self>) -> IntTensor<Self> {
401 unary_op!(tensor, int, |tensor| B::int_max(tensor) => Int)
402 }
403
404 fn int_max_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
405 unary_op!(tensor, int, |tensor| B::int_max_dim(tensor, dim) => Int)
406 }
407
408 fn int_max_dim_with_indices(
409 tensor: IntTensor<Self>,
410 dim: usize,
411 ) -> (IntTensor<Self>, IntTensor<Self>) {
412 multi_op!(
413 inputs[(tensor, int)],
414 outputs[(out, Int), (indices, Int)],
415 B::int_max_dim_with_indices(tensor, dim)
416 )
417 }
418
419 fn int_max_abs(tensor: IntTensor<Self>) -> IntTensor<Self> {
420 unary_op!(tensor, int, |tensor| B::int_max_abs(tensor) => Int)
421 }
422
423 fn int_max_abs_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
424 unary_op!(tensor, int, |tensor| B::int_max_abs_dim(tensor, dim) => Int)
425 }
426
427 fn int_min(tensor: IntTensor<Self>) -> IntTensor<Self> {
428 unary_op!(tensor, int, |tensor| B::int_min(tensor) => Int)
429 }
430
431 fn int_min_dim(tensor: IntTensor<Self>, dim: usize) -> IntTensor<Self> {
432 unary_op!(tensor, int, |tensor| B::int_min_dim(tensor, dim) => Int)
433 }
434
435 fn int_min_dim_with_indices(
436 tensor: IntTensor<Self>,
437 dim: usize,
438 ) -> (IntTensor<Self>, IntTensor<Self>) {
439 multi_op!(
440 inputs[(tensor, int)],
441 outputs[(out, Int), (indices, Int)],
442 B::int_min_dim_with_indices(tensor, dim)
443 )
444 }
445
446 fn int_transpose(tensor: IntTensor<Self>) -> IntTensor<Self> {
447 unary_op!(tensor, int, |tensor| B::int_transpose(tensor) => Int)
448 }
449
450 fn int_arange_step(
451 range: std::ops::Range<i64>,
452 step: usize,
453 device: &DispatchDevice,
454 ) -> IntTensor<Self> {
455 creation_op!(Int, device, |device| B::int_arange_step(
456 range, step, device
457 ))
458 }
459
460 fn int_arange(range: std::ops::Range<i64>, device: &DispatchDevice) -> IntTensor<Self> {
461 creation_op!(Int, device, |device| B::int_arange(range, device))
462 }
463
464 fn int_any(tensor: IntTensor<Self>) -> BoolTensor<Self> {
465 unary_op!(tensor, int, |tensor| B::int_any(tensor) => Bool)
466 }
467
468 fn int_any_dim(tensor: IntTensor<Self>, dim: usize) -> BoolTensor<Self> {
469 unary_op!(tensor, int, |tensor| B::int_any_dim(tensor, dim) => Bool)
470 }
471
472 fn int_all(tensor: IntTensor<Self>) -> BoolTensor<Self> {
473 unary_op!(tensor, int, |tensor| B::int_all(tensor) => Bool)
474 }
475
476 fn int_all_dim(tensor: IntTensor<Self>, dim: usize) -> BoolTensor<Self> {
477 unary_op!(tensor, int, |tensor| B::int_all_dim(tensor, dim) => Bool)
478 }
479
480 fn int_sign(tensor: IntTensor<Self>) -> IntTensor<Self> {
481 unary_op!(tensor, int, |tensor| B::int_sign(tensor) => Int)
482 }
483
484 fn int_sort(tensor: IntTensor<Self>, dim: usize, descending: bool) -> IntTensor<Self> {
485 unary_op!(tensor, int, |tensor| B::int_sort(tensor, dim, descending) => Int)
486 }
487
488 fn int_sort_with_indices(
489 tensor: IntTensor<Self>,
490 dim: usize,
491 descending: bool,
492 ) -> (IntTensor<Self>, IntTensor<Self>) {
493 multi_op!(
494 inputs[(tensor, int)],
495 outputs[(out, Int), (indices, Int)],
496 B::int_sort_with_indices(tensor, dim, descending)
497 )
498 }
499
500 fn int_argsort(tensor: IntTensor<Self>, dim: usize, descending: bool) -> IntTensor<Self> {
501 unary_op!(tensor, int, |tensor| B::int_argsort(tensor, dim, descending) => Int)
502 }
503}