Skip to content

Commit 6bef852

Browse files
committed
Fix int32 overflow in max_pool3d forward kernel
Template MaxPool3dKernelFunctor and max_pool3d_with_indices_out_template with an index_t type parameter, and dispatch between int32 and int64 at runtime using canUse32BitIndexMath. This prevents overflow when computing strides for large tensors while preserving int32 performance for smaller ones. The forward kernel computes stride values (e.g. in_batch_stride = features * T * H * W) that can exceed INT32_MAX for shapes like [2, 2200, 100, 100, 100] (in_batch_stride = 2.2B). Changes: - Fix typo: MaxPool3dKerenlFunctor -> MaxPool3dKernelFunctor - Add index_t template parameter to functor and template function - Dispatch index_t via AT_DISPATCH_INDEX_TYPES + canUse32BitIndexMath - Remove now-redundant (int64_t) casts in operator() - Add test/regressions/test_max_pool3d_fwd_int64.py with shapes that overflow int32 batch strides in the forward pass
1 parent 18f1f78 commit 6bef852

2 files changed

Lines changed: 222 additions & 142 deletions

File tree

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

Lines changed: 150 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@ DISABLE_RETURN_TYPE_WARNING_BEGIN
3333

3434
namespace at::native::xpu {
3535

36-
template <typename scalar_t, bool channels_last_>
37-
struct MaxPool3dKerenlFunctor {
36+
template <typename scalar_t, bool channels_last_, typename index_t>
37+
struct MaxPool3dKernelFunctor {
3838
void operator()(sycl::nd_item<1> item) const {
39-
auto outputIndex = item.get_global_id(0);
39+
index_t outputIndex = item.get_global_id(0);
4040
if (outputIndex < OutputSize_) {
41-
int64_t batch = 0;
42-
int64_t channel = 0;
43-
int64_t oTime = 0;
44-
int64_t oRow = 0;
45-
int64_t oColumn = 0;
41+
index_t batch = 0;
42+
index_t channel = 0;
43+
index_t oTime = 0;
44+
index_t oRow = 0;
45+
index_t oColumn = 0;
4646
// used only for channels-first indexing
47-
int64_t slice = 0;
47+
index_t slice = 0;
4848
batch = outputIndex / out_batch_stride_;
4949
if constexpr (!channels_last_) {
5050
// order: batch, channel, time
@@ -63,9 +63,12 @@ struct MaxPool3dKerenlFunctor {
6363
int tStart = oTime * dT_ - pT_;
6464
int hStart = oRow * dH_ - pH_;
6565
int wStart = oColumn * dW_ - pW_;
66-
int tEnd = std::min(tStart + (kT_ - 1) * dilationT_ + 1, itime_);
67-
int hEnd = std::min(hStart + (kH_ - 1) * dilationH_ + 1, iheight_);
68-
int wEnd = std::min(wStart + (kW_ - 1) * dilationW_ + 1, iwidth_);
66+
int tEnd = std::min(
67+
tStart + (kT_ - 1) * dilationT_ + 1, static_cast<int>(itime_));
68+
int hEnd = std::min(
69+
hStart + (kH_ - 1) * dilationH_ + 1, static_cast<int>(iheight_));
70+
int wEnd = std::min(
71+
wStart + (kW_ - 1) * dilationW_ + 1, static_cast<int>(iwidth_));
6972

7073
while (tStart < 0)
7174
tStart += dilationT_;
@@ -75,13 +78,13 @@ struct MaxPool3dKerenlFunctor {
7578
wStart += dilationW_;
7679

7780
// maxIndex remains in "channels-first"/contiguous
78-
int64_t maxIndex = tStart * in_hw_stride_ + hStart * iwidth_ + wStart;
79-
int64_t ioffset;
81+
index_t maxIndex = tStart * in_hw_stride_ + hStart * iwidth_ + wStart;
82+
index_t ioffset;
8083

8184
if constexpr (!channels_last_) {
82-
ioffset = (int64_t)slice * in_cf_c_stride_;
85+
ioffset = slice * in_cf_c_stride_;
8386
} else {
84-
ioffset = ((int64_t)batch * in_batch_stride_) + channel;
87+
ioffset = batch * in_batch_stride_ + channel;
8588
}
8689

8790
scalar_t max = at::numeric_limits<scalar_t>::lower_bound();
@@ -90,11 +93,11 @@ struct MaxPool3dKerenlFunctor {
9093
for (int h = hStart; h < hEnd; h += dilationH_) {
9194
for (int w = wStart; w < wEnd; w += dilationW_) {
9295
scalar_t val;
93-
int index = t * in_hw_stride_ + h * iwidth_ + w;
96+
index_t index = t * in_hw_stride_ + h * iwidth_ + w;
9497
if constexpr (!channels_last_) {
9598
val = inputData_[ioffset + index];
9699
} else {
97-
int64_t index_channels_last = index * features_;
100+
index_t index_channels_last = index * features_;
98101
val = inputData_[ioffset + index_channels_last];
99102
}
100103

@@ -106,31 +109,30 @@ struct MaxPool3dKerenlFunctor {
106109
}
107110
}
108111

109-
int64_t out_index;
112+
index_t out_index;
110113
if constexpr (!channels_last_) {
111-
out_index = (int64_t)slice * out_cf_c_stride_ +
112-
oTime * out_cf_d_stride_ + oRow * owidth_ + oColumn;
114+
out_index = slice * out_cf_c_stride_ + oTime * out_cf_d_stride_ +
115+
oRow * owidth_ + oColumn;
113116
} else {
114-
out_index = (int64_t)batch * out_batch_stride_ +
115-
oTime * out_cl_d_stride_ + oRow * out_cl_h_stride_ +
116-
oColumn * features_ + channel;
117+
out_index = batch * out_batch_stride_ + oTime * out_cl_d_stride_ +
118+
oRow * out_cl_h_stride_ + oColumn * features_ + channel;
117119
}
118120
outputData_[out_index] = max;
119121
indicesData_[out_index] = maxIndex;
120122
}
121123
}
122-
MaxPool3dKerenlFunctor(
124+
MaxPool3dKernelFunctor(
123125
const scalar_t* inputData,
124126
scalar_t* outputData,
125127
int64_t* indicesData,
126-
int features,
127-
int itime,
128-
int iheight,
129-
int iwidth,
130-
int obatch,
131-
int otime,
132-
int oheight,
133-
int owidth,
128+
index_t features,
129+
index_t itime,
130+
index_t iheight,
131+
index_t iwidth,
132+
index_t obatch,
133+
index_t otime,
134+
index_t oheight,
135+
index_t owidth,
134136
int kT,
135137
int kH,
136138
int kW,
@@ -143,18 +145,18 @@ struct MaxPool3dKerenlFunctor {
143145
int dilationT,
144146
int dilationH,
145147
int dilationW,
146-
int64_t OutputSize,
147-
int out_cf_d_stride,
148-
int out_cf_c_stride,
149-
int in_cf_d_stride,
150-
int in_cf_c_stride,
151-
int out_cl_h_stride,
152-
int out_cl_d_stride,
153-
int in_cl_h_stride,
154-
int in_cl_d_stride,
155-
int in_batch_stride,
156-
int out_batch_stride,
157-
int in_hw_stride)
148+
index_t OutputSize,
149+
index_t out_cf_d_stride,
150+
index_t out_cf_c_stride,
151+
index_t in_cf_d_stride,
152+
index_t in_cf_c_stride,
153+
index_t out_cl_h_stride,
154+
index_t out_cl_d_stride,
155+
index_t in_cl_h_stride,
156+
index_t in_cl_d_stride,
157+
index_t in_batch_stride,
158+
index_t out_batch_stride,
159+
index_t in_hw_stride)
158160
: inputData_(inputData),
159161
outputData_(outputData),
160162
indicesData_(indicesData),
@@ -195,14 +197,14 @@ struct MaxPool3dKerenlFunctor {
195197
const scalar_t* inputData_;
196198
scalar_t* outputData_;
197199
int64_t* indicesData_;
198-
int features_;
199-
int itime_;
200-
int iheight_;
201-
int iwidth_;
202-
int obatch_;
203-
int otime_;
204-
int oheight_;
205-
int owidth_;
200+
index_t features_;
201+
index_t itime_;
202+
index_t iheight_;
203+
index_t iwidth_;
204+
index_t obatch_;
205+
index_t otime_;
206+
index_t oheight_;
207+
index_t owidth_;
206208
int kT_;
207209
int kH_;
208210
int kW_;
@@ -215,33 +217,33 @@ struct MaxPool3dKerenlFunctor {
215217
int dilationT_;
216218
int dilationH_;
217219
int dilationW_;
218-
int64_t OutputSize_;
219-
int out_cf_d_stride_;
220-
int out_cf_c_stride_;
221-
int in_cf_d_stride_;
222-
int in_cf_c_stride_;
223-
int out_cl_h_stride_;
224-
int out_cl_d_stride_;
225-
int in_cl_h_stride_;
226-
int in_cl_d_stride_;
227-
int in_batch_stride_;
228-
int out_batch_stride_;
229-
int in_hw_stride_;
220+
index_t OutputSize_;
221+
index_t out_cf_d_stride_;
222+
index_t out_cf_c_stride_;
223+
index_t in_cf_d_stride_;
224+
index_t in_cf_c_stride_;
225+
index_t out_cl_h_stride_;
226+
index_t out_cl_d_stride_;
227+
index_t in_cl_h_stride_;
228+
index_t in_cl_d_stride_;
229+
index_t in_batch_stride_;
230+
index_t out_batch_stride_;
231+
index_t in_hw_stride_;
230232
};
231233

232-
template <typename scalar_t, bool channels_last>
234+
template <typename scalar_t, bool channels_last, typename index_t>
233235
void max_pool3d_with_indices_out_template(
234236
const scalar_t* inputData,
235237
scalar_t* outputData,
236238
int64_t* indicesData,
237-
int features,
238-
int itime,
239-
int iheight,
240-
int iwidth,
241-
int obatch,
242-
int otime,
243-
int oheight,
244-
int owidth,
239+
int64_t features,
240+
int64_t itime,
241+
int64_t iheight,
242+
int64_t iwidth,
243+
int64_t obatch,
244+
int64_t otime,
245+
int64_t oheight,
246+
int64_t owidth,
245247
int kT,
246248
int kH,
247249
int kW,
@@ -254,12 +256,12 @@ void max_pool3d_with_indices_out_template(
254256
int dilationT,
255257
int dilationH,
256258
int dilationW) {
257-
int64_t OutputSize = obatch * features * otime * oheight * owidth;
259+
index_t OutputSize = obatch * features * otime * oheight * owidth;
258260

259-
int out_cf_d_stride = 0, out_cf_c_stride = 0, in_cf_d_stride = 0,
260-
in_cf_c_stride = 0;
261-
int out_cl_h_stride = 0, out_cl_d_stride = 0, in_cl_h_stride = 0,
262-
in_cl_d_stride = 0;
261+
index_t out_cf_d_stride = 0, out_cf_c_stride = 0, in_cf_d_stride = 0,
262+
in_cf_c_stride = 0;
263+
index_t out_cl_h_stride = 0, out_cl_d_stride = 0, in_cl_h_stride = 0,
264+
in_cl_d_stride = 0;
263265
if constexpr (!channels_last) {
264266
out_cf_d_stride = owidth * oheight;
265267
out_cf_c_stride = otime * out_cf_d_stride;
@@ -269,21 +271,21 @@ void max_pool3d_with_indices_out_template(
269271
out_cl_h_stride = owidth * features;
270272
out_cl_d_stride = oheight * out_cl_h_stride;
271273
}
272-
auto in_batch_stride = itime * iheight * iwidth * features;
273-
auto out_batch_stride = otime * oheight * owidth * features;
274-
auto in_hw_stride = iwidth * iheight;
275-
MaxPool3dKerenlFunctor<scalar_t, channels_last> kfn(
274+
index_t in_batch_stride = itime * iheight * iwidth * features;
275+
index_t out_batch_stride = otime * oheight * owidth * features;
276+
index_t in_hw_stride = iwidth * iheight;
277+
MaxPool3dKernelFunctor<scalar_t, channels_last, index_t> kfn(
276278
inputData,
277279
outputData,
278280
indicesData,
279-
features,
280-
itime,
281-
iheight,
282-
iwidth,
283-
obatch,
284-
otime,
285-
oheight,
286-
owidth,
281+
static_cast<index_t>(features),
282+
static_cast<index_t>(itime),
283+
static_cast<index_t>(iheight),
284+
static_cast<index_t>(iwidth),
285+
static_cast<index_t>(obatch),
286+
static_cast<index_t>(otime),
287+
static_cast<index_t>(oheight),
288+
static_cast<index_t>(owidth),
287289
kT,
288290
kH,
289291
kW,
@@ -560,57 +562,63 @@ void max_pool3d_with_indices_kernel(
560562
AT_DISPATCH_FLOATING_TYPES_AND2(
561563
kHalf, kBFloat16, input.scalar_type(), "max_pool3d_xpu", [&] {
562564
const scalar_t* input_data = work_input.const_data_ptr<scalar_t>();
563-
if (!channels_last) {
564-
max_pool3d_with_indices_out_template<scalar_t, false>(
565-
input_data,
566-
work_output.mutable_data_ptr<scalar_t>(),
567-
work_indices.mutable_data_ptr<int64_t>(),
568-
nslices, // features
569-
itime,
570-
iheight,
571-
iwidth,
572-
nbatch,
573-
otime,
574-
oheight,
575-
owidth,
576-
kT,
577-
kH,
578-
kW,
579-
dT,
580-
dH,
581-
dW,
582-
pT,
583-
pH,
584-
pW,
585-
dilationT,
586-
dilationH,
587-
dilationW);
588-
} else {
589-
max_pool3d_with_indices_out_template<scalar_t, true>(
590-
input_data,
591-
work_output.mutable_data_ptr<scalar_t>(),
592-
work_indices.mutable_data_ptr<int64_t>(),
593-
nslices, // features
594-
itime,
595-
iheight,
596-
iwidth,
597-
nbatch,
598-
otime,
599-
oheight,
600-
owidth,
601-
kT,
602-
kH,
603-
kW,
604-
dT,
605-
dH,
606-
dW,
607-
pT,
608-
pH,
609-
pW,
610-
dilationT,
611-
dilationH,
612-
dilationW);
613-
}
565+
AT_DISPATCH_INDEX_TYPES(
566+
at::native::canUse32BitIndexMath(input, INT_MAX) ? ScalarType::Int
567+
: ScalarType::Long,
568+
"max_pool3d_xpu",
569+
[&] {
570+
if (!channels_last) {
571+
max_pool3d_with_indices_out_template<scalar_t, false, index_t>(
572+
input_data,
573+
work_output.mutable_data_ptr<scalar_t>(),
574+
work_indices.mutable_data_ptr<int64_t>(),
575+
nslices, // features
576+
itime,
577+
iheight,
578+
iwidth,
579+
nbatch,
580+
otime,
581+
oheight,
582+
owidth,
583+
kT,
584+
kH,
585+
kW,
586+
dT,
587+
dH,
588+
dW,
589+
pT,
590+
pH,
591+
pW,
592+
dilationT,
593+
dilationH,
594+
dilationW);
595+
} else {
596+
max_pool3d_with_indices_out_template<scalar_t, true, index_t>(
597+
input_data,
598+
work_output.mutable_data_ptr<scalar_t>(),
599+
work_indices.mutable_data_ptr<int64_t>(),
600+
nslices, // features
601+
itime,
602+
iheight,
603+
iwidth,
604+
nbatch,
605+
otime,
606+
oheight,
607+
owidth,
608+
kT,
609+
kH,
610+
kW,
611+
dT,
612+
dH,
613+
dW,
614+
pT,
615+
pH,
616+
pW,
617+
dilationT,
618+
dilationH,
619+
dilationW);
620+
}
621+
});
614622
});
615623
}
616624
void max_pool3d_with_indices_backward_kernel(

0 commit comments

Comments
 (0)