[GPU] Disable converting gather8 to 7 pass because GPU plugin supports gather8:nagative-index feature (#15868)

* Add GatherV7 and gatherV8 for convert_gather_0d pattern

* Add updating output_shape using reorder/reshape for scalar indice instead of using ConvertGather0D pass

* Add WA for NMS-gather8 pattern
This commit is contained in:
Kelvin Choi authored and GitHub committed 2023-03-23 23:12:12 -07:00
1 parent e434c320f5
commit 8518a3a8e8
9 files changed
+141 -3

No files matched your search

@@ -8,6 +8,8 @@
#include <ngraph/pattern/op/wrap_type.hpp>
#include <ngraph/rt_info.hpp>
#include <openvino/opsets/opset1.hpp>
#include <openvino/opsets/opset7.hpp>
#include <openvino/opsets/opset8.hpp>
#include <vector>
#include "itt.hpp"
@@ -108,6 +108,8 @@ static void CreateConstantOp(Program& p, const std::shared_ptr<ngraph::op::v0::C
}
consts[op].needsBatchInterpretation = all_inputs_1d && constDims.size() == 1;
} else if (ngraph::is_type<ngraph::op::v1::Gather>(outOp) ||
ngraph::is_type<ngraph::op::v7::Gather>(outOp) ||
ngraph::is_type<ngraph::op::v8::Gather>(outOp) ||
ngraph::is_type<ngraph::op::v1::Split>(outOp) ||
ngraph::is_type<ngraph::op::v1::VariadicSplit>(outOp)) {
consts[op].needsBatchInterpretation = constDims.size() == 1;
@@ -9,7 +9,9 @@
#include "intel_gpu/primitives/gather.hpp"
#include "intel_gpu/primitives/reorder.hpp"
#include "intel_gpu/primitives/reshape.hpp"
using namespace InferenceEngine;
namespace ov {
namespace intel_gpu {
@@ -46,6 +48,43 @@ void CreateGatherOpBase(Program& p, const std::shared_ptr<T>& op, const int64_t
// Dynamic path will do shape infer internally, so no need to pass valid out shape for that case
ov::Shape out_shape = op->get_output_partial_shape(0).is_static() ? op->get_output_shape(0) : ov::Shape{};
// Update output_shape in case of scalar indice
bool need_reshape = false;
auto out_shape_original = out_shape;
if (!p.use_new_shape_infer() && op->get_output_partial_shape(0).is_static()) {
auto input1_shape = op->get_input_shape(1);
if (input1_shape.size() == 0 && batch_dim == 0) {
need_reshape = true;
auto new_axis = axis;
if (new_axis < 0) {
new_axis += op->get_input_shape(0).size();
}
out_shape.push_back(1);
for (int i = out_shape.size() - 1; i > new_axis ; i--) {
out_shape[i] = out_shape[i-1];
}
out_shape[new_axis] = 1;
}
}
// WA for NMS->Gather construction. NMS fills part of the output blob by the -1 if these values
// must not be taken into account.
// CPU also uses this like of WA.
if (support_neg_ind) {
const auto& rti = op->get_rt_info();
const auto& reverse = rti.find("dontReverseIndices");
if (reverse != rti.end()) {
support_neg_ind = false;
}
}
// gather
auto reshapeName = layerName + "";
if (need_reshape) {
layerName = layerName + "_reshape_output";
}
auto gatherPrim = cldnn::gather(layerName,
reordered_inputs[0],
reordered_inputs[1],
@@ -55,6 +94,27 @@ void CreateGatherOpBase(Program& p, const std::shared_ptr<T>& op, const int64_t
support_neg_ind);
p.add_primitive(*op, gatherPrim);
// Add reorder and reshape for scalar indice
if (need_reshape) {
auto input = inputs[0];
input.pid = layerName;
auto targetFormat = cldnn::format::get_default_format(out_shape_original.size());
if (targetFormat.value != cldnn::format::get_default_format(out_shape.size()).value) {
auto reorderName = layerName + "_cldnn_in_reorder";
auto targetDatatype = cldnn::element_type_to_data_type(op->get_input_element_type(0));
auto reorderPrim = cldnn::reorder(reorderName,
input,
targetFormat,
targetDatatype);
p.add_primitive(*op, reorderPrim);
input.pid = reorderName;
}
auto reshapePrim = cldnn::reshape(reshapeName, input, tensor_from_dims(out_shape_original));
p.add_primitive(*op, reshapePrim);
}
}
static void CreateGatherOp(Program& p, const std::shared_ptr<ngraph::op::v1::Gather>& op) {
@@ -421,8 +421,10 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Model> func) {
pass_config->disable<ov::pass::WeightsDequantizeToFakeQuantize>();
pass_config->disable<ov::pass::SimplifyCTCGreedyDecoderSeqLen>();
pass_config->disable<ov::pass::ConvertSoftMax8ToSoftMax1>();
pass_config->enable<ov::pass::ConvertGather8ToGather7>();
pass_config->disable<ov::pass::ConvertShapeOf3>();
pass_config->disable<ov::pass::ConvertGather8ToGather7>();
pass_config->disable<ov::pass::ConvertGather7ToGather1>();
pass_config->enable<ov::pass::ConvertInterpolate1ToInterpolate4>();
if (enableInt8) {
@@ -78,6 +78,18 @@ const std::vector<std::vector<size_t>> inputShapesAxes4b2 = {
std::vector<size_t>{2, 3, 7, 8, 4},
};
const auto GatherIndiceScalar = []() {
return testing::Combine(testing::Values(std::vector<size_t>{1, 3, 4, 5}),
testing::Values(std::vector<size_t>{}),
testing::Values(std::tuple<int, int>(2, 0)),
testing::Values(InferenceEngine::Precision::FP32),
testing::Values(InferenceEngine::Precision::UNSPECIFIED),
testing::Values(InferenceEngine::Precision::UNSPECIFIED),
testing::Values(InferenceEngine::Layout::ANY),
testing::Values(InferenceEngine::Layout::ANY),
testing::Values(CommonTestUtils::DEVICE_GPU));
};
const auto GatherAxes4i4b1 = []() {
return testing::Combine(testing::ValuesIn(inputShapesAxes4b1),
testing::ValuesIn(indicesShapes2),
@@ -182,6 +194,13 @@ INSTANTIATE_TEST_SUITE_P(
Gather8LayerTest::getTestCaseName
);
INSTANTIATE_TEST_SUITE_P(
smoke_GatherIndiceScalar,
Gather8IndiceScalarLayerTest,
GatherIndiceScalar(),
Gather8IndiceScalarLayerTest::getTestCaseName
);
const std::vector<std::vector<int>> indices = {
std::vector<int>{0, 3, 2, 1},
};
@@ -58,8 +58,6 @@ std::vector<std::string> disabledTestPatterns() {
R"(.*Behavior.*OVInferRequestIOTensorTest.*canInferAfterIOBlobReallocation.*)",
R"(.*Behavior.*OVInferRequestDynamicTests.*InferUpperBoundNetworkAfterIOTensorsReshaping.*)",
R"(.*(Auto|Multi).*Behavior.*IncorrectConfigTests.*CanNotLoadNetworkWithIncorrectConfig.*)",
// TODO: until issue is xxx-59670 is resolved
R"(.*Gather8LayerTest.*)",
// Not implemented yet:
R"(.*Behavior.*ExecutableNetworkBaseTest.*canSetConfigToExecNet.*)",
R"(.*Behavior.*ExecutableNetworkBaseTest.*canExport.*)",
@@ -20,4 +20,8 @@ TEST_P(Gather8LayerTest, CompareWithRefs) {
Run();
};
TEST_P(Gather8IndiceScalarLayerTest, CompareWithRefs) {
Run();
};
} // namespace LayerTestsDefinitions
@@ -74,4 +74,13 @@ protected:
void SetUp() override;
};
class Gather8IndiceScalarLayerTest : public testing::WithParamInterface<gather7ParamsTuple>,
virtual public LayerTestsUtils::LayerTestsCommon {
public:
static std::string getTestCaseName(const testing::TestParamInfo<gather7ParamsTuple>& obj);
protected:
void SetUp() override;
};
} // namespace LayerTestsDefinitions
@@ -136,4 +136,46 @@ void Gather8LayerTest::SetUp() {
function = std::make_shared<ngraph::Function>(results, functionParams, "gather");
}
std::string Gather8IndiceScalarLayerTest::getTestCaseName(const testing::TestParamInfo<gather7ParamsTuple>& obj) {
std::tuple<int, int> axis_batchIdx;
std::vector<int> indices;
std::vector<size_t> indicesShape, inputShape;
InferenceEngine::Precision netPrecision;
InferenceEngine::Precision inPrc, outPrc;
InferenceEngine::Layout inLayout, outLayout;
std::string targetName;
std::tie(inputShape, indicesShape, axis_batchIdx, netPrecision, inPrc, outPrc, inLayout, outLayout, targetName) = obj.param;
std::ostringstream result;
result << "IS=" << CommonTestUtils::vec2str(inputShape) << "_";
result << "indicesShape=" << CommonTestUtils::vec2str(indicesShape) << "_";
result << "axis=" << std::get<0>(axis_batchIdx) << "_";
result << "batchIdx=" << std::get<1>(axis_batchIdx) << "_";
result << "netPRC=" << netPrecision.name() << "_";
result << "inPRC=" << inPrc.name() << "_";
result << "outPRC=" << outPrc.name() << "_";
result << "inL=" << inLayout << "_";
result << "outL=" << outLayout << "_";
result << "trgDev=" << targetName << "_";
return result.str();
}
void Gather8IndiceScalarLayerTest::SetUp() {
std::tuple<int, int> axis_batchIdx;
std::vector<size_t> indicesShape;
std::vector<size_t> inputShape;
InferenceEngine::Precision netPrecision;
std::tie(inputShape, indicesShape, axis_batchIdx, netPrecision, inPrc, outPrc, inLayout, outLayout, targetDevice) = GetParam();
int axis = std::get<0>(axis_batchIdx);
int batchIdx = std::get<1>(axis_batchIdx);
auto ngPrc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(netPrecision);
auto functionParams = ngraph::builder::makeParams(ngPrc, { inputShape });
auto paramOuts = ngraph::helpers::convert2OutputVector(ngraph::helpers::castOps2Nodes<ngraph::op::Parameter>(functionParams));
auto indicesNode = ngraph::opset1::Constant::create(ngraph::element::i64, ngraph::Shape{}, {inputShape[axis] - 1})->output(0);
auto axisNode = ngraph::opset8::Constant::create(ngraph::element::i64, ngraph::Shape({}), { axis });
auto gather = std::make_shared<ngraph::opset8::Gather>(paramOuts[0], indicesNode, axisNode, batchIdx);
ngraph::ResultVector results{ std::make_shared<ngraph::opset8::Result>(gather) };
function = std::make_shared<ngraph::Function>(results, functionParams, "gather");
}
} // namespace LayerTestsDefinitions