Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / inference_engine_tests / blob_proxy_test.cpp
1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4
5 #include <gtest/gtest.h>
6 #include <gmock/gmock-spec-builders.h>
7
8 #include "mock_allocator.hpp"
9 #include <ie_blob.h>
10 #include <ie_blob_proxy.hpp>
11
12 using namespace ::testing;
13 using namespace std;
14 using namespace InferenceEngine;
15 using namespace InferenceEngine::details;
16
17 #define MAKE_SHORT(l, h) h * 0x100 + l
18
19 class BlobProxyTests: public ::testing::Test {
20 protected:
21     virtual void TearDown() {
22     }
23
24     virtual void SetUp() {
25     }
26
27     shared_ptr<MockAllocator> createMockAllocator() {
28         return shared_ptr<MockAllocator>(new MockAllocator());
29     }
30
31
32 public:
33
34 };
35
36 TEST_F(BlobProxyTests, convertByteBlobToFloat) {
37     const int size = 4;
38     float test_array[size] = {2.2f, 3.5f, 1.1f, 0.0f};
39     TBlob<uint8_t>::Ptr b(new TBlob<uint8_t>(Precision::U8, C, {size * sizeof(float)}));
40     b->allocate();
41     uint8_t *sPtr = (uint8_t *) test_array;
42     uint8_t *dPtr = b->data();
43     ASSERT_EQ(b->size(), size * sizeof(float));
44     for (size_t i = 0; i < b->size(); i++) {
45         dPtr[i] = sPtr[i];
46     }
47 }
48
49 TEST_F(BlobProxyTests, shouldNotDeAllocate)
50 {
51     SizeVector v = {1, 2, 3};
52     auto allocator = createMockAllocator();
53
54     TBlobProxy<float> proxy(Precision::FP32, C, TBlob<float>(Precision::FP32, CHW, v, dynamic_pointer_cast<IAllocator>(allocator)), 2, {2});
55
56     EXPECT_EQ(((Blob&)proxy).deallocate(), false);
57 }
58
59
60 TEST_F(BlobProxyTests, canAccessProxyBlobUsingBaseMethod)
61 {
62     SizeVector v = {1, 2, 3};
63     auto allocator = createMockAllocator();
64
65     float data[] = {5,6,7,8,9,10};
66
67     EXPECT_CALL(*allocator.get(), alloc(1 * 2 * 3 * sizeof(float))).WillRepeatedly(Return((void*)1));
68     EXPECT_CALL(*allocator.get(), lock(_,LOCK_FOR_WRITE)).WillRepeatedly(Return(data));
69     EXPECT_CALL(*allocator.get(), unlock(_)).Times(1);
70     EXPECT_CALL(*allocator.get(), free(_)).Times(1);
71
72     TBlob<float> blob(Precision::FP32, CHW, v, dynamic_pointer_cast<IAllocator>(allocator));
73     blob.allocate();
74
75     TBlobProxy<float> proxy(Precision::FP32, C, move(blob), 2, {2});
76
77     auto proxyBuffer = proxy.buffer();
78     float *ptr = (float*)(void*)proxyBuffer;
79     ASSERT_EQ(ptr[2] , 9);
80 }
81
82 TEST_F(BlobProxyTests, canAccessProxyBlobUsingHelpers)
83 {
84     SizeVector v = {1, 2, 3};
85     auto allocator = createMockAllocator();
86
87     float data[] = {5,6,7, 8, 9, 10};
88
89     EXPECT_CALL(*allocator.get(), alloc(1 * 2 * 3 * sizeof(float))).WillRepeatedly(Return((void*)1));
90     EXPECT_CALL(*allocator.get(), lock(_,LOCK_FOR_WRITE)).WillOnce(Return(data));
91     EXPECT_CALL(*allocator.get(), lock(_,LOCK_FOR_READ)).WillOnce(Return(data));
92     EXPECT_CALL(*allocator.get(), unlock(_)).Times(2);
93     EXPECT_CALL(*allocator.get(), free(_)).Times(1);
94
95     TBlob<float> blob(Precision::FP32, CHW, v, dynamic_pointer_cast<IAllocator>(allocator));
96     blob.allocate();
97
98     TBlobProxy<float> proxy(Precision::FP32, C, std::move(blob), 2, {2});
99
100     auto proxyData = proxy.data();
101     float *ptr = (float * )&proxyData[0];
102     ASSERT_EQ(ptr[2] , 9);
103
104     auto readOnly = proxy.readOnly();
105     ptr = (float * )&readOnly[0];
106     ASSERT_EQ(ptr[2] , 9);
107 }
108
109 TEST_F(BlobProxyTests, canCreateProxyBlobFromDifferentBaseBlobType)
110 {
111     SizeVector v = {1, 2, 3};
112     auto allocator = createMockAllocator();
113
114     uint8_t data[] = {5, 6, 7, 8, 9, 10};
115
116     EXPECT_CALL(*allocator.get(), alloc(1 * 2 * 3 * sizeof(uint8_t))).WillRepeatedly(Return((void*)1));
117     EXPECT_CALL(*allocator.get(), lock(_,LOCK_FOR_READ)).WillOnce(Return(data));
118     EXPECT_CALL(*allocator.get(), unlock(_)).Times(1);
119     EXPECT_CALL(*allocator.get(), free(_)).Times(1);
120
121     TBlob<uint8_t > blob(Precision::U8, CHW, v, dynamic_pointer_cast<IAllocator>(allocator));
122     blob.allocate();
123
124     Blob::Ptr spBlob (&blob, [](Blob*){
125         //don't delete
126     });
127
128     TBlobProxy<short> proxy(Precision::I16, C, spBlob, 0, {3});
129
130     auto readOnly = proxy.readOnly();
131     const short * ptr = readOnly;
132     ASSERT_EQ(ptr[0] , MAKE_SHORT(data[0], data[1]));
133     ASSERT_EQ(ptr[1] , MAKE_SHORT(data[2], data[3]));
134     ASSERT_EQ(ptr[2] , MAKE_SHORT(data[4], data[5]));
135 }
136
137 TEST_F(BlobProxyTests, canNotCreateBlobWithOffsetOfSizeOutOfOriginal) {
138     SizeVector v = {1, 1, 3};
139     auto allocator = createMockAllocator();
140
141     EXPECT_CALL(*allocator.get(), alloc(1 * 1 * 3 * sizeof(float))).WillRepeatedly(Return((void*)1));
142     EXPECT_CALL(*allocator.get(), free(_)).Times(1);
143
144     TBlob<float> blob(Precision::FP32, CHW, v, dynamic_pointer_cast<IAllocator>(allocator));
145     blob.allocate();
146
147     Blob::Ptr spBlob (&blob, [](Blob*){
148         //don't delete
149     });
150
151     EXPECT_THROW(TBlobProxy<float>(Precision::FP32, C, spBlob, 0, {4}), InferenceEngineException);
152     EXPECT_THROW(TBlobProxy<float>(Precision::FP32, C, spBlob, 3, {1}), InferenceEngineException);
153     EXPECT_THROW(TBlobProxy<float>(Precision::FP32, C, spBlob, 2, {2}), InferenceEngineException);
154 }
155
156
157 TEST_F(BlobProxyTests, canAccessBothArraysAfterProxying)
158 {
159     SizeVector v = {1, 2, 4};
160     auto allocator = createMockAllocator();
161
162     uint8_t data[] = {5, 6, 7, 8, 9, 10, 11, 12};
163
164     EXPECT_CALL(*allocator.get(), alloc(1 * 2 * 4 * sizeof(uint8_t))).WillRepeatedly(Return((void*)1));
165     EXPECT_CALL(*allocator.get(), lock(_,LOCK_FOR_READ)).Times(2).WillRepeatedly(Return(data));
166     EXPECT_CALL(*allocator.get(), unlock(_)).Times(2);
167     EXPECT_CALL(*allocator.get(), free(_)).Times(1);
168
169     TBlob<uint8_t> blob(Precision::U8, CHW, v, dynamic_pointer_cast<IAllocator>(allocator));
170     blob.allocate();
171
172     Blob::Ptr spBlob (&blob, [](Blob*){
173         //don't delete
174     });
175
176     TBlobProxy<short> proxy(Precision::I16, C, spBlob, 2, {3});
177
178     auto readOnly = proxy.readOnly();
179     short * ptr = (short * )&readOnly[0];
180     ASSERT_EQ(ptr[0] , MAKE_SHORT(data[2], data[3]));
181     ASSERT_EQ(ptr[1] , MAKE_SHORT(data[4], data[5]));
182
183     auto origBuffer = blob.readOnly();
184     const uint8_t* origPtr = origBuffer;
185
186     ASSERT_EQ(origPtr[0] , 5);
187     ASSERT_EQ(origPtr[1] , 6);
188
189 }
190
191 TEST_F(BlobProxyTests, convertTwoByteBlobToFloat) {
192     const int size = 4;
193     float test_array[size] = {2.2f, 3.5f, 1.1f, 0.0f};
194     TBlob<uint16_t>::Ptr b(new TBlob<uint16_t>(Precision::U16, C, {size*sizeof(float) / sizeof(uint16_t)}));
195     b->allocate();
196     uint16_t *sPtr = (uint16_t *) test_array;
197     uint16_t *dPtr = b->data();
198     ASSERT_EQ(b->byteSize(), size*sizeof(float));
199     ASSERT_EQ(b->size(), size*sizeof(float)/sizeof(uint16_t));
200     for(size_t i = 0; i < b->size(); i++) {
201         dPtr[i] = sPtr[i];
202     }
203
204     TBlobProxy<float>::Ptr proxy(new TBlobProxy<float>(Precision::FP32, C, b, sizeof(float) / sizeof(uint16_t), {size - 1}));
205     ASSERT_NEAR(3.5f, proxy->data()[0], 0.0001f);
206     ASSERT_NEAR(1.1f, proxy->data()[1], 0.0001f);
207     ASSERT_NEAR(0.0f, proxy->data()[2], 0.0001f);
208     ASSERT_EQ(size - 1, proxy->size());
209     ASSERT_EQ(size*sizeof(float) - sizeof(float), proxy->byteSize());
210 }
211
212 TEST_F(BlobProxyTests, throwsIfSmallProxyObjectSize) {
213     TBlob<float>::Ptr b(new TBlob<float>(Precision::FP32, C));
214     b->set({ 1.0f, 2.0f, 3.0f });
215     try {
216         TBlobProxy<uint8_t> proxy(Precision::U8, C, b, 0, { b->byteSize() + 1 });
217         FAIL() << "Should have failed by now: proxy size is larger than blob size";
218     }
219     catch (InferenceEngine::details::InferenceEngineException ex) {};
220 }
221
222 TEST_F(BlobProxyTests, canReturnConstantData) {
223     TBlob<float>::Ptr b(new TBlob<float>(Precision::FP32, C));
224     b->set({ 1.0f, 2.0f, 3.0f });
225     TBlobProxy<uint8_t> const proxy(Precision::U8, C, b, 0, { b->byteSize() });
226     ASSERT_NE(proxy.cbuffer().as<const void*>(), nullptr);
227 }
228
229 TEST_F(BlobProxyTests, canIterateOverData) {
230     TBlob<uint8_t>::Ptr b(new TBlob<uint8_t >(Precision::FP32, C));
231     b->set({ 1, 2, 3 });
232     TBlobProxy<uint8_t> proxy(Precision::U8, C, b, 1, { 2 });
233     vector<uint8_t > u8buffer;
234     for (auto & element : proxy) {
235         u8buffer.push_back(element);
236     }
237     ASSERT_EQ(2, u8buffer.size());
238     ASSERT_EQ(2, u8buffer[0]);
239     ASSERT_EQ(3, u8buffer[1]);
240 }
241
242 TEST_F(BlobProxyTests, canIterateOverReadOnly) {
243     TBlob<uint8_t>::Ptr b(new TBlob<uint8_t >(Precision::FP32, C));
244     b->set({ 1, 2, 3 });
245     TBlobProxy<uint8_t> const proxy(Precision::U8, C, b, 1, { 2 });
246     vector<uint8_t > u8buffer;
247     for (auto  element : proxy) {
248         u8buffer.push_back(element);
249     }
250     ASSERT_EQ(2, u8buffer.size());
251     ASSERT_EQ(2, u8buffer[0]);
252     ASSERT_EQ(3, u8buffer[1]);
253 }