Skip to content

Commit 5dfcfca

Browse files
committed
Fix int32 overflow in max_pool3d backward kernel
Template `MaxPool3dBackwardKernelFunctor` and `max_pool3d_with_indices_backward_template` with an `index_t` type parameter, and dispatch between `int32_t` and `int64_t` at runtime using `canUse32BitIndexMath`. This avoids overflow when computing offsets for large tensors (e.g. shape `[70, 32, 100, 100, 100]`) while preserving int32 performance for smaller tensors. Fixes test case: `test_pool3d_large_size_int64`
1 parent 42e64e2 commit 5dfcfca

1 file changed

Lines changed: 76 additions & 63 deletions

File tree

src/ATen/native/xpu/sycl/DilatedMaxPool3d.cpp

Lines changed: 76 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ DISABLE_RETURN_TYPE_WARNING_BEGIN
2020
#include <ATen/ATen.h>
2121
#include <ATen/AccumulateType.h>
2222
#include <ATen/ceil_div.h>
23+
#include <ATen/native/CanUse32BitIndexMath.h>
2324
#include <ATen/native/Pool.h>
2425
#include <ATen/native/utils/ParamUtils.h>
2526

@@ -316,24 +317,24 @@ void max_pool3d_with_indices_out_template(
316317
sycl_kernel_submit(global_range, work_group_size, queue, kfn);
317318
}
318319

319-
template <typename scalar_t, bool channels_last>
320+
template <typename scalar_t, bool channels_last, typename index_t>
320321
struct MaxPool3dBackwardKernelFunctor {
321322
void operator()(sycl::nd_item<1> item) const {
322-
auto outputIndex = item.get_global_id(0);
323+
index_t outputIndex = item.get_global_id(0);
323324
if (outputIndex < gradOutputSize_) {
324-
int batch = outputIndex / out_nbatch_stride_;
325+
index_t batch = outputIndex / out_nbatch_stride_;
325326
if constexpr (channels_last) {
326-
int channel = outputIndex % features_;
327+
index_t channel = outputIndex % features_;
327328
int64_t index = indicesData_[outputIndex];
328-
int64_t gradIn_offset =
329+
index_t gradIn_offset =
329330
batch * in_nbatch_stride_ + channel + index * features_;
330331
atomicAdd(
331332
(sycl_global_ptr<scalar_t>)&gradInputData_[gradIn_offset],
332333
gradOutputData_[outputIndex]);
333334
} else {
334-
int channel = outputIndex / out_cf_channel_stride_ % features_;
335+
index_t channel = outputIndex / out_cf_channel_stride_ % features_;
335336
int64_t index = indicesData_[outputIndex];
336-
int64_t gradIn_offset =
337+
index_t gradIn_offset =
337338
batch * in_nbatch_stride_ + channel * in_cf_channel_stride_ + index;
338339
atomicAdd(
339340
(sycl_global_ptr<scalar_t>)&gradInputData_[gradIn_offset],
@@ -345,12 +346,12 @@ struct MaxPool3dBackwardKernelFunctor {
345346
scalar_t* gradInputData,
346347
const scalar_t* gradOutputData,
347348
const int64_t* indicesData,
348-
int features,
349-
int64_t gradOutputSize,
350-
int out_cf_channel_stride,
351-
int in_cf_channel_stride,
352-
int out_nbatch_stride,
353-
int in_nbatch_stride)
349+
index_t features,
350+
index_t gradOutputSize,
351+
index_t out_cf_channel_stride,
352+
index_t in_cf_channel_stride,
353+
index_t out_nbatch_stride,
354+
index_t in_nbatch_stride)
354355
: gradInputData_(gradInputData),
355356
gradOutputData_(gradOutputData),
356357
indicesData_(indicesData),
@@ -365,38 +366,38 @@ struct MaxPool3dBackwardKernelFunctor {
365366
scalar_t* gradInputData_;
366367
const scalar_t* gradOutputData_;
367368
const int64_t* indicesData_;
368-
int features_;
369-
int64_t gradOutputSize_;
370-
int out_cf_channel_stride_;
371-
int in_cf_channel_stride_;
372-
int out_nbatch_stride_;
373-
int in_nbatch_stride_;
369+
index_t features_;
370+
index_t gradOutputSize_;
371+
index_t out_cf_channel_stride_;
372+
index_t in_cf_channel_stride_;
373+
index_t out_nbatch_stride_;
374+
index_t in_nbatch_stride_;
374375
};
375376

376-
template <typename scalar_t, bool channels_last>
377+
template <typename scalar_t, bool channels_last, typename index_t>
377378
void max_pool3d_with_indices_backward_template(
378379
scalar_t* gradInputData,
379380
const scalar_t* gradOutputData,
380381
const int64_t* indicesData,
381-
int features,
382-
int itime,
383-
int iheight,
384-
int iwidth,
385-
int obatch,
386-
int otime,
387-
int oheight,
388-
int owidth) {
389-
int64_t gradOutputSize = obatch * features * otime * oheight * owidth;
390-
391-
auto out_cf_channel_stride = otime * oheight * owidth;
392-
auto in_cf_channel_stride = itime * iheight * iwidth;
393-
auto out_nbatch_stride = features * out_cf_channel_stride;
394-
auto in_nbatch_stride = features * in_cf_channel_stride;
395-
MaxPool3dBackwardKernelFunctor<scalar_t, channels_last> kfn(
382+
int64_t features,
383+
int64_t itime,
384+
int64_t iheight,
385+
int64_t iwidth,
386+
int64_t obatch,
387+
int64_t otime,
388+
int64_t oheight,
389+
int64_t owidth) {
390+
index_t gradOutputSize = obatch * features * otime * oheight * owidth;
391+
392+
index_t out_cf_channel_stride = otime * oheight * owidth;
393+
index_t in_cf_channel_stride = itime * iheight * iwidth;
394+
index_t out_nbatch_stride = features * out_cf_channel_stride;
395+
index_t in_nbatch_stride = features * in_cf_channel_stride;
396+
MaxPool3dBackwardKernelFunctor<scalar_t, channels_last, index_t> kfn(
396397
gradInputData,
397398
gradOutputData,
398399
indicesData,
399-
features,
400+
static_cast<index_t>(features),
400401
gradOutputSize,
401402
out_cf_channel_stride,
402403
in_cf_channel_stride,
@@ -769,33 +770,45 @@ void max_pool3d_with_indices_backward_kernel(
769770
[&] {
770771
scalar_t* grad_input_data =
771772
work_grad_input.mutable_data_ptr<scalar_t>();
772-
if (!channels_last) {
773-
max_pool3d_with_indices_backward_template<scalar_t, false>(
774-
grad_input_data,
775-
work_grad_output.const_data_ptr<scalar_t>(),
776-
work_indices.const_data_ptr<int64_t>(),
777-
nslices,
778-
itime,
779-
iheight,
780-
iwidth,
781-
nbatch,
782-
otime,
783-
oheight,
784-
owidth);
785-
} else {
786-
max_pool3d_with_indices_backward_template<scalar_t, true>(
787-
grad_input_data,
788-
work_grad_output.const_data_ptr<scalar_t>(),
789-
work_indices.const_data_ptr<int64_t>(),
790-
nslices,
791-
itime,
792-
iheight,
793-
iwidth,
794-
nbatch,
795-
otime,
796-
oheight,
797-
owidth);
798-
}
773+
AT_DISPATCH_INDEX_TYPES(
774+
at::native::canUse32BitIndexMath(input, INT_MAX) ? ScalarType::Int
775+
: ScalarType::Long,
776+
"max_pool3d_with_indices_backward_out_xpu",
777+
[&] {
778+
if (!channels_last) {
779+
max_pool3d_with_indices_backward_template<
780+
scalar_t,
781+
false,
782+
index_t>(
783+
grad_input_data,
784+
work_grad_output.const_data_ptr<scalar_t>(),
785+
work_indices.const_data_ptr<int64_t>(),
786+
nslices,
787+
itime,
788+
iheight,
789+
iwidth,
790+
nbatch,
791+
otime,
792+
oheight,
793+
owidth);
794+
} else {
795+
max_pool3d_with_indices_backward_template<
796+
scalar_t,
797+
true,
798+
index_t>(
799+
grad_input_data,
800+
work_grad_output.const_data_ptr<scalar_t>(),
801+
work_indices.const_data_ptr<int64_t>(),
802+
nslices,
803+
itime,
804+
iheight,
805+
iwidth,
806+
nbatch,
807+
otime,
808+
oheight,
809+
owidth);
810+
}
811+
});
799812
});
800813
}
801814

0 commit comments

Comments
 (0)