From 3f8856862dfb9186ea7bee6935a1044b432131d9 Mon Sep 17 00:00:00 2001 From: Anton Pankratv Date: Tue, 19 Oct 2021 04:53:33 +0300 Subject: [PATCH] Forbid typed data access and roi tensor creation for little bit types (#8007) --- .../op_reference/base_reference_test.cpp | 4 +-- ngraph/core/src/runtime/ov_tensor.cpp | 32 ++++++++++-------- ngraph/test/ov_tensor_test.cpp | 33 +++++++------------ 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/docs/template_plugin/tests/functional/op_reference/base_reference_test.cpp b/docs/template_plugin/tests/functional/op_reference/base_reference_test.cpp index 97b76d1756e..67179994556 100644 --- a/docs/template_plugin/tests/functional/op_reference/base_reference_test.cpp +++ b/docs/template_plugin/tests/functional/op_reference/base_reference_test.cpp @@ -151,12 +151,12 @@ void CommonReferenceTest::ValidateBlobs(const ov::runtime::Tensor& refBlob, cons case ov::element::i4: case ov::element::u4: LayerTestsUtils::LayerTestsCommon::Compare( - refBlob.data(), outBlob.data(), + static_cast(refBlob.data()), static_cast(outBlob.data()), refBlob.get_size() / 2, threshold, abs_threshold); break; case ov::element::u1: LayerTestsUtils::LayerTestsCommon::Compare( - refBlob.data(), outBlob.data(), + static_cast(refBlob.data()), static_cast(outBlob.data()), refBlob.get_size() / 8, threshold, abs_threshold); break; default: diff --git a/ngraph/core/src/runtime/ov_tensor.cpp b/ngraph/core/src/runtime/ov_tensor.cpp index b80546ecfbc..b7ccf5aa9fc 100644 --- a/ngraph/core/src/runtime/ov_tensor.cpp +++ b/ngraph/core/src/runtime/ov_tensor.cpp @@ -65,6 +65,9 @@ Tensor::Tensor(const element::Type element_type, const Shape& shape, void* host_ } Tensor::Tensor(const Tensor& owner, const Coordinate& begin, const Coordinate& end) : _so{owner._so} { + OPENVINO_ASSERT(owner.get_element_type().bitwidth() >= 8, + "ROI Tensor for types with bitwidths less then 8 bit is not implemented. Tensor type: ", + owner.get_element_type()); try { _impl = owner._impl->createROI(begin, end); } catch (const std::exception& ex) { @@ -87,7 +90,10 @@ Shape Tensor::get_shape() const { } Strides Tensor::get_strides() const { - OV_TENSOR_STATEMENT(return _impl->getTensorDesc().getBlockingDesc().getStrides();); + OPENVINO_ASSERT(get_element_type().bitwidth() >= 8, + "Could not get strides for types with bitwidths less then 8 bit. Tensor type: ", + get_element_type()); + OV_TENSOR_STATEMENT(return _impl->getTensorDesc().getBlockingDesc().getStrides()); } size_t Tensor::get_size() const { @@ -108,20 +114,18 @@ void* Tensor::data(const element::Type element_type) const { #undef TYPE_CHECK OPENVINO_ASSERT(host_accesable_implementation, "Tensor implementation type dose not contains host accessable data"); if (element_type != element::undefined) { - OPENVINO_ASSERT( - element::fundamental_type_for(element_type) == element::fundamental_type_for(get_element_type()), - get_element_type(), - " tensor fundamental element type is ", - element::fundamental_type_for(get_element_type()), - ", but it casted to ", - element_type, - " with fundamental element type ", - element::fundamental_type_for(element_type)); + OPENVINO_ASSERT(element_type == get_element_type(), + "Tensor data with element type ", + get_element_type(), + ", is not representable as pointer to ", + element_type); } - OV_TENSOR_STATEMENT({ - return _impl->getTensorDesc().getBlockingDesc().getOffsetPadding() * get_element_type().size() + - InferenceEngine::as(_impl)->rmap().as(); - }); + auto byte_offset = _impl->getTensorDesc().getBlockingDesc().getOffsetPadding() * get_element_type().size(); + OPENVINO_ASSERT((get_element_type().bitwidth() >= 8) || (byte_offset == 0), + "ROI access for types with bitwidths less then 8 bit is not implemented. Tensor type: ", + get_element_type()); + OV_TENSOR_STATEMENT( + { return byte_offset + InferenceEngine::as(_impl)->rmap().as(); }); } bool Tensor::operator!() const noexcept { diff --git a/ngraph/test/ov_tensor_test.cpp b/ngraph/test/ov_tensor_test.cpp index c99ebe04fa0..a88b7b22db0 100644 --- a/ngraph/test/ov_tensor_test.cpp +++ b/ngraph/test/ov_tensor_test.cpp @@ -11,6 +11,7 @@ #include #include +#include "ngraph/coordinate_transform.hpp" #include "openvino/core/except.hpp" #include "openvino/runtime/allocator.hpp" #include "openvino/runtime/tensor.hpp" @@ -191,18 +192,12 @@ TEST_F(OVTensorTest, cannotSetShapeOnRoiTensor) { ASSERT_THROW(roi_tensor.set_shape(newShape), ov::Exception); } -TEST_F(OVTensorTest, makeRangeRoiTensorInt4) { +TEST_F(OVTensorTest, tensorInt4DataAccess) { ov::runtime::Tensor t{ov::element::i4, {1, 6, 5, 3}}; // RGB picture of size (WxH) = 5x6 - ov::runtime::Tensor roi_tensor{t, {0, 1, 2, 0}, {1, 5, 4, 3}}; - ov::Shape ref_shape = {1, 4, 2, 3}; - ptrdiff_t ref_offset = 21; - ov::Strides ref_strides = {90, 15, 3, 1}; - ASSERT_EQ(roi_tensor.get_shape(), ref_shape); - ASSERT_EQ(roi_tensor.data() - t.data(), ref_offset); - ASSERT_EQ(roi_tensor.get_strides(), ref_strides); - ASSERT_EQ(roi_tensor.get_strides(), t.get_strides()); - ASSERT_EQ(ref_strides, roi_tensor.get_strides()); - ASSERT_EQ(roi_tensor.get_element_type(), t.get_element_type()); + ASSERT_THROW((ov::runtime::Tensor{t, {0, 1, 2, 0}, {1, 5, 4, 3}}), ov::Exception); + ASSERT_THROW(t.get_strides(), ov::Exception); + ASSERT_THROW(t.data(), ov::Exception); + ASSERT_NO_THROW(t.data()); } TEST_F(OVTensorTest, makeRangeRoiBlobWrongSize) { @@ -226,17 +221,11 @@ TEST_F(OVTensorTest, readRangeRoiBlob) { auto roi = roi_tensor.data(); ASSERT_NE(nullptr, roi); auto strides = roi_tensor.get_strides(); - for (size_t n = 0; n < roi_tensor.get_shape()[0]; ++n) { - for (size_t c = 0; c < roi_tensor.get_shape()[1]; ++c) { - for (size_t h = 0; h < roi_tensor.get_shape()[2]; ++h) { - for (size_t w = 0; w < roi_tensor.get_shape()[3]; ++w) { - auto actual = roi[w * strides[3] + h * strides[2] + c * strides[1] + n * strides[0]]; - auto expected = t.data()[(w + 4) * strides[3] + (h + 2) * strides[2] + - (c + 0) * strides[1] + (n + 0) * strides[0]]; - ASSERT_EQ(expected, actual) << ov::Shape{n, c, h, w}; - } - } - } + for (auto&& c : ngraph::CoordinateTransformBasic{roi_tensor.get_shape()}) { + auto actual = roi[c[3] * strides[3] + c[2] * strides[2] + c[1] * strides[1] + c[0] * strides[0]]; + auto expected = t.data()[(c[3] + 4) * strides[3] + (c[2] + 2) * strides[2] + + (c[1] + 0) * strides[1] + (c[0] + 0) * strides[0]]; + ASSERT_EQ(expected, actual) << c; } } }