1use burn_backend::{
2 IntDType,
3 ops::{
4 BatchNormTrain, BatchNormTrainBackward, DeformConv2dBackward, MaxPool1dBackward,
5 MaxPool1dWithIndices, MaxPool2dBackward, MaxPool2dWithIndices, ModuleOps,
6 },
7 tensor::{FloatTensor, IntTensor},
8};
9use burn_backend_extension::backend_dispatch;
10
11use crate::Dispatch;
12
13#[backend_dispatch]
14impl ModuleOps<Self> for Dispatch {
15 fn batch_norm(
16 x: FloatTensor<Self>,
17 gamma: FloatTensor<Self>,
18 beta: FloatTensor<Self>,
19 mean: FloatTensor<Self>,
20 variance: FloatTensor<Self>,
21 epsilon: f64,
22 ) -> FloatTensor<Self> {
23 B::batch_norm(x, gamma, beta, mean, variance, epsilon)
24 }
25
26 #[backend_dispatch(skip)]
27 fn batch_norm_train(
28 x: FloatTensor<Self>,
29 gamma: FloatTensor<Self>,
30 beta: FloatTensor<Self>,
31 epsilon: f64,
32 ) -> BatchNormTrain<Self> {
33 let (output, mean, variance) = Self::batch_norm_train_dispatch(x, gamma, beta, epsilon);
34 BatchNormTrain::new(output, mean, variance)
35 }
36
37 #[backend_dispatch(skip)]
38 fn batch_norm_train_backward(
39 x: FloatTensor<Self>,
40 gamma: FloatTensor<Self>,
41 mean: FloatTensor<Self>,
42 variance: FloatTensor<Self>,
43 epsilon: f64,
44 output_grad: FloatTensor<Self>,
45 ) -> BatchNormTrainBackward<Self> {
46 let (x_grad, gamma_grad, beta_grad) = Self::batch_norm_train_backward_dispatch(
47 x,
48 gamma,
49 mean,
50 variance,
51 epsilon,
52 output_grad,
53 );
54 BatchNormTrainBackward::new(x_grad, gamma_grad, beta_grad)
55 }
56
57 fn conv2d(
58 x: FloatTensor<Self>,
59 weight: FloatTensor<Self>,
60 bias: Option<FloatTensor<Self>>,
61 options: burn_backend::ops::ConvOptions<2>,
62 ) -> FloatTensor<Self> {
63 B::conv2d(x, weight, bias, options)
64 }
65
66 fn deform_conv2d(
67 x: FloatTensor<Self>,
68 offset: FloatTensor<Self>,
69 weight: FloatTensor<Self>,
70 mask: Option<FloatTensor<Self>>,
71 bias: Option<FloatTensor<Self>>,
72 options: burn_backend::ops::DeformConvOptions<2>,
73 ) -> FloatTensor<Self> {
74 B::deform_conv2d(x, offset, weight, mask, bias, options)
75 }
76
77 #[backend_dispatch(skip)]
78 fn deform_conv2d_backward(
79 x: FloatTensor<Self>,
80 offset: FloatTensor<Self>,
81 weight: FloatTensor<Self>,
82 mask: Option<FloatTensor<Self>>,
83 bias: Option<FloatTensor<Self>>,
84 output_grad: FloatTensor<Self>,
85 options: burn_backend::ops::DeformConvOptions<2>,
86 ) -> DeformConv2dBackward<Self> {
87 let (x_grad, offset_grad, weight_grad, mask_grad, bias_grad) =
88 Self::deform_conv2d_backward_dispatch(
89 x,
90 offset,
91 weight,
92 mask,
93 bias,
94 output_grad,
95 options,
96 );
97 DeformConv2dBackward::new(x_grad, offset_grad, weight_grad, mask_grad, bias_grad)
98 }
99
100 fn conv3d(
101 x: FloatTensor<Self>,
102 weight: FloatTensor<Self>,
103 bias: Option<FloatTensor<Self>>,
104 options: burn_backend::ops::ConvOptions<3>,
105 ) -> FloatTensor<Self> {
106 B::conv3d(x, weight, bias, options)
107 }
108
109 fn conv_transpose2d(
110 x: FloatTensor<Self>,
111 weight: FloatTensor<Self>,
112 bias: Option<FloatTensor<Self>>,
113 options: burn_backend::ops::ConvTransposeOptions<2>,
114 ) -> FloatTensor<Self> {
115 B::conv_transpose2d(x, weight, bias, options)
116 }
117
118 fn conv_transpose3d(
119 x: FloatTensor<Self>,
120 weight: FloatTensor<Self>,
121 bias: Option<FloatTensor<Self>>,
122 options: burn_backend::ops::ConvTransposeOptions<3>,
123 ) -> FloatTensor<Self> {
124 B::conv_transpose3d(x, weight, bias, options)
125 }
126
127 fn avg_pool2d(
128 x: FloatTensor<Self>,
129 kernel_size: [usize; 2],
130 stride: [usize; 2],
131 padding: [usize; 2],
132 count_include_pad: bool,
133 ceil_mode: bool,
134 ) -> FloatTensor<Self> {
135 B::avg_pool2d(
136 x,
137 kernel_size,
138 stride,
139 padding,
140 count_include_pad,
141 ceil_mode,
142 )
143 }
144
145 fn avg_pool2d_backward(
146 x: FloatTensor<Self>,
147 grad: FloatTensor<Self>,
148 kernel_size: [usize; 2],
149 stride: [usize; 2],
150 padding: [usize; 2],
151 count_include_pad: bool,
152 ceil_mode: bool,
153 ) -> FloatTensor<Self> {
154 B::avg_pool2d_backward(
155 x,
156 grad,
157 kernel_size,
158 stride,
159 padding,
160 count_include_pad,
161 ceil_mode,
162 )
163 }
164
165 fn adaptive_avg_pool2d(x: FloatTensor<Self>, output_size: [usize; 2]) -> FloatTensor<Self> {
166 B::adaptive_avg_pool2d(x, output_size)
167 }
168
169 fn adaptive_avg_pool2d_backward(
170 x: FloatTensor<Self>,
171 grad: FloatTensor<Self>,
172 ) -> FloatTensor<Self> {
173 B::adaptive_avg_pool2d_backward(x, grad)
174 }
175
176 fn adaptive_avg_pool3d(x: FloatTensor<Self>, output_size: [usize; 3]) -> FloatTensor<Self> {
177 B::adaptive_avg_pool3d(x, output_size)
178 }
179
180 fn adaptive_avg_pool3d_backward(
181 x: FloatTensor<Self>,
182 grad: FloatTensor<Self>,
183 ) -> FloatTensor<Self> {
184 B::adaptive_avg_pool3d_backward(x, grad)
185 }
186
187 fn max_pool2d(
188 x: FloatTensor<Self>,
189 kernel_size: [usize; 2],
190 stride: [usize; 2],
191 padding: [usize; 2],
192 dilation: [usize; 2],
193 ceil_mode: bool,
194 ) -> FloatTensor<Self> {
195 B::max_pool2d(x, kernel_size, stride, padding, dilation, ceil_mode)
196 }
197
198 #[backend_dispatch(skip)]
199 fn max_pool2d_with_indices(
200 x: FloatTensor<Self>,
201 kernel_size: [usize; 2],
202 stride: [usize; 2],
203 padding: [usize; 2],
204 dilation: [usize; 2],
205 ceil_mode: bool,
206 indices_dtype: IntDType,
207 ) -> MaxPool2dWithIndices<Self> {
208 let (output, indices) = Self::max_pool2d_with_indices_dispatch(
209 x,
210 kernel_size,
211 stride,
212 padding,
213 dilation,
214 ceil_mode,
215 indices_dtype,
216 );
217 MaxPool2dWithIndices::new(output, indices)
218 }
219
220 #[backend_dispatch(skip)]
221 fn max_pool2d_with_indices_backward(
222 x: FloatTensor<Self>,
223 kernel_size: [usize; 2],
224 stride: [usize; 2],
225 padding: [usize; 2],
226 dilation: [usize; 2],
227 ceil_mode: bool,
228 output_grad: FloatTensor<Self>,
229 indices: IntTensor<Self>,
230 ) -> MaxPool2dBackward<Self> {
231 let x_grad = Self::max_pool2d_with_indices_backward_dispatch(
232 x,
233 kernel_size,
234 stride,
235 padding,
236 dilation,
237 ceil_mode,
238 output_grad,
239 indices,
240 );
241 MaxPool2dBackward::new(x_grad)
242 }
243
244 fn interpolate(
245 x: FloatTensor<Self>,
246 output_size: [usize; 2],
247 options: burn_backend::ops::InterpolateOptions,
248 ) -> FloatTensor<Self> {
249 B::interpolate(x, output_size, options)
250 }
251
252 fn interpolate_backward(
253 x: FloatTensor<Self>,
254 grad: FloatTensor<Self>,
255 output_size: [usize; 2],
256 options: burn_backend::ops::InterpolateOptions,
257 ) -> FloatTensor<Self> {
258 B::interpolate_backward(x, grad, output_size, options)
259 }
260
261 fn embedding(weights: FloatTensor<Self>, indices: IntTensor<Self>) -> FloatTensor<Self> {
262 B::embedding(weights, indices)
263 }
264
265 fn embedding_backward(
266 weights: FloatTensor<Self>,
267 output_grad: FloatTensor<Self>,
268 indices: IntTensor<Self>,
269 ) -> FloatTensor<Self> {
270 B::embedding_backward(weights, output_grad, indices)
271 }
272
273 fn conv1d(
274 x: FloatTensor<Self>,
275 weight: FloatTensor<Self>,
276 bias: Option<FloatTensor<Self>>,
277 options: burn_backend::ops::ConvOptions<1>,
278 ) -> FloatTensor<Self> {
279 B::conv1d(x, weight, bias, options)
280 }
281
282 fn conv1d_x_backward(
283 x: FloatTensor<Self>,
284 weight: FloatTensor<Self>,
285 output_grad: FloatTensor<Self>,
286 options: burn_backend::ops::ConvOptions<1>,
287 ) -> FloatTensor<Self> {
288 B::conv1d_x_backward(x, weight, output_grad, options)
289 }
290
291 fn conv1d_weight_backward(
292 x: FloatTensor<Self>,
293 weight: FloatTensor<Self>,
294 output_grad: FloatTensor<Self>,
295 options: burn_backend::ops::ConvOptions<1>,
296 ) -> FloatTensor<Self> {
297 B::conv1d_weight_backward(x, weight, output_grad, options)
298 }
299
300 fn conv1d_bias_backward(
301 x: FloatTensor<Self>,
302 bias: FloatTensor<Self>,
303 output_grad: FloatTensor<Self>,
304 ) -> FloatTensor<Self> {
305 B::conv1d_bias_backward(x, bias, output_grad)
306 }
307
308 fn conv2d_x_backward(
309 x: FloatTensor<Self>,
310 weight: FloatTensor<Self>,
311 output_grad: FloatTensor<Self>,
312 options: burn_backend::ops::ConvOptions<2>,
313 ) -> FloatTensor<Self> {
314 B::conv2d_x_backward(x, weight, output_grad, options)
315 }
316
317 fn conv2d_weight_backward(
318 x: FloatTensor<Self>,
319 weight: FloatTensor<Self>,
320 output_grad: FloatTensor<Self>,
321 options: burn_backend::ops::ConvOptions<2>,
322 ) -> FloatTensor<Self> {
323 B::conv2d_weight_backward(x, weight, output_grad, options)
324 }
325
326 fn conv2d_bias_backward(
327 x: FloatTensor<Self>,
328 bias: FloatTensor<Self>,
329 output_grad: FloatTensor<Self>,
330 ) -> FloatTensor<Self> {
331 B::conv2d_bias_backward(x, bias, output_grad)
332 }
333
334 fn conv3d_x_backward(
335 x: FloatTensor<Self>,
336 weight: FloatTensor<Self>,
337 output_grad: FloatTensor<Self>,
338 options: burn_backend::ops::ConvOptions<3>,
339 ) -> FloatTensor<Self> {
340 B::conv3d_x_backward(x, weight, output_grad, options)
341 }
342
343 fn conv3d_weight_backward(
344 x: FloatTensor<Self>,
345 weight: FloatTensor<Self>,
346 output_grad: FloatTensor<Self>,
347 options: burn_backend::ops::ConvOptions<3>,
348 ) -> FloatTensor<Self> {
349 B::conv3d_weight_backward(x, weight, output_grad, options)
350 }
351
352 fn conv3d_bias_backward(
353 x: FloatTensor<Self>,
354 bias: FloatTensor<Self>,
355 output_grad: FloatTensor<Self>,
356 ) -> FloatTensor<Self> {
357 B::conv3d_bias_backward(x, bias, output_grad)
358 }
359
360 fn conv_transpose1d(
361 x: FloatTensor<Self>,
362 weight: FloatTensor<Self>,
363 bias: Option<FloatTensor<Self>>,
364 options: burn_backend::ops::ConvTransposeOptions<1>,
365 ) -> FloatTensor<Self> {
366 B::conv_transpose1d(x, weight, bias, options)
367 }
368
369 fn conv_transpose1d_x_backward(
370 weight: FloatTensor<Self>,
371 output_grad: FloatTensor<Self>,
372 options: burn_backend::ops::ConvTransposeOptions<1>,
373 ) -> FloatTensor<Self> {
374 B::conv_transpose1d_x_backward(weight, output_grad, options)
375 }
376
377 fn conv_transpose1d_weight_backward(
378 x: FloatTensor<Self>,
379 weight: FloatTensor<Self>,
380 output_grad: FloatTensor<Self>,
381 options: burn_backend::ops::ConvTransposeOptions<1>,
382 ) -> FloatTensor<Self> {
383 B::conv_transpose1d_weight_backward(x, weight, output_grad, options)
384 }
385
386 fn conv_transpose1d_bias_backward(
387 x: FloatTensor<Self>,
388 bias: FloatTensor<Self>,
389 output_grad: FloatTensor<Self>,
390 ) -> FloatTensor<Self> {
391 B::conv_transpose1d_bias_backward(x, bias, output_grad)
392 }
393
394 fn conv_transpose2d_x_backward(
395 weight: FloatTensor<Self>,
396 output_grad: FloatTensor<Self>,
397 options: burn_backend::ops::ConvTransposeOptions<2>,
398 ) -> FloatTensor<Self> {
399 B::conv_transpose2d_x_backward(weight, output_grad, options)
400 }
401
402 fn conv_transpose2d_weight_backward(
403 x: FloatTensor<Self>,
404 weight: FloatTensor<Self>,
405 output_grad: FloatTensor<Self>,
406 options: burn_backend::ops::ConvTransposeOptions<2>,
407 ) -> FloatTensor<Self> {
408 B::conv_transpose2d_weight_backward(x, weight, output_grad, options)
409 }
410
411 fn conv_transpose2d_bias_backward(
412 x: FloatTensor<Self>,
413 bias: FloatTensor<Self>,
414 output_grad: FloatTensor<Self>,
415 ) -> FloatTensor<Self> {
416 B::conv_transpose2d_bias_backward(x, bias, output_grad)
417 }
418
419 fn conv_transpose3d_x_backward(
420 weight: FloatTensor<Self>,
421 output_grad: FloatTensor<Self>,
422 options: burn_backend::ops::ConvTransposeOptions<3>,
423 ) -> FloatTensor<Self> {
424 B::conv_transpose3d_x_backward(weight, output_grad, options)
425 }
426
427 fn conv_transpose3d_weight_backward(
428 x: FloatTensor<Self>,
429 weight: FloatTensor<Self>,
430 output_grad: FloatTensor<Self>,
431 options: burn_backend::ops::ConvTransposeOptions<3>,
432 ) -> FloatTensor<Self> {
433 B::conv_transpose3d_weight_backward(x, weight, output_grad, options)
434 }
435
436 fn conv_transpose3d_bias_backward(
437 x: FloatTensor<Self>,
438 bias: FloatTensor<Self>,
439 output_grad: FloatTensor<Self>,
440 ) -> FloatTensor<Self> {
441 B::conv_transpose3d_bias_backward(x, bias, output_grad)
442 }
443
444 fn unfold4d(
445 x: FloatTensor<Self>,
446 kernel_size: [usize; 2],
447 options: burn_backend::ops::UnfoldOptions,
448 ) -> FloatTensor<Self> {
449 B::unfold4d(x, kernel_size, options)
450 }
451
452 fn avg_pool1d(
453 x: FloatTensor<Self>,
454 kernel_size: usize,
455 stride: usize,
456 padding: usize,
457 count_include_pad: bool,
458 ceil_mode: bool,
459 ) -> FloatTensor<Self> {
460 B::avg_pool1d(
461 x,
462 kernel_size,
463 stride,
464 padding,
465 count_include_pad,
466 ceil_mode,
467 )
468 }
469
470 fn avg_pool1d_backward(
471 x: FloatTensor<Self>,
472 grad: FloatTensor<Self>,
473 kernel_size: usize,
474 stride: usize,
475 padding: usize,
476 count_include_pad: bool,
477 ceil_mode: bool,
478 ) -> FloatTensor<Self> {
479 B::avg_pool1d_backward(
480 x,
481 grad,
482 kernel_size,
483 stride,
484 padding,
485 count_include_pad,
486 ceil_mode,
487 )
488 }
489
490 fn adaptive_avg_pool1d(x: FloatTensor<Self>, output_size: usize) -> FloatTensor<Self> {
491 B::adaptive_avg_pool1d(x, output_size)
492 }
493
494 fn adaptive_avg_pool1d_backward(
495 x: FloatTensor<Self>,
496 grad: FloatTensor<Self>,
497 ) -> FloatTensor<Self> {
498 B::adaptive_avg_pool1d_backward(x, grad)
499 }
500
501 fn max_pool1d(
502 x: FloatTensor<Self>,
503 kernel_size: usize,
504 stride: usize,
505 padding: usize,
506 dilation: usize,
507 ceil_mode: bool,
508 ) -> FloatTensor<Self> {
509 B::max_pool1d(x, kernel_size, stride, padding, dilation, ceil_mode)
510 }
511
512 #[backend_dispatch(skip)]
513 fn max_pool1d_with_indices(
514 x: FloatTensor<Self>,
515 kernel_size: usize,
516 stride: usize,
517 padding: usize,
518 dilation: usize,
519 ceil_mode: bool,
520 indices_dtype: IntDType,
521 ) -> MaxPool1dWithIndices<Self> {
522 let (output, indices) = Self::max_pool1d_with_indices_dispatch(
523 x,
524 kernel_size,
525 stride,
526 padding,
527 dilation,
528 ceil_mode,
529 indices_dtype,
530 );
531 MaxPool1dWithIndices::new(output, indices)
532 }
533
534 #[backend_dispatch(skip)]
535 fn max_pool1d_with_indices_backward(
536 x: FloatTensor<Self>,
537 kernel_size: usize,
538 stride: usize,
539 padding: usize,
540 dilation: usize,
541 ceil_mode: bool,
542 output_grad: FloatTensor<Self>,
543 indices: IntTensor<Self>,
544 ) -> MaxPool1dBackward<Self> {
545 let x_grad = Self::max_pool1d_with_indices_backward_dispatch(
546 x,
547 kernel_size,
548 stride,
549 padding,
550 dilation,
551 ceil_mode,
552 output_grad,
553 indices,
554 );
555 MaxPool1dBackward::new(x_grad)
556 }
557
558 fn attention(
559 query: FloatTensor<Self>,
560 key: FloatTensor<Self>,
561 value: FloatTensor<Self>,
562 mask: Option<burn_backend::tensor::BoolTensor<Self>>,
563 attn_bias: Option<FloatTensor<Self>>,
564 options: burn_backend::ops::AttentionModuleOptions,
565 ) -> FloatTensor<Self> {
566 B::attention(query, key, value, mask, attn_bias, options)
567 }
568
569 fn layer_norm(
570 tensor: FloatTensor<Self>,
571 gamma: FloatTensor<Self>,
572 beta: Option<FloatTensor<Self>>,
573 epsilon: f64,
574 ) -> FloatTensor<Self> {
575 B::layer_norm(tensor, gamma, beta, epsilon)
576 }
577
578 #[backend_dispatch(skip)]
579 fn has_ctc_loss_backward() -> bool {
580 false
585 }
586
587 fn ctc_loss(
588 log_probs: FloatTensor<Self>,
589 targets: IntTensor<Self>,
590 input_lengths: IntTensor<Self>,
591 target_lengths: IntTensor<Self>,
592 blank: usize,
593 ) -> FloatTensor<Self> {
594 B::ctc_loss(log_probs, targets, input_lengths, target_lengths, blank)
595 }
596
597 fn ctc_loss_backward(
598 log_probs: FloatTensor<Self>,
599 targets: IntTensor<Self>,
600 input_lengths: IntTensor<Self>,
601 target_lengths: IntTensor<Self>,
602 grad_loss: FloatTensor<Self>,
603 blank: usize,
604 ) -> FloatTensor<Self> {
605 B::ctc_loss_backward(
606 log_probs,
607 targets,
608 input_lengths,
609 target_lengths,
610 grad_loss,
611 blank,
612 )
613 }
614
615 }
624
625#[backend_dispatch]
626impl Dispatch {
627 fn deform_conv2d_backward_dispatch(
628 x: FloatTensor<Self>,
629 offset: FloatTensor<Self>,
630 weight: FloatTensor<Self>,
631 mask: Option<FloatTensor<Self>>,
632 bias: Option<FloatTensor<Self>>,
633 output_grad: FloatTensor<Self>,
634 options: burn_backend::ops::DeformConvOptions<2>,
635 ) -> (
636 FloatTensor<Self>,
637 FloatTensor<Self>,
638 FloatTensor<Self>,
639 Option<FloatTensor<Self>>,
640 Option<FloatTensor<Self>>,
641 ) {
642 let output = B::deform_conv2d_backward(x, offset, weight, mask, bias, output_grad, options);
643 (
644 output.x_grad,
645 output.offset_grad,
646 output.weight_grad,
647 output.mask_grad,
648 output.bias_grad,
649 )
650 }
651
652 fn batch_norm_train_dispatch(
653 x: FloatTensor<Self>,
654 gamma: FloatTensor<Self>,
655 beta: FloatTensor<Self>,
656 epsilon: f64,
657 ) -> (FloatTensor<Self>, FloatTensor<Self>, FloatTensor<Self>) {
658 let result = B::batch_norm_train(x, gamma, beta, epsilon);
659 (result.output, result.mean, result.variance)
660 }
661
662 fn batch_norm_train_backward_dispatch(
663 x: FloatTensor<Self>,
664 gamma: FloatTensor<Self>,
665 mean: FloatTensor<Self>,
666 variance: FloatTensor<Self>,
667 epsilon: f64,
668 output_grad: FloatTensor<Self>,
669 ) -> (FloatTensor<Self>, FloatTensor<Self>, FloatTensor<Self>) {
670 let result = B::batch_norm_train_backward(x, gamma, mean, variance, epsilon, output_grad);
671 (result.x_grad, result.gamma_grad, result.beta_grad)
672 }
673
674 fn max_pool2d_with_indices_dispatch(
675 x: FloatTensor<Self>,
676 kernel_size: [usize; 2],
677 stride: [usize; 2],
678 padding: [usize; 2],
679 dilation: [usize; 2],
680 ceil_mode: bool,
681 indices_dtype: IntDType,
682 ) -> (FloatTensor<Self>, IntTensor<Self>) {
683 let output = B::max_pool2d_with_indices(
684 x,
685 kernel_size,
686 stride,
687 padding,
688 dilation,
689 ceil_mode,
690 indices_dtype,
691 );
692 (output.output, output.indices)
693 }
694
695 fn max_pool2d_with_indices_backward_dispatch(
696 x: FloatTensor<Self>,
697 kernel_size: [usize; 2],
698 stride: [usize; 2],
699 padding: [usize; 2],
700 dilation: [usize; 2],
701 ceil_mode: bool,
702 output_grad: FloatTensor<Self>,
703 indices: IntTensor<Self>,
704 ) -> FloatTensor<Self> {
705 B::max_pool2d_with_indices_backward(
706 x,
707 kernel_size,
708 stride,
709 padding,
710 dilation,
711 ceil_mode,
712 output_grad,
713 indices,
714 )
715 .x_grad
716 }
717
718 fn max_pool1d_with_indices_dispatch(
719 x: FloatTensor<Self>,
720 kernel_size: usize,
721 stride: usize,
722 padding: usize,
723 dilation: usize,
724 ceil_mode: bool,
725 indices_dtype: IntDType,
726 ) -> (FloatTensor<Self>, IntTensor<Self>) {
727 let output = B::max_pool1d_with_indices(
728 x,
729 kernel_size,
730 stride,
731 padding,
732 dilation,
733 ceil_mode,
734 indices_dtype,
735 );
736 (output.output, output.indices)
737 }
738
739 fn max_pool1d_with_indices_backward_dispatch(
740 x: FloatTensor<Self>,
741 kernel_size: usize,
742 stride: usize,
743 padding: usize,
744 dilation: usize,
745 ceil_mode: bool,
746 output_grad: FloatTensor<Self>,
747 indices: IntTensor<Self>,
748 ) -> FloatTensor<Self> {
749 B::max_pool1d_with_indices_backward(
750 x,
751 kernel_size,
752 stride,
753 padding,
754 dilation,
755 ceil_mode,
756 output_grad,
757 indices,
758 )
759 .x_grad
760 }
761}