[PT FE] Extend upsample support (#15826)
* [PT FE] Extend upsample suport * Update tests/layer_tests/pytorch_tests/test_upsample.py Co-authored-by: Ekaterina Aidova <ekaterina.aidova@intel.com> --------- Co-authored-by: Ekaterina Aidova <ekaterina.aidova@intel.com>
This commit is contained in:
parent
900332c46e
commit
a9efe5bd8d
|
|
@ -16,10 +16,12 @@ namespace op {
|
|||
using namespace ov::op;
|
||||
|
||||
namespace {
|
||||
OutputVector base_translate_upsample2d(const NodeContext& context, v4::Interpolate::InterpolateMode interpolate_mode) {
|
||||
num_inputs_check(context, 3, 4);
|
||||
OutputVector base_translate_upsample(const NodeContext& context,
|
||||
v4::Interpolate::InterpolateMode interpolate_mode,
|
||||
size_t dims) {
|
||||
num_inputs_check(context, 1, 4);
|
||||
auto data = context.get_input(0);
|
||||
std::vector<size_t> pad{0};
|
||||
std::vector<size_t> pad(dims, 0);
|
||||
auto size_mode = v4::Interpolate::ShapeCalcMode::SIZES;
|
||||
bool align_corners = false;
|
||||
int scale_id = 2;
|
||||
|
|
@ -29,11 +31,21 @@ OutputVector base_translate_upsample2d(const NodeContext& context, v4::Interpola
|
|||
align_corners = context.const_input<bool>(2);
|
||||
}
|
||||
}
|
||||
auto target_axes = std::make_shared<v0::Constant>(element::i32, Shape{2}, std::vector<int>({2, 3}));
|
||||
std::vector<int> spatial_axes;
|
||||
if (dims == 1) {
|
||||
spatial_axes = {2};
|
||||
} else if (dims == 2) {
|
||||
spatial_axes = {2, 3};
|
||||
} else if (dims == 3) {
|
||||
spatial_axes = {2, 3, 4};
|
||||
} else {
|
||||
FRONT_END_OP_CONVERSION_CHECK(false, "Unsupported number of dimensions in upsample");
|
||||
}
|
||||
auto target_axes = std::make_shared<v0::Constant>(element::i32, Shape{spatial_axes.size()}, spatial_axes);
|
||||
auto scales =
|
||||
context.mark_node(std::make_shared<v0::Constant>(element::f32, Shape{2}, std::vector<double>({1, 1})));
|
||||
context.mark_node(std::make_shared<v0::Constant>(element::f32, Shape{dims}, std::vector<double>(dims, 1)));
|
||||
auto output_sizes =
|
||||
context.mark_node(std::make_shared<v0::Constant>(element::i32, Shape{2}, std::vector<int>({1, 1})));
|
||||
context.mark_node(std::make_shared<v0::Constant>(element::i32, Shape{dims}, std::vector<int>(dims, 1)));
|
||||
if (context.input_is_none(1)) {
|
||||
FRONT_END_OP_CONVERSION_CHECK(!context.input_is_none(scale_id), "Scale or Output size should be provided");
|
||||
auto spatial_scales = context.get_input(scale_id);
|
||||
|
|
@ -48,6 +60,7 @@ OutputVector base_translate_upsample2d(const NodeContext& context, v4::Interpola
|
|||
attrs.coordinate_transformation_mode = v4::Interpolate::CoordinateTransformMode::ASYMMETRIC;
|
||||
attrs.nearest_mode = v4::Interpolate::NearestMode::FLOOR;
|
||||
if (attrs.mode != v4::Interpolate::InterpolateMode::NEAREST) {
|
||||
attrs.coordinate_transformation_mode = v4::Interpolate::CoordinateTransformMode::PYTORCH_HALF_PIXEL;
|
||||
if (align_corners) {
|
||||
attrs.coordinate_transformation_mode = v4::Interpolate::CoordinateTransformMode::ALIGN_CORNERS;
|
||||
}
|
||||
|
|
@ -56,16 +69,33 @@ OutputVector base_translate_upsample2d(const NodeContext& context, v4::Interpola
|
|||
};
|
||||
} // namespace
|
||||
|
||||
OutputVector translate_upsample_linear1d(NodeContext& context) {
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::LINEAR_ONNX, 1);
|
||||
};
|
||||
|
||||
OutputVector translate_upsample_bilinear2d(NodeContext& context) {
|
||||
return base_translate_upsample2d(context, v4::Interpolate::InterpolateMode::LINEAR_ONNX);
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::LINEAR_ONNX, 2);
|
||||
};
|
||||
|
||||
OutputVector translate_upsample_trilinear3d(NodeContext& context) {
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::LINEAR_ONNX, 3);
|
||||
};
|
||||
|
||||
OutputVector translate_upsample_nearest1d(NodeContext& context) {
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::NEAREST, 1);
|
||||
};
|
||||
|
||||
OutputVector translate_upsample_nearest2d(NodeContext& context) {
|
||||
return base_translate_upsample2d(context, v4::Interpolate::InterpolateMode::NEAREST);
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::NEAREST, 2);
|
||||
};
|
||||
|
||||
OutputVector translate_upsample_nearest3d(NodeContext& context) {
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::NEAREST, 3);
|
||||
};
|
||||
|
||||
// bicubic is only supported for 2d in pytorch
|
||||
OutputVector translate_upsample_bicubic2d(NodeContext& context) {
|
||||
return base_translate_upsample2d(context, v4::Interpolate::InterpolateMode::CUBIC);
|
||||
return base_translate_upsample(context, v4::Interpolate::InterpolateMode::CUBIC, 2);
|
||||
};
|
||||
|
||||
} // namespace op
|
||||
|
|
|
|||
|
|
@ -110,7 +110,11 @@ OP_CONVERTER(translate_triu);
|
|||
OP_CONVERTER(translate_unfold);
|
||||
OP_CONVERTER(translate_upsample_bicubic2d);
|
||||
OP_CONVERTER(translate_upsample_bilinear2d);
|
||||
OP_CONVERTER(translate_upsample_linear1d);
|
||||
OP_CONVERTER(translate_upsample_nearest1d);
|
||||
OP_CONVERTER(translate_upsample_nearest2d);
|
||||
OP_CONVERTER(translate_upsample_nearest3d);
|
||||
OP_CONVERTER(translate_upsample_trilinear3d);
|
||||
OP_CONVERTER(translate_var);
|
||||
OP_CONVERTER(translate_var_mean);
|
||||
OP_CONVERTER(translate_where);
|
||||
|
|
@ -303,7 +307,11 @@ const std::map<std::string, PytorchCreatorFunction> get_supported_ops() {
|
|||
{"aten::unsqueeze_", op::inplace_op<op::translate_1to1_match_2_inputs<opset10::Unsqueeze>>},
|
||||
{"aten::upsample_bicubic2d", op::translate_upsample_bicubic2d},
|
||||
{"aten::upsample_bilinear2d", op::translate_upsample_bilinear2d},
|
||||
{"aten::upsample_linear1d", op::translate_upsample_linear1d},
|
||||
{"aten::upsample_nearest1d", op::translate_upsample_nearest1d},
|
||||
{"aten::upsample_nearest2d", op::translate_upsample_nearest2d},
|
||||
{"aten::upsample_nearest3d", op::translate_upsample_nearest3d},
|
||||
{"aten::upsample_trilinear3d", op::translate_upsample_trilinear3d},
|
||||
{"aten::var", op::translate_var},
|
||||
{"aten::var_mean", op::translate_var_mean},
|
||||
{"aten::view", op::translate_reshape},
|
||||
|
|
|
|||
|
|
@ -6,10 +6,50 @@ import pytest
|
|||
from pytorch_layer_test_class import PytorchLayerTest
|
||||
|
||||
|
||||
class TestUpsample1D(PytorchLayerTest):
|
||||
def _prepare_input(self):
|
||||
import numpy as np
|
||||
return (np.random.randn(1, 3, 224).astype(np.float32),)
|
||||
|
||||
def create_model(self, size, scale, mode):
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
class aten_upsample(torch.nn.Module):
|
||||
def __init__(self, size, scale, mode):
|
||||
super().__init__()
|
||||
self.size = size
|
||||
self.scale = scale
|
||||
self.mode = mode
|
||||
|
||||
def forward(self, x):
|
||||
return F.interpolate(x, self.size, scale_factor=self.scale, mode=self.mode)
|
||||
|
||||
ref_net = None
|
||||
|
||||
return aten_upsample(size, scale, mode), ref_net, F"aten::upsample_{mode}1d"
|
||||
|
||||
@pytest.mark.parametrize("mode,size,scale", [
|
||||
('nearest', 300, None),
|
||||
('nearest', 200, None),
|
||||
('nearest', None, 2.5),
|
||||
('nearest', None, 0.75),
|
||||
('linear', 300, None),
|
||||
('linear', 200, None),
|
||||
('linear', None, 2.5,),
|
||||
('linear', None, 0.75),
|
||||
])
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
def test_upsample1d(self, mode, size, scale, ie_device, precision, ir_version):
|
||||
self._test(*self.create_model(size, scale, mode), ie_device,
|
||||
precision, ir_version, trace_model=True)
|
||||
|
||||
|
||||
class TestUpsample2D(PytorchLayerTest):
|
||||
def _prepare_input(self):
|
||||
import numpy as np
|
||||
return (np.zeros((1, 3, 224, 224)).astype(np.float32),)
|
||||
return (np.random.randn(1, 3, 200, 200).astype(np.float32),)
|
||||
|
||||
def create_model(self, size, scale, mode):
|
||||
import torch
|
||||
|
|
@ -31,25 +71,70 @@ class TestUpsample2D(PytorchLayerTest):
|
|||
|
||||
@pytest.mark.parametrize("mode,size,scale", [
|
||||
('nearest', 300, None),
|
||||
('nearest', 200, None),
|
||||
('nearest', (128, 480), None),
|
||||
('nearest', None, 2.5,),
|
||||
('nearest', 150, None),
|
||||
('nearest', (300, 400), None),
|
||||
('nearest', None, 2.5),
|
||||
('nearest', None, 0.75),
|
||||
('nearest', None, (1.2, 0.8)),
|
||||
('nearest', None, (1.5, 2)),
|
||||
('bilinear', 300, None),
|
||||
('bilinear', 200, None),
|
||||
('bilinear', (128, 480), None),
|
||||
('bilinear', 150, None),
|
||||
('bilinear', (400, 480), None),
|
||||
('bilinear', None, 2.5,),
|
||||
('bilinear', None, 0.75),
|
||||
('bilinear', None, (1.2, 0.8)),
|
||||
('bilinear', None, (1.2, 1.3)),
|
||||
('bicubic', 300, None),
|
||||
('bicubic', 200, None),
|
||||
('bicubic', (128, 480), None),
|
||||
('bicubic', 150, None),
|
||||
('bicubic', (400, 480), None),
|
||||
('bicubic', None, 2.5,),
|
||||
('bicubic', None, 0.75),
|
||||
('bicubic', None, (1.2, 0.8))]
|
||||
)
|
||||
('bicubic', None, (1.2, 1.3))
|
||||
])
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
def test_upsample(self, mode, size, scale, ie_device, precision, ir_version):
|
||||
self._test(*self.create_model(size, scale, mode), ie_device, precision, ir_version, trace_model=True)
|
||||
def test_upsample2d(self, mode, size, scale, ie_device, precision, ir_version):
|
||||
self._test(*self.create_model(size, scale, mode), ie_device,
|
||||
precision, ir_version, trace_model=True, **{"custom_eps": 1e-3})
|
||||
|
||||
|
||||
class TestUpsample3D(PytorchLayerTest):
|
||||
def _prepare_input(self):
|
||||
import numpy as np
|
||||
return (np.random.randn(1, 3, 100, 100, 100).astype(np.float32),)
|
||||
|
||||
def create_model(self, size, scale, mode):
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
class aten_upsample(torch.nn.Module):
|
||||
def __init__(self, size, scale, mode):
|
||||
super().__init__()
|
||||
self.size = size
|
||||
self.scale = scale
|
||||
self.mode = mode
|
||||
|
||||
def forward(self, x):
|
||||
return F.interpolate(x, self.size, scale_factor=self.scale, mode=self.mode)
|
||||
|
||||
ref_net = None
|
||||
|
||||
return aten_upsample(size, scale, mode), ref_net, F"aten::upsample_{mode}3d"
|
||||
|
||||
@pytest.mark.parametrize("mode,size,scale", [
|
||||
('nearest', 200, None),
|
||||
('nearest', 150, None),
|
||||
('nearest', (150, 200, 250), None),
|
||||
('nearest', None, 2.5),
|
||||
('nearest', None, 0.75),
|
||||
('nearest', None, (1.5, 2, 2.5)),
|
||||
('trilinear', 200, None),
|
||||
('trilinear', 150, None),
|
||||
('trilinear', (200, 240, 210), None),
|
||||
('trilinear', None, 2.5,),
|
||||
('trilinear', None, 0.75),
|
||||
('trilinear', None, (1.2, 1.1, 1.5)),
|
||||
])
|
||||
@pytest.mark.nightly
|
||||
@pytest.mark.precommit
|
||||
def test_upsample3d(self, mode, size, scale, ie_device, precision, ir_version):
|
||||
self._test(*self.create_model(size, scale, mode), ie_device,
|
||||
precision, ir_version, trace_model=True, **{"custom_eps": 1e-3})
|
||||
|
|
|
|||
Loading…
Reference in New Issue