[GPU] Fix constants reuse (#20003)

This commit is contained in:
Vladimir Paramuzov
2023-09-22 15:29:38 +04:00
committed by GitHub
parent 7a2ac27f09
commit 5611f7d65c
3 changed files with 86 additions and 10 deletions
@@ -89,7 +89,7 @@ public:
std::vector<cldnn::primitive_id> profiling_ids;
std::map<std::string, cldnn::layout> inputLayouts;
using BlobCacheKey = std::pair<const char*, std::vector<size_t>>;
using BlobCacheKey = std::tuple<const char*, ov::Shape, ov::element::Type>;
std::map<BlobCacheKey, cldnn::primitive_id> blobMemCache;
std::shared_ptr<cldnn::program> get_compiled_program() const;
@@ -67,30 +67,31 @@ struct ConstProperties {
bool needsBatchInterpretation;
};
static void create_data(ProgramBuilder& p, const ov::Shape& constDims, const std::shared_ptr<ov::op::v0::Constant>& op, const ConstProperties& props) {
cldnn::tensor constTensor = getConstTensor(constDims);
auto constFormat = cldnn::format::get_default_format(constDims.size());
static void create_data(ProgramBuilder& p, const ov::Shape& const_shape, const std::shared_ptr<ov::op::v0::Constant>& op, const ConstProperties& props) {
cldnn::tensor constTensor = getConstTensor(const_shape);
auto constFormat = cldnn::format::get_default_format(const_shape.size());
if (props.needsBatchInterpretation) {
constTensor.batch[0] = static_cast<cldnn::tensor::value_type>(constTensor.count());
constTensor.feature[0] = 1;
}
// If constDims has a dimension = 0, then create tensor with single value
// If const_shape has a dimension = 0, then create tensor with single value
// TODO: check if dim=0 is a valid case
if (std::accumulate(constDims.begin(), constDims.end(), size_t(1), std::multiplies<size_t>()) == 0)
if (std::accumulate(const_shape.begin(), const_shape.end(), size_t(1), std::multiplies<size_t>()) == 0)
constTensor = cldnn::tensor{1};
auto newDims = constDims;
cldnn::data_types out_dtype = cldnn::element_type_to_data_type(op->get_output_element_type(0));
cldnn::layout constLayout = p.use_new_shape_infer() ? cldnn::layout(newDims, out_dtype, constFormat) :
cldnn::layout constLayout = p.use_new_shape_infer() ? cldnn::layout(const_shape, out_dtype, constFormat) :
cldnn::layout(out_dtype, constFormat, constTensor);
cldnn::primitive_id initialconstPrimID = layer_type_name_ID(op);
cldnn::primitive_id constPrimID;
auto data = op->get_data_ptr<char>();
auto bufIter = p.blobMemCache.find(std::make_pair(data, newDims));
const auto cache_key = std::make_tuple(data, const_shape, op->get_output_element_type(0));
auto bufIter = p.blobMemCache.find(cache_key);
if (bufIter != p.blobMemCache.end()) {
constPrimID = bufIter->second;
@@ -112,7 +113,7 @@ static void create_data(ProgramBuilder& p, const ov::Shape& constDims, const std
std::memcpy(&buf[0], &data[0], bufSize);
p.add_primitive(*op, cldnn::data(initialconstPrimID, mem));
p.blobMemCache[std::make_pair(data, newDims)] = initialconstPrimID;
p.blobMemCache[cache_key] = initialconstPrimID;
constPrimID = initialconstPrimID;
}
}
@@ -0,0 +1,75 @@
// Copyright (C) 2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "openvino/core/partial_shape.hpp"
#include "openvino/runtime/properties.hpp"
#include "shared_test_classes/base/ov_subgraph.hpp"
#include "functional_test_utils/skip_tests_config.hpp"
#include "common_test_utils/test_constants.hpp"
#include "common_test_utils/ov_tensor_utils.hpp"
using namespace ov::test;
namespace ov {
namespace test {
namespace intel_gpu {
class SharedConstantGPUTest : public SubgraphBaseTest {
protected:
void SetUp() override {
targetDevice = ov::test::utils::DEVICE_GPU;
std::vector<InputShape> input_shapes {
{ov::PartialShape{1}, {{1}}},
{ov::PartialShape{1}, {{1}}},
{ov::PartialShape{2}, {{2}}},
{ov::PartialShape{1, 2}, {{1, 2}}},
};
init_input_shapes(input_shapes);
auto p0 = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, input_shapes[0].first);
auto p1 = std::make_shared<ov::op::v0::Parameter>(ov::element::i32, input_shapes[1].first);
auto p2 = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, input_shapes[2].first);
auto p3 = std::make_shared<ov::op::v0::Parameter>(ov::element::f32, input_shapes[3].first);
std::vector<int32_t> values0{0};
std::vector<float> values1{0.0f, 1.0f};
ov::Tensor t0(ov::element::f32, input_shapes[0].first.to_shape(), values0.data());
ov::Tensor t1(ov::element::i32, input_shapes[1].first.to_shape(), values0.data());
ov::Tensor t2(ov::element::f32, input_shapes[2].first.to_shape(), values1.data());
ov::Tensor t3(ov::element::f32, input_shapes[3].first.to_shape(), values1.data());
auto c0 = std::make_shared<ov::op::v0::Constant>(t0);
auto c1 = std::make_shared<ov::op::v0::Constant>(t1);
auto c2 = std::make_shared<ov::op::v0::Constant>(t2);
auto c3 = std::make_shared<ov::op::v0::Constant>(t3);
auto add0 = std::make_shared<ov::op::v1::Add>(p0, c0);
auto add1 = std::make_shared<ov::op::v1::Add>(p1, c1);
auto add2 = std::make_shared<ov::op::v1::Add>(p2, c2);
auto add3 = std::make_shared<ov::op::v1::Add>(p3, c3);
ov::ParameterVector params{p0, p1, p2, p3};
ov::ResultVector results {
std::make_shared<ov::op::v0::Result>(add0->output(0)),
std::make_shared<ov::op::v0::Result>(add1->output(0)),
std::make_shared<ov::op::v0::Result>(add2->output(0)),
std::make_shared<ov::op::v0::Result>(add3->output(0))
};
function = std::make_shared<ov::Model>(results, params, "SharedConstantGPUTest");
this->configuration.insert({ov::hint::inference_precision(ov::element::f32)});
}
};
TEST_F(SharedConstantGPUTest, CompareWithRefs) {
SKIP_IF_CURRENT_TEST_IS_DISABLED()
run();
}
} // namespace intel_gpu
} // namespace test
} // namespace ov