Skip to content

Commit 8ec27f1

Browse files
Revert Conv3d portable convolution support (pytorch#20888)
Summary: - Revert 636daf1, which added forward portable Conv3d support for contiguous 5D inputs in aten::convolution.out. Testing: - git diff --check origin/main...HEAD - python3 -m py_compile backends/cortex_m/test/ops/test_conv.py Note: - Tried `buck2 test //kernels/test:op_convolution_test`, but this checkout has no `.buck2` file, so Buck could not start.
1 parent abd2b54 commit 8ec27f1

4 files changed

Lines changed: 47 additions & 406 deletions

File tree

backends/cortex_m/test/ops/test_conv.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ def test_dialect_conv2d(test_case, cortex_m_target):
333333

334334
xfails_implementation: dict[str, xfail_type] = {
335335
"conv1d": "Currently not supported.",
336+
"conv3d": "Currently not supported.",
336337
}
337338

338339

kernels/portable/cpu/op_convolution.cpp

Lines changed: 21 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -191,117 +191,6 @@ void conv2d_impl(
191191
}
192192
}
193193

194-
template <typename CTYPE, typename LoadFn = CTYPE (*)(const void*)>
195-
void conv3d_impl(
196-
const CTYPE* const in_ptr,
197-
SizesArrayRef in_sizes,
198-
StridesArrayRef in_strides,
199-
const CTYPE* const w_ptr,
200-
SizesArrayRef w_sizes,
201-
StridesArrayRef w_strides,
202-
const std::optional<Tensor>& bias,
203-
const char* const bias_ptr,
204-
LoadFn load_bias,
205-
IntArrayRef stride,
206-
IntArrayRef padding,
207-
IntArrayRef dilation,
208-
const int64_t groups,
209-
CTYPE* const out_ptr,
210-
SizesArrayRef out_sizes,
211-
StridesArrayRef out_strides,
212-
const size_t batch,
213-
const size_t group,
214-
const size_t out_c) {
215-
size_t in_C = in_sizes[1];
216-
size_t out_D = out_sizes[2];
217-
size_t in_D = in_sizes[2];
218-
size_t w_D = w_sizes[2];
219-
220-
size_t out_H = out_sizes[3];
221-
size_t in_H = in_sizes[3];
222-
size_t w_H = w_sizes[3];
223-
224-
size_t out_W = out_sizes[4];
225-
size_t in_W = in_sizes[4];
226-
size_t w_W = w_sizes[4];
227-
228-
size_t in_C_per_group = in_C / groups;
229-
size_t in_c_start = group * in_C_per_group;
230-
231-
executorch::aten::SizesType in_coord[kTensorDimensionLimit];
232-
in_coord[0] = batch;
233-
executorch::aten::SizesType out_coord[kTensorDimensionLimit];
234-
out_coord[0] = batch;
235-
out_coord[1] = out_c;
236-
executorch::aten::SizesType w_coord[kTensorDimensionLimit];
237-
238-
const int64_t stride_z = val_at(stride, 0);
239-
const int64_t padding_z = val_at(padding, 0, /*default_value=*/0);
240-
const int64_t dilation_z = val_at(dilation, 0);
241-
const int64_t stride_y = val_at(stride, 1);
242-
const int64_t padding_y = val_at(padding, 1, /*default_value=*/0);
243-
const int64_t dilation_y = val_at(dilation, 1);
244-
const int64_t stride_x = val_at(stride, 2);
245-
const int64_t padding_x = val_at(padding, 2, /*default_value=*/0);
246-
const int64_t dilation_x = val_at(dilation, 2);
247-
248-
w_coord[0] = out_c;
249-
for (const auto out_z : c10::irange(out_D)) {
250-
out_coord[2] = out_z;
251-
for (const auto out_y : c10::irange(out_H)) {
252-
out_coord[3] = out_y;
253-
for (const auto out_x : c10::irange(out_W)) {
254-
out_coord[4] = out_x;
255-
256-
CTYPE accum = 0.0f;
257-
for (const auto in_c :
258-
c10::irange(in_c_start, in_c_start + in_C_per_group)) {
259-
in_coord[1] = in_c;
260-
w_coord[1] = in_c - in_c_start;
261-
262-
for (const auto w_z : c10::irange(w_D)) {
263-
w_coord[2] = w_z;
264-
ssize_t in_z = stride_z * out_z + dilation_z * w_z - padding_z;
265-
in_coord[2] = in_z;
266-
if (in_z < 0 || in_z >= static_cast<ssize_t>(in_D)) {
267-
continue;
268-
}
269-
270-
for (const auto w_y : c10::irange(w_H)) {
271-
w_coord[3] = w_y;
272-
ssize_t in_y = stride_y * out_y + dilation_y * w_y - padding_y;
273-
in_coord[3] = in_y;
274-
if (in_y < 0 || in_y >= static_cast<ssize_t>(in_H)) {
275-
continue;
276-
}
277-
278-
for (const auto w_x : c10::irange(w_W)) {
279-
w_coord[4] = w_x;
280-
ssize_t in_x = stride_x * out_x + dilation_x * w_x - padding_x;
281-
in_coord[4] = in_x;
282-
if (in_x >= 0 && in_x < static_cast<ssize_t>(in_W)) {
283-
size_t in_idx =
284-
calculate_linear_index(in_coord, in_strides.data(), 5);
285-
size_t w_idx =
286-
calculate_linear_index(w_coord, w_strides.data(), 5);
287-
accum += in_ptr[in_idx] * w_ptr[w_idx];
288-
}
289-
}
290-
}
291-
}
292-
}
293-
294-
if (bias_ptr != nullptr) {
295-
accum += load_bias(&bias_ptr[out_c * bias.value().element_size()]);
296-
}
297-
size_t out_idx =
298-
calculate_linear_index(out_coord, out_strides.data(), 5);
299-
out_ptr[out_idx] = accum;
300-
}
301-
}
302-
}
303-
}
304-
305194
template <typename CTYPE, typename LoadFn = CTYPE (*)(const void*)>
306195
void convolution_wrapper(
307196
const Tensor& in,
@@ -405,7 +294,6 @@ void convolution_wrapper(
405294
size_t out_N = out.size(0);
406295
size_t out_C = out.size(1);
407296
size_t out_C_per_group = out_C / groups;
408-
const bool is_conv3d = in_sizes.size() == 5;
409297

410298
if (transposed) {
411299
// For transposed convolution, we need to initialized the output before we
@@ -430,50 +318,27 @@ void convolution_wrapper(
430318
// Populate all the out channels in the group
431319
for (const auto out_c :
432320
c10::irange(out_c_start, out_c_start + out_C_per_group)) {
433-
if (is_conv3d) {
434-
conv3d_impl(
435-
in_ptr,
436-
in_sizes,
437-
{in_strides, 5},
438-
w_ptr,
439-
weight_sizes,
440-
{weight_strides, 5},
441-
bias,
442-
bias_ptr,
443-
load_bias,
444-
stride_,
445-
padding_,
446-
dilation_,
447-
groups,
448-
out_ptr,
449-
out_sizes,
450-
{out_strides, 5},
451-
batch,
452-
group,
453-
out_c);
454-
} else {
455-
conv2d_impl(
456-
in_ptr,
457-
in_sizes,
458-
{in_strides, 4},
459-
w_ptr,
460-
weight_sizes,
461-
{weight_strides, 4},
462-
bias,
463-
bias_ptr,
464-
load_bias,
465-
stride_,
466-
padding_,
467-
dilation_,
468-
groups,
469-
out_ptr,
470-
out_sizes,
471-
{out_strides, 4},
472-
batch,
473-
group,
474-
out_c,
475-
transposed);
476-
}
321+
conv2d_impl(
322+
in_ptr,
323+
in_sizes,
324+
{in_strides, 4},
325+
w_ptr,
326+
weight_sizes,
327+
{weight_strides, 4},
328+
bias,
329+
bias_ptr,
330+
load_bias,
331+
stride_,
332+
padding_,
333+
dilation_,
334+
groups,
335+
out_ptr,
336+
out_sizes,
337+
{out_strides, 4},
338+
batch,
339+
group,
340+
out_c,
341+
transposed);
477342
}
478343
}
479344
}

kernels/portable/cpu/util/kernel_ops_util.cpp

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@ bool param_array_is_valid(
4545
return true;
4646
}
4747

48-
void fill_convolution_kernel_size(
49-
const Tensor& weight,
50-
int64_t* kernel_size,
51-
size_t* kernel_ndim) {
52-
*kernel_ndim = weight.dim() - 2;
53-
for (const auto i : c10::irange(*kernel_ndim)) {
54-
kernel_size[i] = weight.size(i + 2);
55-
}
56-
}
57-
5848
} // namespace
5949

6050
bool int_array_all_ge(IntArrayRef array, int64_t val) {
@@ -391,29 +381,18 @@ bool check_convolution_args(
391381
const Tensor& out) {
392382
ET_LOG_AND_RETURN_IF_FALSE(tensors_have_same_dtype(in, weight, out));
393383

384+
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_default_or_channels_last_dim_order(in));
385+
ET_LOG_AND_RETURN_IF_FALSE(
386+
tensor_is_default_or_channels_last_dim_order(weight));
387+
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_default_or_channels_last_dim_order(out));
388+
394389
ET_CHECK_OR_RETURN_FALSE(
395-
in.dim() == 3 || in.dim() == 4 || in.dim() == 5,
396-
"Expect input tensor to be 3-D, 4-D or 5-D, but got, %zu.",
390+
in.dim() == 3 || in.dim() == 4,
391+
"Expect input tensor to be 3-D or 4-D, but got, %zu.",
397392
static_cast<size_t>(in.dim()));
398393
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_rank(weight, in.dim()));
399394
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_rank(out, in.dim()));
400395

401-
if (in.dim() == 5) {
402-
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_default_dim_order(in));
403-
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_default_dim_order(weight));
404-
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_default_dim_order(out));
405-
ET_CHECK_OR_RETURN_FALSE(
406-
!transposed,
407-
"Transposed 3D convolution is not yet supported on portable.");
408-
} else {
409-
ET_LOG_AND_RETURN_IF_FALSE(
410-
tensor_is_default_or_channels_last_dim_order(in));
411-
ET_LOG_AND_RETURN_IF_FALSE(
412-
tensor_is_default_or_channels_last_dim_order(weight));
413-
ET_LOG_AND_RETURN_IF_FALSE(
414-
tensor_is_default_or_channels_last_dim_order(out));
415-
}
416-
417396
if (bias.has_value()) {
418397
ET_LOG_AND_RETURN_IF_FALSE(tensor_is_rank(bias.value(), 1));
419398
ET_CHECK_OR_RETURN_FALSE(
@@ -425,11 +404,15 @@ bool check_convolution_args(
425404
transposed ? groups * weight.size(1) : weight.size(0));
426405
}
427406

428-
int64_t kernel_size[3];
429-
size_t kernel_ndim = 0;
430-
fill_convolution_kernel_size(weight, kernel_size, &kernel_ndim);
431-
ET_LOG_AND_RETURN_IF_FALSE(
432-
kernel_size_is_valid({kernel_size, kernel_ndim}, kernel_ndim));
407+
int64_t kernel_size[2];
408+
size_t kernel_ndim = 2;
409+
if (weight.dim() == 3) {
410+
kernel_size[0] = weight.size(2);
411+
kernel_ndim = 1;
412+
} else {
413+
kernel_size[0] = weight.size(2);
414+
kernel_size[1] = weight.size(3);
415+
}
433416
ET_LOG_AND_RETURN_IF_FALSE(
434417
stride_is_valid(stride, kernel_ndim, /*allow_empty=*/false));
435418
ET_LOG_AND_RETURN_IF_FALSE(
@@ -499,9 +482,15 @@ void get_convolution_out_target_size(
499482
out_sizes[1] = in.size(1) == 0 ? 0 : groups * weight.size(1);
500483
}
501484

502-
int64_t kernel_size[3];
503-
size_t kernel_ndim = 0;
504-
fill_convolution_kernel_size(weight, kernel_size, &kernel_ndim);
485+
int64_t kernel_size[2];
486+
size_t kernel_ndim = 2;
487+
if (weight.dim() == 3) {
488+
kernel_size[0] = weight.size(2);
489+
kernel_ndim = 1;
490+
} else {
491+
kernel_size[0] = weight.size(2);
492+
kernel_size[1] = weight.size(3);
493+
}
505494
calculate_kernel_output_sizes(
506495
in,
507496
kernel_ndim,

0 commit comments

Comments
 (0)