[Coverage] Increase function coverage
[platform/adaptation/npu/trix-engine.git] / tests / unittests / ne_core_data_test.cc
1 /**
2  * Proprietary
3  * Copyright (C) 2021 Samsung Electronics
4  * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
5  */
6 /**
7  * @file ne_core_data_test.cc
8  * @date 17 Feb 2021
9  * @brief UnitTests to test functionality of data converter
10  * @author Dongju Chae <dongju.chae@samsung.com>
11  * @bug No known bugs except for NYI items
12  */
13
14 #include <ne-data.h>
15 #include <ne-model.h>
16 #include "ne_unittest_utils.h"
17
18 #include <npubinfmt.h>
19 #include <cstdlib>
20
21 /**
22  * @brief Test checkCapability()
23  */
24 TEST (ne_core_data_test, check_capability) {
25   std::unique_ptr<DataConverter> converter (new DataConverter (true));
26   converter->setDataType (DATA_TYPE_QASYMM8, DATA_TYPE_QASYMM8);
27
28   converter->setDataLayout (DATA_LAYOUT_NHWC, DATA_LAYOUT_TRIV2);
29   EXPECT_TRUE (converter->checkCapability ());
30
31   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_NHWC);
32   EXPECT_TRUE (converter->checkCapability ());
33 }
34
35 /**
36  * @brief Test checkCapability() with negative cases
37  */
38 TEST (ne_core_data_test, check_capability_n) {
39   std::unique_ptr<DataConverter> converter (new DataConverter (true));
40
41   /* layouts are not resolved yet */
42   converter->setDataLayout (DATA_LAYOUT_MODEL, DATA_LAYOUT_MODEL);
43   EXPECT_FALSE (converter->checkCapability ());
44
45   /* types are not resolved yet */
46   converter->setDataLayout (DATA_LAYOUT_NHWC, DATA_LAYOUT_TRIV2);
47   converter->setDataType (DATA_TYPE_MODEL, DATA_TYPE_MODEL);
48   EXPECT_FALSE (converter->checkCapability ());
49
50   /* some layouts are not supported */
51   converter->setDataType (DATA_TYPE_QASYMM8, DATA_TYPE_QASYMM8);
52   converter->setDataLayout (DATA_LAYOUT_NCHW, DATA_LAYOUT_TRIV2);
53   EXPECT_FALSE (converter->checkCapability ());
54 }
55
56 /**
57  * @brief Test perform() with quantization (QASYMM8)
58  */
59 TEST (ne_core_data_test, perform_quantization_asymm8) {
60   std::unique_ptr<DataConverter> converter (new DataConverter (true));
61   uint16_t *src_data = new uint16_t[4096];
62   uint8_t *dst_data = new uint8_t[4096];
63   uint32_t data_dims[] = {1, 8, 8, 64};
64   uint32_t zero = 127;
65   float scale = 127.0;
66   double max = 255.0;
67   double min = 0.0;
68
69   converter->setData (src_data, dst_data, 4096 * 2);
70   converter->setDataDims (data_dims);
71   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
72   converter->setDataType (DATA_TYPE_UINT16, DATA_TYPE_QASYMM8);
73   converter->setQuantZero (zero);
74   converter->setQuantScale (scale);
75
76   /* fill any data */
77   for (int i = 0; i < 4096; i++) {
78     src_data[i] = rand () % UINT16_MAX;
79     dst_data[i] = 0;
80   }
81
82   EXPECT_EQ (converter->perform (), 4096 * 2);
83
84   /* check quantized value */
85   for (int i = 0; i < 4096; i++) {
86     double val = src_data[i];
87     val = val / scale;
88     val += zero;
89     val = (val > max) ? max : val;
90     val = (val < min) ? min : val;
91     EXPECT_EQ (dst_data[i], (uint8_t) val);
92   }
93
94   delete[] src_data;
95   delete[] dst_data;
96 }
97
98 /**
99  * @brief Test perform() with quantization (QSYMM16)
100  */
101 TEST (ne_core_data_test, perform_quantization_symm16) {
102   std::unique_ptr<DataConverter> converter (new DataConverter (true));
103   uint32_t *src_data = new uint32_t[4096];
104   int16_t *dst_data = new int16_t[4096];
105   uint32_t data_dims[] = {1, 8, 8, 64};
106   uint32_t zero = 0;
107   float scale = 127.0;
108   double max = 32767.0;
109   double min = -32768.0;
110
111   converter->setData (src_data, dst_data, 4096 * 4);
112   converter->setDataDims (data_dims);
113   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
114   converter->setDataType (DATA_TYPE_UINT32, DATA_TYPE_QSYMM16);
115   converter->setQuantZero (zero);
116   converter->setQuantScale (scale);
117
118   /* fill any data */
119   for (int i = 0; i < 4096; i++) {
120     src_data[i] = rand () % UINT32_MAX;
121     dst_data[i] = 0;
122   }
123
124   EXPECT_EQ (converter->perform (), 4096 * 4);
125
126   /* check quantized value */
127   for (int i = 0; i < 4096; i++) {
128     double val = src_data[i];
129     val = val / scale;
130     val += zero;
131     val = (val > max) ? max : val;
132     val = (val < min) ? min : val;
133     EXPECT_EQ (dst_data[i], (int16_t) val);
134   }
135
136   delete[] src_data;
137   delete[] dst_data;
138 }
139
140 /**
141  * @brief Test perform() with quantization (negative)
142  */
143 TEST (ne_core_data_test, perform_quantization_n) {
144   std::unique_ptr<DataConverter> converter (new DataConverter (true));
145   uint32_t *src_data = new uint32_t[4096];
146   int16_t *dst_data = new int16_t[4096];
147   uint32_t data_dims[] = {1, 8, 8, 64};
148   uint32_t zero = 0;
149   float scale = 0.0;
150
151   converter->setData (src_data, dst_data, 4096 * 4);
152   converter->setDataDims (data_dims);
153   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
154   converter->setDataType (DATA_TYPE_UINT32, DATA_TYPE_QSYMM16);
155   converter->setQuantZero (zero);
156   converter->setQuantScale (scale);
157
158   /* fill any data */
159   for (int i = 0; i < 4096; i++) {
160     src_data[i] = rand () % UINT32_MAX;
161     dst_data[i] = 0;
162   }
163
164   EXPECT_EQ (converter->perform (), 4096 * 4);
165
166   /* failed to quantize */
167   for (int i = 0; i < 4096; i++) {
168     EXPECT_EQ (dst_data[i], 0);
169   }
170
171   delete[] src_data;
172   delete[] dst_data;
173 }
174
175 /**
176  * @brief Test perform() with dequantization (QASYMM8)
177  */
178 TEST (ne_core_data_test, perform_dequantization_asymm8) {
179   std::unique_ptr<DataConverter> converter (new DataConverter (false));
180   uint8_t *src_data = new uint8_t[4096];
181   uint16_t *dst_data = new uint16_t[4096];
182   uint32_t data_dims[] = {1, 8, 8, 64};
183   uint32_t zero = 127;
184   float scale = 127.0;
185
186   converter->setData (src_data, dst_data, 4096);
187   converter->setDataDims (data_dims);
188   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
189   converter->setDataType (DATA_TYPE_QASYMM8, DATA_TYPE_UINT16);
190   converter->setQuantZero (zero);
191   converter->setQuantScale (scale);
192
193   /* fill any data */
194   for (int i = 0; i < 4096; i++) {
195     src_data[i] = rand () % UINT8_MAX;
196     dst_data[i] = 0;
197   }
198
199   EXPECT_EQ (converter->perform (), 4096);
200
201   /* check dequantized value */
202   for (int i = 0; i < 4096; i++) {
203     double val = src_data[i];
204     val -= zero;
205     val *= scale;
206     EXPECT_EQ (dst_data[i], (uint16_t) val);
207   }
208
209   delete[] src_data;
210   delete[] dst_data;
211 }
212
213 /**
214  * @brief Test perform() with dequantization (QSYMM16)
215  */
216 TEST (ne_core_data_test, perform_dequantization_symm16) {
217   std::unique_ptr<DataConverter> converter (new DataConverter (false));
218   int16_t *src_data = new int16_t[4096];
219   uint32_t *dst_data = new uint32_t[4096];
220   uint32_t data_dims[] = {1, 8, 8, 64};
221   uint32_t zero = 0;
222   float scale = 127.0;
223
224   converter->setData (src_data, dst_data, 4096 * 2);
225   converter->setDataDims (data_dims);
226   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
227   converter->setDataType (DATA_TYPE_QSYMM16, DATA_TYPE_UINT32);
228   converter->setQuantZero (zero);
229   converter->setQuantScale (scale);
230
231   /* fill any data */
232   for (int i = 0; i < 4096; i++) {
233     src_data[i] = rand () % INT16_MAX;
234     dst_data[i] = 0;
235   }
236
237   EXPECT_EQ (converter->perform (), 4096 * 2);
238
239   /* check dequantized value */
240   for (int i = 0; i < 4096; i++) {
241     double val = src_data[i];
242     val -= zero;
243     val *= scale;
244     EXPECT_EQ (dst_data[i], (int32_t) val);
245   }
246
247   delete[] src_data;
248   delete[] dst_data;
249 }
250
251 /**
252  * @brief Test perform() with layer conversion (QASYMM8)
253  */
254 TEST (ne_core_data_test, perform_layer_conversion_asymm8) {
255   std::unique_ptr<DataConverter> converter (new DataConverter (true));
256   uint8_t *src_data = new uint8_t[4096];
257   uint8_t *dst_data = new uint8_t[4096];
258   uint32_t data_dims[] = {1, 8, 8, 64};
259   uint32_t granularity = DATA_GRANULARITY;
260
261   converter->setData (src_data, dst_data, 4096);
262   converter->setDataDims (data_dims);
263   converter->setDataLayout (DATA_LAYOUT_NHWC, DATA_LAYOUT_TRIV2);
264   converter->setDataType (DATA_TYPE_QASYMM8, DATA_TYPE_QASYMM8);
265
266   /* fill any data */
267   for (int i = 0; i < 4096; i++) {
268     src_data[i] = rand () % UINT8_MAX;
269     dst_data[i] = 0;
270   }
271
272   EXPECT_EQ (converter->perform (), 4096);
273
274   /* check values */
275   EXPECT_EQ (memcmp (src_data, dst_data, 4096), 0);
276
277   /* 2-TOPS */
278   converter->setTops (2);
279   EXPECT_EQ (converter->perform (), 4096);
280
281   for (int i = 0; i < 4096; i += granularity) {
282     EXPECT_EQ (
283         memcmp (src_data + i, dst_data + (granularity / 2) * (i / granularity),
284                 granularity / 2),
285         0);
286     EXPECT_EQ (memcmp (src_data + i + (granularity / 2),
287                        dst_data + (granularity / 2) * (i / granularity) + 2048,
288                        granularity / 2),
289                0);
290   }
291
292   delete[] src_data;
293   delete[] dst_data;
294 }
295
296 /**
297  * @brief Test perform() with layer conversion (QSYMM16)
298  */
299 TEST (ne_core_data_test, perform_layer_conversion_symm16) {
300   std::unique_ptr<DataConverter> converter (new DataConverter (true));
301   int16_t *src_data = new int16_t[4096];
302   int16_t *dst_data = new int16_t[4096];
303   uint32_t data_dims[] = {1, 8, 8, 64};
304   uint32_t granularity = DATA_GRANULARITY;
305
306   converter->setData (src_data, dst_data, 4096 * 2);
307   converter->setDataDims (data_dims);
308   converter->setDataLayout (DATA_LAYOUT_NHWC, DATA_LAYOUT_TRIV2);
309   converter->setDataType (DATA_TYPE_QSYMM16, DATA_TYPE_QSYMM16);
310
311   /* fill any data */
312   for (int i = 0; i < 4096; i++) {
313     src_data[i] = rand () % INT16_MAX;
314     dst_data[i] = 0;
315   }
316
317   EXPECT_EQ (converter->perform (), 4096 * 2);
318
319   /* check values */
320   for (int i = 0; i < 4096; i += granularity) {
321     EXPECT_EQ (
322         memcmp (src_data + i, dst_data + (granularity / 2) * (i / granularity),
323                 granularity / 2),
324         0);
325     EXPECT_EQ (memcmp (src_data + i + (granularity / 2),
326                        dst_data + (granularity / 2) * (i / granularity) + 2048,
327                        granularity / 2),
328                0);
329   }
330
331   /* 2-TOPS */
332   converter->setTops (2);
333   EXPECT_EQ (converter->perform (), 4096 * 2);
334
335   for (int i = 0; i < 4096; i += granularity) {
336     EXPECT_EQ (
337         memcmp (src_data + i, dst_data + (granularity / 4) * (i / granularity),
338                 granularity / 4),
339         0);
340     EXPECT_EQ (memcmp (src_data + i + (granularity / 4),
341                        dst_data + (granularity / 4) * (i / granularity) + 1024,
342                        granularity / 4),
343                0);
344     EXPECT_EQ (memcmp (src_data + i + 2 * (granularity / 4),
345                        dst_data + (granularity / 4) * (i / granularity) + 2048,
346                        granularity / 4),
347                0);
348     EXPECT_EQ (memcmp (src_data + i + 3 * (granularity / 4),
349                        dst_data + (granularity / 4) * (i / granularity) + 3072,
350                        granularity / 4),
351                0);
352   }
353
354   delete[] src_data;
355   delete[] dst_data;
356 }
357
358 /**
359  * @brief Test perform() with negative cases
360  */
361 TEST (ne_core_data_test, perform_n) {
362   std::unique_ptr<DataConverter> converter (new DataConverter (true));
363   char *dummy_data = new char[4096];
364   uint32_t dummy_dims[] = {1, 1, 1, 4096};
365
366   /* invalid parameters */
367   converter->setData (nullptr, nullptr, 4096);
368   EXPECT_EQ (converter->perform (), 0);
369
370   converter->setData (dummy_data, nullptr, 4096);
371   EXPECT_EQ (converter->perform (), 0);
372
373   converter->setData (nullptr, dummy_data, 4096);
374   EXPECT_EQ (converter->perform (), 0);
375
376   converter->setData (dummy_data, dummy_data, 0);
377   EXPECT_EQ (converter->perform (), 0);
378
379   converter->setData (dummy_data, dummy_data, 4096);
380   converter->setDataDims (nullptr);
381   EXPECT_EQ (converter->perform (), 0);
382
383   /* still layout/types are not resolved */
384   converter->setDataDims (dummy_dims);
385   EXPECT_EQ (converter->perform (), 0);
386
387   delete[] dummy_data;
388 }
389
390 /**
391  * @brief Test quantize() with various types (dummy)
392  */
393 TEST (ne_core_data_test, dummy_quantize) {
394   data_type npu_types[] = {DATA_TYPE_SRNPU, DATA_TYPE_QASYMM8,
395                            DATA_TYPE_QSYMM16};
396   data_type std_types[] = {
397       DATA_TYPE_INT8,    DATA_TYPE_UINT8,  DATA_TYPE_INT16, DATA_TYPE_UINT16,
398       DATA_TYPE_INT32,   DATA_TYPE_UINT32, DATA_TYPE_INT64, DATA_TYPE_UINT64,
399       DATA_TYPE_FLOAT32, DATA_TYPE_FLOAT64};
400   uint32_t data_dims[] = {1, 1, 1, 1024};
401
402   void *src_data = malloc (4096);
403   void *dst_data = malloc (4096);
404
405   ASSERT_NE (src_data, nullptr);
406   ASSERT_NE (dst_data, nullptr);
407
408   /* std to npu */
409   std::unique_ptr<DataConverter> converter (new DataConverter (true));
410
411   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
412   converter->setDataDims (data_dims);
413   converter->setTops (2);
414   converter->setQuantZero (127);
415   converter->setQuantScale (1.0);
416
417   for (auto &s : std_types) {
418     converter->setData (src_data, dst_data, get_data_size (s));
419     for (auto &n : npu_types) {
420       converter->setDataType (s, n);
421       converter->perform ();
422     }
423   }
424
425   /* npu to std */
426   converter.reset (new DataConverter (false));
427
428   converter->setDataLayout (DATA_LAYOUT_TRIV2, DATA_LAYOUT_TRIV2);
429   converter->setDataDims (data_dims);
430   converter->setTops (2);
431   converter->setQuantZero (127);
432   converter->setQuantScale (1.0);
433
434   for (auto &n : npu_types) {
435     converter->setData (src_data, dst_data, get_data_size (n));
436     for (auto &s : std_types) {
437       converter->setDataType (n, s);
438       converter->perform ();
439     }
440   }
441
442   free (src_data);
443   free (dst_data);
444 }
445
446 /**
447  * @brief main function for unit test
448  */
449 int
450 main (int argc, char **argv) {
451   return start_gtest (argc, argv);
452 }