[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:
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
|
||||
+9
@@ -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
|
||||
Reference in new issue
Block a user