Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / tests / unit / engines / gna / gna_memory_test.cpp
1 //
2 // Copyright 2016-2018 Intel Corporation.
3 //
4 // This software and the related documents are Intel copyrighted materials,
5 // and your use of them is governed by the express license under which they
6 // were provided to you (End User License Agreement for the Intel(R) Software
7 // Development Products (Version May 2017)). Unless the License provides
8 // otherwise, you may not use, modify, copy, publish, distribute, disclose or
9 // transmit this software or the related documents without Intel's prior
10 // written permission.
11 //
12 // This software and the related documents are provided as is, with no
13 // express or implied warranties, other than those that are expressly
14 // stated in the License.
15 //
16
17 #include <vector>
18 #include <gtest/gtest.h>
19 #include "gna_plugin/gna_memory.hpp"
20
21 using namespace GNAPluginNS;
22
23 class GNAMemoryTest : public ::testing::Test {
24
25  protected:
26     GNAMemory<std::allocator<uint8_t>> mem;
27
28     void SetUp() override  {
29     }
30 };
31
32 TEST_F(GNAMemoryTest, canStoreActualBlob){
33     float input [] = {1,2,3};
34     float* pFuture = nullptr;
35     size_t len = sizeof(input);
36
37     mem.push_ptr(&pFuture, input, len);
38     mem.commit();
39
40     ASSERT_NE(pFuture, nullptr);
41     ASSERT_NE(pFuture, input);
42     ASSERT_EQ(pFuture[0], 1);
43     ASSERT_EQ(pFuture[1], 2);
44     ASSERT_EQ(pFuture[2], 3);
45 }
46
47 TEST_F(GNAMemoryTest, canStore2Blobs) {
48     float input [] = {1,2,3,4};
49     float* pFuture = nullptr;
50     float* pFuture2 = nullptr;
51
52     mem.push_ptr(&pFuture, input, 3*4);
53     mem.push_ptr(&pFuture2, input+1, 3*4);
54     mem.commit();
55
56     ASSERT_NE(pFuture, input);
57     ASSERT_NE(pFuture2, input);
58     ASSERT_EQ(pFuture + 3, pFuture2);
59
60     ASSERT_EQ(pFuture[0], 1);
61     ASSERT_EQ(pFuture[1], 2);
62     ASSERT_EQ(pFuture[2], 3);
63     ASSERT_EQ(pFuture[3], 2);
64     ASSERT_EQ(pFuture[4], 3);
65     ASSERT_EQ(pFuture[5], 4);
66 }
67
68 TEST_F(GNAMemoryTest, canStoreBlobsALIGNED) {
69     float input [] = {1,2,3,4,5,6,7,8};
70     float* pFuture = nullptr;
71
72     mem.push_ptr(&pFuture, input, 3*4, 8);
73     mem.commit();
74
75     ASSERT_EQ(16 , mem.getTotalBytes());
76
77     ASSERT_NE(pFuture, input);
78     ASSERT_NE(pFuture, nullptr);
79
80     ASSERT_EQ(pFuture[0], 1);
81     ASSERT_EQ(pFuture[1], 2);
82     ASSERT_EQ(pFuture[2], 3);
83     //least probability for next element to be equal if not copied
84     ASSERT_NE(pFuture[3], 4);
85 }
86
87 TEST_F(GNAMemoryTest, canStore2BlobsALIGNED) {
88     float input [] = {1,2,3,4,5,6,7,8};
89     float* pFuture = nullptr;
90     float* pFuture2 = nullptr;
91
92     mem.push_ptr(&pFuture, input, 3*4, 8);
93     mem.push_ptr(&pFuture2, input, 3*4, 16);
94     mem.commit();
95
96     ASSERT_EQ(32 , mem.getTotalBytes());
97
98     ASSERT_NE(pFuture, nullptr);
99
100     ASSERT_EQ(pFuture[0], 1);
101     ASSERT_EQ(pFuture[1], 2);
102     ASSERT_EQ(pFuture[2], 3);
103     //least probability for next element to be equal if not copied
104     ASSERT_EQ(pFuture[4], 1);
105     ASSERT_EQ(pFuture[5], 2);
106     ASSERT_EQ(pFuture[6], 3);
107
108 }
109
110 TEST_F(GNAMemoryTest, canReserveData) {
111
112     float* pFuture = nullptr;
113     mem.reserve_ptr(&pFuture, 3*4);
114     mem.commit();
115
116     ASSERT_NE(pFuture, nullptr);
117 }
118
119 TEST_F(GNAMemoryTest, canReserveDataByVoid) {
120     mem.reserve_ptr(nullptr, 3*4);
121     ASSERT_NO_THROW(mem.commit());
122 }
123
124
125 TEST_F(GNAMemoryTest, canReserveAndPushData) {
126
127     float input[] = {1, 2, 3};
128     float *pFuture = nullptr;
129     float* pFuture2 = nullptr;
130     size_t len = sizeof(input) ;
131
132     mem.push_ptr(&pFuture, input, len);
133     mem.reserve_ptr(&pFuture2, 3*4);
134     mem.commit();
135
136     ASSERT_NE(pFuture, nullptr);
137     ASSERT_NE(pFuture2, nullptr);
138     ASSERT_NE(pFuture, input);
139     ASSERT_NE(pFuture2, pFuture);
140
141     pFuture2[0] = -1;
142     pFuture2[1] = -1;
143     pFuture2[2] = -1;
144
145     ASSERT_EQ(pFuture[0], 1);
146     ASSERT_EQ(pFuture[1], 2);
147     ASSERT_EQ(pFuture[2], 3);
148 }
149
150 TEST_F(GNAMemoryTest, canBindAndResolve) {
151
152     float input[] = {1, 2, 3};
153     float *pFuture = nullptr;
154     float *pFuture2 = nullptr;
155     float *pFuture3 = nullptr;
156     size_t len = sizeof(input);
157
158     mem.bind_ptr(&pFuture3, &pFuture);
159     mem.push_ptr(&pFuture, input, len);
160     mem.bind_ptr(&pFuture2, &pFuture);
161
162     mem.commit();
163
164     ASSERT_NE(pFuture, input);
165     ASSERT_NE(pFuture2, nullptr);
166     ASSERT_EQ(pFuture2, pFuture);
167     ASSERT_EQ(pFuture3, pFuture);
168
169     ASSERT_EQ(pFuture2[0], 1);
170     ASSERT_EQ(pFuture2[1], 2);
171     ASSERT_EQ(pFuture2[2], 3);
172 }
173
174 TEST_F(GNAMemoryTest, canBindTransitevlyAndResolve) {
175
176     float input[] = {1, 2, 3};
177     float *pFuture = nullptr;
178     float *pFuture3 = nullptr;
179     float *pFuture4 = nullptr;
180     size_t len = sizeof(input);
181
182     mem.bind_ptr(&pFuture4, &pFuture3);
183     mem.bind_ptr(&pFuture3, &pFuture);
184     mem.push_ptr(&pFuture, input, len);
185
186     mem.commit();
187
188     ASSERT_NE(pFuture, input);
189     ASSERT_EQ(pFuture3, pFuture);
190     ASSERT_EQ(pFuture4, pFuture);
191
192     ASSERT_NE(pFuture4, nullptr);
193
194     ASSERT_EQ(pFuture4[0], 1);
195     ASSERT_EQ(pFuture4[1], 2);
196     ASSERT_EQ(pFuture4[2], 3);
197 }
198
199 TEST_F(GNAMemoryTest, canBindTransitevlyWithOffsetsAndResolve) {
200
201     float input[] = {1, 2, 3};
202     float *pFuture = nullptr;
203     float *pFuture3 = nullptr;
204     float *pFuture4 = nullptr;
205     size_t len = sizeof(input);
206
207     mem.bind_ptr(&pFuture4, &pFuture3, 4);
208     mem.bind_ptr(&pFuture3, &pFuture, 4);
209     mem.push_ptr(&pFuture, input, len);
210
211     mem.commit();
212
213     ASSERT_NE(pFuture, input);
214     ASSERT_EQ(pFuture3, pFuture + 1);
215     ASSERT_EQ(pFuture4, pFuture + 2);
216
217     ASSERT_NE(pFuture, nullptr);
218
219     ASSERT_EQ(pFuture[0], 1);
220     ASSERT_EQ(pFuture[1], 2);
221     ASSERT_EQ(pFuture[2], 3);
222 }
223
224 TEST_F(GNAMemoryTest, canBindWithOffsetAndResolve) {
225
226     float input[] = {1, 2, 3};
227     float *pFuture = nullptr;
228     float *pFuture2 = nullptr;
229     float *pFuture3 = nullptr;
230     size_t len = sizeof(input);
231
232     mem.bind_ptr(&pFuture3, &pFuture, 4);
233     mem.push_ptr(&pFuture, input, len);
234     mem.bind_ptr(&pFuture2, &pFuture);
235
236     mem.commit();
237
238     ASSERT_NE(pFuture, input);
239     ASSERT_NE(pFuture2, nullptr);
240     ASSERT_EQ(pFuture2, pFuture);
241     ASSERT_NE(pFuture3, nullptr);
242     ASSERT_EQ(pFuture3, pFuture + 1);
243
244     ASSERT_EQ(pFuture2[0], 1);
245     ASSERT_EQ(pFuture2[1], 2);
246     ASSERT_EQ(pFuture2[2], 3);
247     ASSERT_EQ(pFuture3[0], 2);
248 }
249
250
251 TEST_F(GNAMemoryTest, canPushLocal) {
252
253     float* pFuture = (float*)&pFuture;
254
255     {
256         std::vector<float> input = {1.0f, 2.0f, 3.0f, 4.0f};
257         mem.push_local_ptr(pFuture, &*input.begin(), 4 * 4, 1);
258     }
259
260     //poison stack
261     float input [] = {11,21,31,41};
262     mem.commit();
263
264     ASSERT_FLOAT_EQ(pFuture[0], 1);
265     ASSERT_FLOAT_EQ(pFuture[1], 2);
266     ASSERT_FLOAT_EQ(pFuture[2], 3);
267     ASSERT_FLOAT_EQ(pFuture[3], 4);
268 }
269
270 TEST_F(GNAMemoryTest, canPushValue) {
271
272     float* pFuture = (float*)&pFuture;
273     float* pFuture2 = (float*)&pFuture2;
274
275     {
276         mem.push_value(pFuture, 3.f,  2);
277         mem.push_value(pFuture2, 13.f, 2);
278     }
279
280     mem.commit();
281
282     ASSERT_FLOAT_EQ(pFuture[0], 3);
283     ASSERT_FLOAT_EQ(pFuture[1], 3);
284     ASSERT_FLOAT_EQ(pFuture[2], 13);
285     ASSERT_FLOAT_EQ(pFuture[3], 13);
286 }
287
288 TEST_F(GNAMemoryTest, canPushReadOnlyValue) {
289
290     float* pFuture = (float*)&pFuture;
291     float* pFuture2 = (float*)&pFuture2;
292
293     {
294         mem.push_value(pFuture, 3.f,  2);
295         mem.readonly().push_value(pFuture2, 13.f, 2);
296     }
297
298     mem.commit();
299
300     ASSERT_FLOAT_EQ(pFuture[0], 3);
301     ASSERT_FLOAT_EQ(pFuture[1], 3);
302     ASSERT_FLOAT_EQ(pFuture[2], 13);
303     ASSERT_FLOAT_EQ(pFuture[3], 13);
304 }
305
306 TEST_F(GNAMemoryTest, canCalculateReadWriteSectionSize) {
307
308     mem.push_value(nullptr, 3.f,  2);
309     mem.readonly().push_value(nullptr, 13.f, 2);
310     mem.commit();
311
312     ASSERT_EQ(mem.getTotalBytes(), 4 * sizeof(float));
313     ASSERT_EQ(mem.getRWBytes(), 2 * sizeof(float));
314 }
315
316 TEST_F(GNAMemoryTest, canCalculateReadWriteSectionSizeWithAlignment) {
317
318     GNAMemory<std::allocator<uint8_t>> memAligned(64);
319
320     memAligned.push_value(nullptr, 3.f,  2);
321     memAligned.readonly().push_value(nullptr, 13.f, 2);
322     memAligned.commit();
323
324     ASSERT_EQ(memAligned.getTotalBytes(), 128);
325     ASSERT_EQ(memAligned.getRWBytes(), 64);
326 }
327
328 TEST_F(GNAMemoryTest, canSetUpReadWriteSectionPtr) {
329
330     float* pFuture2 = (float*)&pFuture2;
331     float* pFuture1 = (float*)&pFuture1;
332     float* pFuture3 = (float*)&pFuture3;
333
334
335     mem.readonly().push_value(pFuture1, 3.f,  2);
336     mem.push_value(pFuture2, 13.f, 3);
337     mem.readonly().push_value(pFuture3, 32.f,  4);
338     mem.commit();
339
340     ASSERT_EQ(mem.getTotalBytes(), (2+3+4) * sizeof(float));
341     ASSERT_EQ(mem.getRWBytes(), 3 * sizeof(float));
342
343     ASSERT_LT(&pFuture2[0], &pFuture1[0]);
344     ASSERT_LT(&pFuture1[0], &pFuture3[0]);
345
346     ASSERT_FLOAT_EQ(pFuture1[0], 3.f);
347     ASSERT_FLOAT_EQ(pFuture1[1], 3.f);
348
349     ASSERT_FLOAT_EQ(pFuture2[0], 13.f);
350     ASSERT_FLOAT_EQ(pFuture2[1], 13.f);
351     ASSERT_FLOAT_EQ(pFuture2[2], 13.f);
352
353     ASSERT_FLOAT_EQ(pFuture3[0], 32.f);
354     ASSERT_FLOAT_EQ(pFuture3[1], 32.f);
355     ASSERT_FLOAT_EQ(pFuture3[2], 32.f);
356     ASSERT_FLOAT_EQ(pFuture3[3], 32.f);
357 }
358
359
360 TEST_F(GNAMemoryTest, canUpdateSizeOfPushRequestWithBindRequest) {
361     float input[]  = {1, 2, 3};
362
363     float *pFuture = nullptr;
364     float *pFuture2 = nullptr;
365     float *pFuture3 = nullptr;
366
367     size_t len = sizeof(input);
368
369     mem.push_ptr(&pFuture, input, len);
370     mem.bind_ptr(&pFuture2, &pFuture, len, len);
371     mem.bind_ptr(&pFuture3, &pFuture2, 2 * len, len);
372
373     mem.commit();
374
375     ASSERT_EQ(mem.getTotalBytes(), 4 * len);
376     ASSERT_NE(pFuture, nullptr);
377     ASSERT_EQ(pFuture2, pFuture + 3);
378     ASSERT_EQ(pFuture3, pFuture + 9);
379
380     ASSERT_FLOAT_EQ(pFuture[0], 1);
381     ASSERT_FLOAT_EQ(pFuture[1], 2);
382     ASSERT_FLOAT_EQ(pFuture[2], 3);
383     ASSERT_FLOAT_EQ(pFuture[3], 0);
384     ASSERT_FLOAT_EQ(pFuture[4], 0);
385     ASSERT_FLOAT_EQ(pFuture[5], 0);
386     ASSERT_FLOAT_EQ(pFuture[6], 0);
387     ASSERT_FLOAT_EQ(pFuture[7], 0);
388     ASSERT_FLOAT_EQ(pFuture[8], 0);
389 }
390
391 TEST_F(GNAMemoryTest, canUpdateSizeOfPushRequestWithBindRequestWhenPush) {
392     float input[]  = {1, 2, 3};
393     float input2[]  = {6, 7, 8};
394
395     float *pFutureInput2 = nullptr;
396     float *pFuture = nullptr;
397     float *pFuture2 = nullptr;
398
399     size_t len = sizeof(input);
400
401     mem.push_ptr(&pFuture, input, len);
402     mem.bind_ptr(&pFuture2, &pFuture, len, len);
403     mem.push_ptr(&pFutureInput2, input2, len);
404
405     mem.commit();
406
407     ASSERT_EQ(mem.getTotalBytes(), 3 * len);
408     ASSERT_NE(pFuture, nullptr);
409     ASSERT_NE(pFutureInput2, nullptr);
410     ASSERT_EQ(pFuture2, pFuture + 3);
411
412     ASSERT_FLOAT_EQ(pFuture[0], 1);
413     ASSERT_FLOAT_EQ(pFuture[1], 2);
414     ASSERT_FLOAT_EQ(pFuture[2], 3);
415     ASSERT_FLOAT_EQ(pFuture[3], 0);
416     ASSERT_FLOAT_EQ(pFuture[4], 0);
417
418     ASSERT_FLOAT_EQ(pFutureInput2[0], 6);
419     ASSERT_FLOAT_EQ(pFutureInput2[1], 7);
420     ASSERT_FLOAT_EQ(pFutureInput2[2], 8);
421 }
422
423 TEST_F(GNAMemoryTest, canUpdateSizeOfPushRequestWithBindRequestWhenAlloc) {
424     float input[]  = {1, 2, 3};
425
426     float *pFutureInput = nullptr;
427     float *pFuture = nullptr;
428     float *pFuture2 = nullptr;
429
430     size_t len = sizeof(input);
431
432     mem.reserve_ptr(&pFuture, len);
433     mem.bind_ptr(&pFuture2, &pFuture, len, len);
434     mem.push_ptr(&pFutureInput, input, len);
435
436     mem.commit();
437
438     ASSERT_EQ(mem.getTotalBytes(), 3 * len);
439     ASSERT_NE(pFuture, nullptr);
440     ASSERT_NE(pFutureInput, nullptr);
441     ASSERT_EQ(pFuture2, pFuture + 3);
442
443     ASSERT_FLOAT_EQ(pFuture[0], 0);
444     ASSERT_FLOAT_EQ(pFuture[1], 0);
445     ASSERT_FLOAT_EQ(pFuture[2], 0);
446     ASSERT_FLOAT_EQ(pFuture[3], 0);
447     ASSERT_FLOAT_EQ(pFuture[4], 0);
448
449     ASSERT_FLOAT_EQ(pFutureInput[0], 1);
450     ASSERT_FLOAT_EQ(pFutureInput[1], 2);
451     ASSERT_FLOAT_EQ(pFutureInput[2], 3);
452 }