[Bug] Fix memory access error in addValue
[platform/core/ml/nntrainer.git] / test / unittest / jni / tests / unittest_nntrainer_tensor.cpp
1 // SPDX-License-Identifier: Apache-2.0
2 /**
3  * Copyright (C) 2020 Jijoong Moon <jijoong.moon@samsung.com>
4  *
5  * @file        unittest_nntrainer_tensor.cpp
6  * @date        03 June 2020
7  * @brief       Unit test utility for tensor.
8  * @see         https://github.com/nnstreamer/nntrainer
9  * @author      Jijoong Moon <jijoong.moon@samsung.com>
10  * @bug         No known bugs
11  */
12 #include <gtest/gtest.h>
13
14 #include "nntrainer_test_util.h"
15 #include "util_func.h"
16 #include <fstream>
17 #include <nntrainer_error.h>
18 #include <tensor.h>
19 #include <tensor_dim.h>
20 #include <iostream>
21
22 TEST(nntrainer_TensorDim, ctor_initializer_p) {
23   unsigned int b = 3;
24   unsigned int c = 2;
25   unsigned int h = 4;
26   unsigned int w = 5;
27
28   nntrainer::TensorDim t = {w};
29   EXPECT_EQ(nntrainer::TensorDim(1, 1, 1, w), t);
30
31   t = {h, w};
32   EXPECT_EQ(nntrainer::TensorDim(1, 1, h, w), t);
33
34   t = {c, h, w};
35   EXPECT_EQ(nntrainer::TensorDim(1, c, h, w), t);
36
37   t = {b, c, h, w};
38   EXPECT_EQ(nntrainer::TensorDim(b, c, h, w), t);
39 }
40
41 TEST(nntrainer_TensorDim, ctor_initializer_nhwc_p) {
42   unsigned int b = 3;
43   unsigned int c = 2;
44   unsigned int h = 4;
45   unsigned int w = 5;
46
47   nntrainer::TensorDim t = {c};
48   EXPECT_EQ(nntrainer::TensorDim(1, 1, 1, c), t);
49
50   t = {w, c};
51   EXPECT_EQ(nntrainer::TensorDim(1, 1, w, c), t);
52
53   t = {h, w, c};
54   EXPECT_EQ(nntrainer::TensorDim(1, h, w, c), t);
55
56   t = {b, h, w, c};
57   EXPECT_EQ(nntrainer::TensorDim(b, h, w, c), t);
58 }
59
60 TEST(nntrianer_TensorDim, effective_dimension_p) {
61   nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NCHW);
62   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
63
64   t.setEffDimFlag(0b1101);
65   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 5}));
66
67   t.setEffDimFlag(0b0011);
68   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({4, 5}));
69
70   t.setEffDimFlag(0b1111);
71   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
72
73   t.setEffDimFlag(0b1100);
74   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2}));
75
76   t.setDynDimFlag(0b1100);
77   EXPECT_EQ(t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
78
79   auto copied_t = t;
80   EXPECT_EQ(copied_t.getEffectiveDimension(), std::vector<int>({3, 2}));
81   EXPECT_EQ(copied_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
82
83   auto moved_t = std::move(copied_t);
84   EXPECT_EQ(moved_t.getEffectiveDimension(), std::vector<int>({3, 2}));
85   EXPECT_EQ(moved_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
86 }
87
88 TEST(nntrianer_TensorDim, effective_dimension_nhwc_p) {
89   nntrainer::TensorDim t(3, 2, 4, 5, nntrainer::Tformat::NHWC);
90   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
91
92   t.setEffDimFlag(0b1101);
93   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 5}));
94
95   t.setEffDimFlag(0b0011);
96   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({4, 5}));
97
98   t.setEffDimFlag(0b1111);
99   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2, 4, 5}));
100
101   t.setEffDimFlag(0b1100);
102   EXPECT_EQ(t.getEffectiveDimension(), std::vector<int>({3, 2}));
103
104   t.setDynDimFlag(0b1100);
105   EXPECT_EQ(t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
106
107   auto copied_t = t;
108   EXPECT_EQ(copied_t.getEffectiveDimension(), std::vector<int>({3, 2}));
109   EXPECT_EQ(copied_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
110
111   auto moved_t = std::move(copied_t);
112   EXPECT_EQ(moved_t.getEffectiveDimension(), std::vector<int>({3, 2}));
113   EXPECT_EQ(moved_t.getEffectiveDimension(true), std::vector<int>({-1, -1}));
114 }
115
116 TEST(nntrainer_TensorDim, ctor_initializer_n) {
117   EXPECT_THROW(nntrainer::TensorDim t({1, 2, 3, 4, 5}), std::invalid_argument);
118 }
119
120 TEST(nntrainer_TensorDim, ctor_initializer_nhwc_n) {
121   EXPECT_THROW(
122     nntrainer::TensorDim t({1, 2, 3, 4, 5}, nntrainer::Tformat::NHWC),
123     std::invalid_argument);
124 }
125
126 TEST(nntrainer_TensorDim, setTensorDim_01_p) {
127   int status = ML_ERROR_NONE;
128
129   nntrainer::TensorDim tensor_dim;
130   status = tensor_dim.setTensorDim("1:2:3:4");
131   EXPECT_EQ(status, ML_ERROR_NONE);
132 }
133
134 TEST(nntrainer_TensorDim, setTensorDim_01_nhwc_p) {
135   int status = ML_ERROR_NONE;
136
137   nntrainer::TensorDim tensor_dim;
138   status = tensor_dim.setTensorDim("1:2:3:4", nntrainer::Tformat::NHWC);
139   EXPECT_EQ(status, ML_ERROR_NONE);
140 }
141
142 TEST(nntrainer_TensorDim, setTensorDim_02_n) {
143   int status = ML_ERROR_NONE;
144
145   nntrainer::TensorDim tensor_dim;
146   status = tensor_dim.setTensorDim("1:2:3:4:5");
147   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
148 }
149
150 TEST(nntrainer_TensorDim, setTensorDim_02__nhwc_n) {
151   int status = ML_ERROR_NONE;
152
153   nntrainer::TensorDim tensor_dim;
154   status = tensor_dim.setTensorDim("1:2:3:4:5", nntrainer::Tformat::NHWC);
155   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
156 }
157
158 TEST(nntrainer_TensorDim, setTensorDim_03_n) {
159   nntrainer::TensorDim d;
160
161   EXPECT_THROW(d.setTensorDim(0, 0), std::invalid_argument);
162   EXPECT_THROW(d.setTensorDim(1, 0), std::invalid_argument);
163   EXPECT_THROW(d.setTensorDim(2, 0), std::invalid_argument);
164   EXPECT_THROW(d.setTensorDim(3, 0), std::invalid_argument);
165 }
166
167 TEST(nntrainer_TensorDim, setTensorDim_03_nhwc_n) {
168   nntrainer::TensorDim d(nntrainer::Tformat::NHWC);
169
170   EXPECT_THROW(d.setTensorDim(0, 0), std::invalid_argument);
171   EXPECT_THROW(d.setTensorDim(1, 0), std::invalid_argument);
172   EXPECT_THROW(d.setTensorDim(2, 0), std::invalid_argument);
173   EXPECT_THROW(d.setTensorDim(3, 0), std::invalid_argument);
174 }
175
176 TEST(nntrainer_TensorDim, setTensorDim_04_p) {
177   nntrainer::TensorDim d;
178
179   d.setTensorDim(0, 4);
180   d.setTensorDim(1, 5);
181   d.setTensorDim(2, 6);
182   d.setTensorDim(3, 7);
183
184   EXPECT_EQ(d.batch(), 4u);
185   EXPECT_EQ(d.channel(), 5u);
186   EXPECT_EQ(d.height(), 6u);
187   EXPECT_EQ(d.width(), 7u);
188 }
189
190 TEST(nntrainer_TensorDim, setTensorDim_04_nhwc_p) {
191   nntrainer::TensorDim d(nntrainer::Tformat::NHWC);
192
193   d.setTensorDim(0, 4);
194   d.setTensorDim(1, 5);
195   d.setTensorDim(2, 6);
196   d.setTensorDim(3, 7);
197
198   EXPECT_EQ(d.batch(), 4u);
199   EXPECT_EQ(d.height(), 5u);
200   EXPECT_EQ(d.width(), 6u);
201   EXPECT_EQ(d.channel(), 7u);
202 }
203
204 TEST(nntrainer_Tensor, Tensor_01_p) {
205   int status = ML_ERROR_NONE;
206   nntrainer::Tensor tensor = nntrainer::Tensor(1, 2, 3);
207   tensor.setZero();
208   ASSERT_NE(nullptr, tensor.getData());
209   if (tensor.getValue(0, 0, 0, 0) != 0.0)
210     status = ML_ERROR_INVALID_PARAMETER;
211   EXPECT_EQ(status, ML_ERROR_NONE);
212 }
213
214 TEST(nntrainer_Tensor, Tensor_01_nhwc_p) {
215   int status = ML_ERROR_NONE;
216   nntrainer::Tensor tensor =
217     nntrainer::Tensor(1, 2, 3, nntrainer::Tformat::NHWC);
218   tensor.setZero();
219   ASSERT_NE(nullptr, tensor.getData());
220   if (tensor.getValue(0, 0, 0, 0) != 0.0)
221     status = ML_ERROR_INVALID_PARAMETER;
222   EXPECT_EQ(status, ML_ERROR_NONE);
223 }
224
225 TEST(nntrainer_Tensor, Tensor_02_p) {
226   int status = ML_ERROR_NONE;
227   int height = 3;
228   int width = 10;
229   std::vector<std::vector<float>> in;
230   for (int i = 0; i < height; ++i) {
231     std::vector<float> tv;
232     for (int j = 0; j < width; ++j) {
233       tv.push_back(i * 2.0 + j);
234     }
235     in.push_back(tv);
236   }
237
238   nntrainer::Tensor tensor = nntrainer::Tensor(in);
239   ASSERT_NE(nullptr, tensor.getData<float>());
240
241   if (tensor.getValue<float>(0, 0, 0, 1) != 1.0)
242     status = ML_ERROR_INVALID_PARAMETER;
243   EXPECT_EQ(status, ML_ERROR_NONE);
244 }
245
246 TEST(nntrainer_Tensor, Tensor_03_p) {
247   int status = ML_ERROR_NONE;
248   int batch = 3;
249   int height = 3;
250   int width = 10;
251   std::vector<std::vector<std::vector<float>>> in;
252   for (int k = 0; k < batch; ++k) {
253     std::vector<std::vector<float>> ttv;
254     for (int i = 0; i < height; ++i) {
255       std::vector<float> tv;
256       for (int j = 0; j < width; ++j) {
257         tv.push_back(k * height * width + i * width + j);
258       }
259       ttv.push_back(tv);
260     }
261     in.push_back(ttv);
262   }
263
264   nntrainer::Tensor tensor = nntrainer::Tensor(in);
265   ASSERT_NE(nullptr, tensor.getData());
266
267   if (tensor.getValue(0, 0, 0, 1) != 1.0)
268     status = ML_ERROR_INVALID_PARAMETER;
269   EXPECT_EQ(status, ML_ERROR_NONE);
270 }
271
272 TEST(nntrainer_Tensor, multiply_i_01_p) {
273   int status = ML_ERROR_NONE;
274   int batch = 3;
275   int channel = 1;
276   int height = 3;
277   int width = 10;
278
279   nntrainer::Tensor input(batch, channel, height, width);
280   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
281
282   nntrainer::Tensor original;
283   original.copy(input);
284
285   status = input.multiply_i(2.0);
286   EXPECT_EQ(status, ML_ERROR_NONE);
287
288   float *data = original.getData();
289   ASSERT_NE(nullptr, data);
290   float *indata = input.getData();
291   ASSERT_NE(nullptr, indata);
292
293   for (int i = 0; i < batch * height * width * channel; ++i) {
294     EXPECT_FLOAT_EQ(data[i] + data[i], indata[i]);
295   }
296 }
297
298 TEST(nntrainer_Tensor, multiply_i_02_p) {
299   int status = ML_ERROR_NONE;
300   int batch = 3;
301   int channel = 1;
302   int height = 3;
303   int width = 10;
304
305   nntrainer::Tensor input(batch, channel, height, width);
306   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
307
308   nntrainer::Tensor original;
309   original.copy(input);
310
311   status = input.multiply_i(input);
312   EXPECT_EQ(status, ML_ERROR_NONE);
313
314   float *data = original.getData();
315   ASSERT_NE(nullptr, data);
316   float *indata = input.getData();
317   ASSERT_NE(nullptr, indata);
318
319   for (int i = 0; i < batch * height * width * channel; ++i) {
320     EXPECT_FLOAT_EQ(data[i] * data[i], indata[i]);
321   }
322 }
323
324 TEST(nntrainer_Tensor, multiply_i_03_n) {
325   int status = ML_ERROR_NONE;
326   int batch = 3;
327   int channel = 1;
328   int height = 3;
329   int width = 10;
330
331   nntrainer::Tensor input(batch, channel, height, width);
332   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
333
334   nntrainer::Tensor target2(batch, channel, height - 2, width - 1);
335   status = input.multiply_i(target2);
336
337   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
338 }
339
340 TEST(nntrainer_Tensor, multiply_i_broadcast_01_p) {
341   {
342     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
343     nntrainer::Tensor t = ranged(3, 2, 4, 5);
344     nntrainer::Tensor m = ranged(1, 2, 4, 5);
345     float answer_data[] = {
346       0,    1,    4,    9,    16,   25,   36,   49,   64,   81,   100,  121,
347       144,  169,  196,  225,  256,  289,  324,  361,  400,  441,  484,  529,
348       576,  625,  676,  729,  784,  841,  900,  961,  1024, 1089, 1156, 1225,
349       1296, 1369, 1444, 1521, 0,    41,   84,   129,  176,  225,  276,  329,
350       384,  441,  500,  561,  624,  689,  756,  825,  896,  969,  1044, 1121,
351       1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201,
352       2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 0,    81,   164,  249,
353       336,  425,  516,  609,  704,  801,  900,  1001, 1104, 1209, 1316, 1425,
354       1536, 1649, 1764, 1881, 2000, 2121, 2244, 2369, 2496, 2625, 2756, 2889,
355       3024, 3161, 3300, 3441, 3584, 3729, 3876, 4025, 4176, 4329, 4484, 4641};
356     nntrainer::Tensor answer(ref_dim, answer_data);
357     int status = t.multiply_i(m);
358     EXPECT_EQ(status, ML_ERROR_NONE);
359     EXPECT_EQ(t, answer);
360   }
361   {
362     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
363     nntrainer::Tensor t = ranged(3, 2, 4, 5);
364     nntrainer::Tensor m = ranged(3, 1, 4, 5);
365     float answer_data[] = {
366       0,    1,    4,    9,    16,   25,   36,   49,   64,   81,   100,  121,
367       144,  169,  196,  225,  256,  289,  324,  361,  0,    21,   44,   69,
368       96,   125,  156,  189,  224,  261,  300,  341,  384,  429,  476,  525,
369       576,  629,  684,  741,  800,  861,  924,  989,  1056, 1125, 1196, 1269,
370       1344, 1421, 1500, 1581, 1664, 1749, 1836, 1925, 2016, 2109, 2204, 2301,
371       1200, 1281, 1364, 1449, 1536, 1625, 1716, 1809, 1904, 2001, 2100, 2201,
372       2304, 2409, 2516, 2625, 2736, 2849, 2964, 3081, 3200, 3321, 3444, 3569,
373       3696, 3825, 3956, 4089, 4224, 4361, 4500, 4641, 4784, 4929, 5076, 5225,
374       5376, 5529, 5684, 5841, 4000, 4141, 4284, 4429, 4576, 4725, 4876, 5029,
375       5184, 5341, 5500, 5661, 5824, 5989, 6156, 6325, 6496, 6669, 6844, 7021};
376     nntrainer::Tensor answer(ref_dim, answer_data);
377     int status = t.multiply_i(m);
378     EXPECT_EQ(status, ML_ERROR_NONE);
379     EXPECT_EQ(t, answer);
380   }
381   {
382     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
383     nntrainer::Tensor t = ranged(3, 2, 4, 5);
384     nntrainer::Tensor m = ranged(3, 2, 4, 1);
385     float answer_data[] = {
386       0,    0,    0,    0,    0,    5,    6,    7,    8,    9,    20,   22,
387       24,   26,   28,   45,   48,   51,   54,   57,   80,   84,   88,   92,
388       96,   125,  130,  135,  140,  145,  180,  186,  192,  198,  204,  245,
389       252,  259,  266,  273,  320,  328,  336,  344,  352,  405,  414,  423,
390       432,  441,  500,  510,  520,  530,  540,  605,  616,  627,  638,  649,
391       720,  732,  744,  756,  768,  845,  858,  871,  884,  897,  980,  994,
392       1008, 1022, 1036, 1125, 1140, 1155, 1170, 1185, 1280, 1296, 1312, 1328,
393       1344, 1445, 1462, 1479, 1496, 1513, 1620, 1638, 1656, 1674, 1692, 1805,
394       1824, 1843, 1862, 1881, 2000, 2020, 2040, 2060, 2080, 2205, 2226, 2247,
395       2268, 2289, 2420, 2442, 2464, 2486, 2508, 2645, 2668, 2691, 2714, 2737};
396     nntrainer::Tensor answer(ref_dim, answer_data);
397     int status = t.multiply_i(m);
398     EXPECT_EQ(status, ML_ERROR_NONE);
399     EXPECT_EQ(t, answer);
400   }
401   {
402     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
403     nntrainer::Tensor t = ranged(3, 2, 4, 5);
404     nntrainer::Tensor m = ranged(3, 1, 1, 5);
405     float answer_data[] = {
406       0,    1,    4,    9,    16,   0,    6,    14,   24,   36,   0,    11,
407       24,   39,   56,   0,    16,   34,   54,   76,   0,    21,   44,   69,
408       96,   0,    26,   54,   84,   116,  0,    31,   64,   99,   136,  0,
409       36,   74,   114,  156,  200,  246,  294,  344,  396,  225,  276,  329,
410       384,  441,  250,  306,  364,  424,  486,  275,  336,  399,  464,  531,
411       300,  366,  434,  504,  576,  325,  396,  469,  544,  621,  350,  426,
412       504,  584,  666,  375,  456,  539,  624,  711,  800,  891,  984,  1079,
413       1176, 850,  946,  1044, 1144, 1246, 900,  1001, 1104, 1209, 1316, 950,
414       1056, 1164, 1274, 1386, 1000, 1111, 1224, 1339, 1456, 1050, 1166, 1284,
415       1404, 1526, 1100, 1221, 1344, 1469, 1596, 1150, 1276, 1404, 1534, 1666};
416     nntrainer::Tensor answer(ref_dim, answer_data);
417     int status = t.multiply_i(m);
418     EXPECT_EQ(status, ML_ERROR_NONE);
419     EXPECT_EQ(t, answer);
420   }
421   {
422     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
423     nntrainer::Tensor t = ranged(3, 2, 4, 5);
424     nntrainer::Tensor m = ranged(1, 2, 1, 5);
425     float answer_data[] = {
426       0,   1,   4,    9,   16,  0,   6,   14,  24,  36,  0,   11,  24,  39,
427       56,  0,   16,   34,  54,  76,  100, 126, 154, 184, 216, 125, 156, 189,
428       224, 261, 150,  186, 224, 264, 306, 175, 216, 259, 304, 351, 0,   41,
429       84,  129, 176,  0,   46,  94,  144, 196, 0,   51,  104, 159, 216, 0,
430       56,  114, 174,  236, 300, 366, 434, 504, 576, 325, 396, 469, 544, 621,
431       350, 426, 504,  584, 666, 375, 456, 539, 624, 711, 0,   81,  164, 249,
432       336, 0,   86,   174, 264, 356, 0,   91,  184, 279, 376, 0,   96,  194,
433       294, 396, 500,  606, 714, 824, 936, 525, 636, 749, 864, 981, 550, 666,
434       784, 904, 1026, 575, 696, 819, 944, 1071};
435     nntrainer::Tensor answer(ref_dim, answer_data);
436     int status = t.multiply_i(m);
437     EXPECT_EQ(status, ML_ERROR_NONE);
438     EXPECT_EQ(t, answer);
439   }
440   {
441     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
442     nntrainer::Tensor t = ranged(3, 2, 4, 5);
443     nntrainer::Tensor m = ranged(3, 1, 4, 1);
444     float answer_data[] = {
445       0,    0,    0,    0,    0,    5,    6,    7,    8,    9,    20,   22,
446       24,   26,   28,   45,   48,   51,   54,   57,   0,    0,    0,    0,
447       0,    25,   26,   27,   28,   29,   60,   62,   64,   66,   68,   105,
448       108,  111,  114,  117,  160,  164,  168,  172,  176,  225,  230,  235,
449       240,  245,  300,  306,  312,  318,  324,  385,  392,  399,  406,  413,
450       240,  244,  248,  252,  256,  325,  330,  335,  340,  345,  420,  426,
451       432,  438,  444,  525,  532,  539,  546,  553,  640,  648,  656,  664,
452       672,  765,  774,  783,  792,  801,  900,  910,  920,  930,  940,  1045,
453       1056, 1067, 1078, 1089, 800,  808,  816,  824,  832,  945,  954,  963,
454       972,  981,  1100, 1110, 1120, 1130, 1140, 1265, 1276, 1287, 1298, 1309};
455     nntrainer::Tensor answer(ref_dim, answer_data);
456     int status = t.multiply_i(m);
457     EXPECT_EQ(status, ML_ERROR_NONE);
458     EXPECT_EQ(t, answer);
459   }
460   {
461     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
462     nntrainer::Tensor t = ranged(3, 2, 4, 5);
463     nntrainer::Tensor m = ranged(1, 1, 1, 5);
464     float answer_data[] = {
465       0, 1,   4,   9,   16,  0, 6,   14,  24,  36,  0, 11,  24,  39,  56,
466       0, 16,  34,  54,  76,  0, 21,  44,  69,  96,  0, 26,  54,  84,  116,
467       0, 31,  64,  99,  136, 0, 36,  74,  114, 156, 0, 41,  84,  129, 176,
468       0, 46,  94,  144, 196, 0, 51,  104, 159, 216, 0, 56,  114, 174, 236,
469       0, 61,  124, 189, 256, 0, 66,  134, 204, 276, 0, 71,  144, 219, 296,
470       0, 76,  154, 234, 316, 0, 81,  164, 249, 336, 0, 86,  174, 264, 356,
471       0, 91,  184, 279, 376, 0, 96,  194, 294, 396, 0, 101, 204, 309, 416,
472       0, 106, 214, 324, 436, 0, 111, 224, 339, 456, 0, 116, 234, 354, 476};
473     nntrainer::Tensor answer(ref_dim, answer_data);
474     int status = t.multiply_i(m);
475     EXPECT_EQ(status, ML_ERROR_NONE);
476     EXPECT_EQ(t, answer);
477   }
478   {
479     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
480     nntrainer::Tensor t = ranged(3, 2, 4, 5);
481     nntrainer::Tensor m = ranged(1, 2, 1, 1);
482     float answer_data[] = {
483       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
484       0,   0,   0,   0,   0,   0,   20,  21,  22,  23,  24,  25,  26,  27,
485       28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  0,   0,
486       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
487       0,   0,   0,   0,   60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
488       70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  0,   0,   0,   0,
489       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
490       0,   0,   100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
491       112, 113, 114, 115, 116, 117, 118, 119};
492     nntrainer::Tensor answer(ref_dim, answer_data);
493     int status = t.multiply_i(m);
494     EXPECT_EQ(status, ML_ERROR_NONE);
495     EXPECT_EQ(t, answer);
496   }
497   {
498     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
499     nntrainer::Tensor t = ranged(3, 2, 4, 5);
500     nntrainer::Tensor m = ranged(3, 1, 1, 1);
501     float answer_data[] = {
502       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
503       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
504       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   40,  41,
505       42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
506       56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
507       70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  160, 162, 164, 166,
508       168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194,
509       196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
510       224, 226, 228, 230, 232, 234, 236, 238};
511     nntrainer::Tensor answer(ref_dim, answer_data);
512     int status = t.multiply_i(m);
513     EXPECT_EQ(status, ML_ERROR_NONE);
514     EXPECT_EQ(t, answer);
515   }
516   {
517     nntrainer::TensorDim ref_dim(3, 5, 1, 4);
518     nntrainer::Tensor t = ranged(3, 5, 1, 4);
519     nntrainer::Tensor m = ranged(3, 1, 1, 4);
520     float answer_data[] = {0,   1,   4,   9,   0,   5,   12,  21,  0,   9,
521                            20,  33,  0,   13,  28,  45,  0,   17,  36,  57,
522                            80,  105, 132, 161, 96,  125, 156, 189, 112, 145,
523                            180, 217, 128, 165, 204, 245, 144, 185, 228, 273,
524                            320, 369, 420, 473, 352, 405, 460, 517, 384, 441,
525                            500, 561, 416, 477, 540, 605, 448, 513, 580, 649};
526     nntrainer::Tensor answer(ref_dim, answer_data);
527     int status = t.multiply_i(m);
528     EXPECT_EQ(status, ML_ERROR_NONE);
529     EXPECT_EQ(t, answer);
530   }
531 }
532
533 TEST(nntrainer_Tensor, multiply_i_broadcast_not_supported_01_n) {
534   nntrainer::Tensor target(3, 1, 3, 1);
535   nntrainer::Tensor target2(3, 1, 3, 3);
536
537   EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER);
538 }
539
540 TEST(nntrainer_Tensor, multiply_i_broadcast_not_broadcastable_02_n) {
541   nntrainer::Tensor target(3, 2, 4, 5);
542   nntrainer::Tensor target2(3, 2, 3, 1);
543
544   EXPECT_EQ(target.multiply_i(target2), ML_ERROR_INVALID_PARAMETER);
545 }
546
547 TEST(nntrainer_Tensor, multiply_01_p) {
548   int status = ML_ERROR_NONE;
549   int batch = 3;
550   int channel = 1;
551   int height = 3;
552   int width = 10;
553
554   nntrainer::Tensor input(batch, channel, height, width);
555   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
556
557   nntrainer::Tensor result = input.multiply(0.0);
558   if (result.getValue(0, 0, 1, 1) != 0.0)
559     status = ML_ERROR_RESULT_OUT_OF_RANGE;
560   EXPECT_EQ(status, ML_ERROR_NONE);
561 }
562
563 TEST(nntrainer_Tensor, multiply_02_p) {
564   int status = ML_ERROR_NONE;
565   int batch = 3;
566   int channel = 1;
567   int height = 3;
568   int width = 10;
569
570   nntrainer::Tensor input(batch, channel, height, width);
571   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
572
573   nntrainer::Tensor result = input.multiply(input);
574
575   float *data = result.getData();
576   ASSERT_NE(nullptr, data);
577   float *indata = input.getData();
578   ASSERT_NE(nullptr, indata);
579
580   for (int i = 0; i < batch * height * width; ++i) {
581     if (data[i] != indata[i] * indata[i]) {
582       status = ML_ERROR_RESULT_OUT_OF_RANGE;
583       break;
584     }
585   }
586
587   EXPECT_EQ(status, ML_ERROR_NONE);
588 }
589
590 TEST(nntrainer_Tensor, multiply_03_n) {
591   int batch = 3;
592   int channel = 1;
593   int height = 3;
594   int width = 10;
595
596   nntrainer::Tensor input(batch, channel, height, width);
597   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
598
599   nntrainer::Tensor test(batch - 1, height - 1, width - 1);
600
601   EXPECT_THROW({ input.multiply(test); }, std::invalid_argument);
602 }
603
604 TEST(nntrainer_Tensor, multiply_04_n) {
605   int batch = 3;
606   int channel = 1;
607   int height = 3;
608   int width = 10;
609
610   nntrainer::TensorDim dim(batch, channel, height, width);
611
612   nntrainer::Tensor input(batch, channel, height, 2 * width);
613   nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false);
614   nntrainer::Tensor test(dim);
615
616   EXPECT_THROW(shared_input.multiply(test), std::invalid_argument);
617 }
618
619 TEST(nntrainer_Tensor, multiply_05_n) {
620   int batch = 3;
621   int channel = 1;
622   int height = 3;
623   int width = 10;
624
625   nntrainer::TensorDim dim(batch, channel, height, width);
626
627   nntrainer::Tensor input(dim);
628   nntrainer::Tensor test(batch, channel, height, 2 * width);
629   nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false);
630
631   EXPECT_THROW(input.multiply(shared_test), std::invalid_argument);
632 }
633
634 TEST(nntrainer_Tensor, multiply_06_n) {
635   int batch = 3;
636   int channel = 1;
637   int height = 3;
638   int width = 10;
639
640   nntrainer::TensorDim dim(batch, channel, height, width);
641
642   nntrainer::Tensor input(dim, false);
643   nntrainer::Tensor test(dim);
644   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1);
645
646   EXPECT_THROW(input.multiply(test), std::invalid_argument);
647 }
648
649 TEST(nntrainer_Tensor, multiply_07_n) {
650   int batch = 3;
651   int channel = 1;
652   int height = 3;
653   int width = 10;
654
655   nntrainer::TensorDim dim(batch, channel, height, width);
656
657   nntrainer::Tensor input(dim);
658   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
659   nntrainer::Tensor test(dim, false);
660
661   EXPECT_THROW(input.multiply(test), std::invalid_argument);
662 }
663
664 TEST(nntrainer_Tensor, multiply_08_n) {
665   int batch = 3;
666   int channel = 1;
667   int height = 3;
668   int width = 10;
669
670   nntrainer::TensorDim dim(batch, channel, height, width);
671
672   nntrainer::Tensor input(dim);
673   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
674   nntrainer::Tensor test(dim);
675   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2);
676   nntrainer::Tensor output(dim, false);
677
678   EXPECT_THROW(input.multiply(test, output), std::invalid_argument);
679 }
680
681 TEST(nntrainer_Tensor, multiply_float_01_p) {
682   int batch = 3;
683   int channel = 1;
684   int height = 3;
685   int width = 10;
686
687   nntrainer::Tensor input(batch, channel, height, width);
688   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
689
690   nntrainer::Tensor expected(batch, channel, height, width);
691   GEN_TEST_INPUT(expected, (i * (batch * height) + j * (width) + k + 1) * 2);
692
693   nntrainer::Tensor result = input.multiply(2.0);
694
695   EXPECT_EQ(result, expected);
696 }
697
698 TEST(nntrainer_Tensor, divide_i_01_p) {
699   int status = ML_ERROR_NONE;
700   int batch = 3;
701   int channel = 1;
702   int height = 3;
703   int width = 10;
704
705   nntrainer::Tensor input(batch, channel, height, width);
706   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
707
708   nntrainer::Tensor original;
709   original.copy(input);
710
711   status = input.divide_i((float)2.0);
712   EXPECT_EQ(status, ML_ERROR_NONE);
713
714   float *data = original.getData();
715   ASSERT_NE(nullptr, data);
716   float *indata = input.getData();
717   ASSERT_NE(nullptr, indata);
718
719   for (int i = 0; i < batch * height * width * channel; ++i) {
720     EXPECT_FLOAT_EQ(data[i], indata[i] + indata[i]);
721   }
722 }
723
724 TEST(nntrainer_Tensor, divide_i_02_p) {
725   int status = ML_ERROR_NONE;
726   int batch = 3;
727   int channel = 1;
728   int height = 3;
729   int width = 10;
730
731   nntrainer::Tensor input(batch, channel, height, width);
732   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
733
734   status = input.divide_i(input);
735   EXPECT_EQ(status, ML_ERROR_NONE);
736   float *indata = input.getData();
737   ASSERT_NE(nullptr, indata);
738
739   for (int i = 0; i < batch * height * width * channel; ++i) {
740     EXPECT_FLOAT_EQ(indata[i], float(1.0));
741   }
742 }
743
744 TEST(nntrainer_Tensor, divide_i_01_n) {
745   int status = ML_ERROR_NONE;
746   int batch = 3;
747   int channel = 1;
748   int height = 3;
749   int width = 10;
750
751   nntrainer::Tensor input(batch, channel, height, width);
752   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
753
754   status = input.divide_i((float)0);
755   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
756 }
757
758 TEST(nntrainer_Tensor, divide_i_02_n) {
759   int status = ML_ERROR_NONE;
760   int batch = 3;
761   int channel = 1;
762   int height = 3;
763   int width = 10;
764
765   nntrainer::Tensor input(batch, channel, height, width);
766   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
767
768   nntrainer::Tensor original(batch, channel, height - 2, width - 1);
769
770   status = input.divide_i(original);
771   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
772 }
773
774 TEST(nntrainer_Tensor, divide_01_p) {
775   int batch = 3;
776   int channel = 1;
777   int height = 3;
778   int width = 10;
779
780   nntrainer::Tensor input(batch, channel, height, width);
781   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
782
783   nntrainer::Tensor result = input.divide(1.0);
784
785   float *previous = input.getData();
786   ASSERT_NE(nullptr, previous);
787   float *data = result.getData();
788   ASSERT_NE(nullptr, data);
789
790   for (int i = 0; i < batch * height * width * channel; ++i) {
791     EXPECT_FLOAT_EQ(data[i], previous[i]);
792   }
793 }
794
795 TEST(nntrainer_Tensor, divide_02_n) {
796   int batch = 3;
797   int channel = 1;
798   int height = 3;
799   int width = 10;
800
801   nntrainer::Tensor input(batch, channel, height, width);
802   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
803
804   EXPECT_THROW({ input.divide(0.0); }, std::invalid_argument);
805 }
806
807 TEST(nntrainer_Tensor, divide_03_n) {
808   int batch = 3;
809   int channel = 1;
810   int height = 3;
811   int width = 10;
812
813   nntrainer::Tensor input(batch, channel, height, width);
814   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
815
816   nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1);
817
818   EXPECT_THROW({ input.divide(test); }, std::invalid_argument);
819 }
820
821 TEST(nntrainer_Tensor, divide_04_n) {
822   int batch = 3;
823   int channel = 1;
824   int height = 3;
825   int width = 10;
826
827   nntrainer::TensorDim dim(batch, channel, height, width);
828
829   nntrainer::Tensor input(batch, channel, height, 2 * width);
830   nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false);
831   nntrainer::Tensor test(dim);
832
833   EXPECT_THROW(shared_input.divide(test), std::invalid_argument);
834 }
835
836 TEST(nntrainer_Tensor, divide_05_n) {
837   int batch = 3;
838   int channel = 1;
839   int height = 3;
840   int width = 10;
841
842   nntrainer::TensorDim dim(batch, channel, height, width);
843
844   nntrainer::Tensor input(dim);
845   nntrainer::Tensor test(batch, channel, height, 2 * width);
846   nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false);
847
848   EXPECT_THROW(input.divide(shared_test), std::invalid_argument);
849 }
850
851 TEST(nntrainer_Tensor, divide_06_n) {
852   int batch = 3;
853   int channel = 1;
854   int height = 3;
855   int width = 10;
856
857   nntrainer::TensorDim dim(batch, channel, height, width);
858
859   nntrainer::Tensor input(dim, false);
860   nntrainer::Tensor test(dim);
861   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1);
862
863   EXPECT_THROW(input.divide(test), std::invalid_argument);
864 }
865
866 TEST(nntrainer_Tensor, divide_07_n) {
867   int batch = 3;
868   int channel = 1;
869   int height = 3;
870   int width = 10;
871
872   nntrainer::TensorDim dim(batch, channel, height, width);
873
874   nntrainer::Tensor input(dim);
875   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
876   nntrainer::Tensor test(dim, false);
877
878   EXPECT_THROW(input.divide(test), std::invalid_argument);
879 }
880
881 TEST(nntrainer_Tensor, divide_08_n) {
882   int batch = 3;
883   int channel = 1;
884   int height = 3;
885   int width = 10;
886
887   nntrainer::TensorDim dim(batch, channel, height, width);
888
889   nntrainer::Tensor input(dim);
890   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
891   nntrainer::Tensor test(dim);
892   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2);
893   nntrainer::Tensor output(dim, false);
894
895   EXPECT_THROW(input.divide(test, output), std::invalid_argument);
896 }
897
898 TEST(nntrainer_Tensor, divide_i_broadcast_01_p) {
899   {
900     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
901     nntrainer::Tensor t = ranged(3, 2, 4, 5);
902     t.add_i(1);
903     nntrainer::Tensor m = ranged(1, 2, 4, 5);
904     m.add_i(1);
905     float answer_data[] = {
906       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
907       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
908       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
909       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
910       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
911       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
912       1.0,       1.0,       1.0,       1.0,       41.0,      21.0,
913       14.333333, 11.0,      9.0,       7.6666665, 6.714286,  6.0,
914       5.4444447, 5.0,       4.6363635, 4.3333335, 4.076923,  3.857143,
915       3.6666667, 3.5,       3.3529413, 3.2222223, 3.1052632, 3.0,
916       2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6,       2.5384614,
917       2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25,
918       2.2121212, 2.1764705, 2.142857,  2.1111112, 2.0810812, 2.0526316,
919       2.025641,  2.0,       81.0,      41.0,      27.666666, 21.0,
920       17.0,      14.333333, 12.428572, 11.0,      9.888889,  9.0,
921       8.272727,  7.6666665, 7.1538463, 6.714286,  6.3333335, 6.0,
922       5.7058825, 5.4444447, 5.2105265, 5.0,       4.8095236, 4.6363635,
923       4.478261,  4.3333335, 4.2,       4.076923,  3.9629629, 3.857143,
924       3.7586207, 3.6666667, 3.580645,  3.5,       3.4242425, 3.3529413,
925       3.2857144, 3.2222223, 3.162162,  3.1052632, 3.0512822, 3.0};
926     nntrainer::Tensor answer(ref_dim, answer_data);
927     int status = t.divide_i(m);
928     EXPECT_EQ(status, ML_ERROR_NONE);
929     EXPECT_EQ(t, answer);
930   }
931   {
932     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
933     nntrainer::Tensor t = ranged(3, 2, 4, 5);
934     t.add_i(1);
935     nntrainer::Tensor m = ranged(3, 1, 4, 5);
936     m.add_i(1);
937     float answer_data[] = {
938       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
939       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
940       1.0,       1.0,       1.0,       1.0,       1.0,       1.0,
941       1.0,       1.0,       21.0,      11.0,      7.6666665, 6.0,
942       5.0,       4.3333335, 3.857143,  3.5,       3.2222223, 3.0,
943       2.8181818, 2.6666667, 2.5384614, 2.4285715, 2.3333333, 2.25,
944       2.1764705, 2.1111112, 2.0526316, 2.0,       1.9523809, 1.9090909,
945       1.8695652, 1.8333334, 1.8,       1.7692307, 1.7407408, 1.7142857,
946       1.6896552, 1.6666666, 1.6451613, 1.625,     1.6060606, 1.5882353,
947       1.5714285, 1.5555556, 1.5405406, 1.5263158, 1.5128205, 1.5,
948       2.9047618, 2.8181818, 2.7391305, 2.6666667, 2.6,       2.5384614,
949       2.4814816, 2.4285715, 2.3793104, 2.3333333, 2.2903225, 2.25,
950       2.2121212, 2.1764705, 2.142857,  2.1111112, 2.0810812, 2.0526316,
951       2.025641,  2.0,       1.9756098, 1.9523809, 1.9302325, 1.9090909,
952       1.8888888, 1.8695652, 1.8510638, 1.8333334, 1.8163265, 1.8,
953       1.7843137, 1.7692307, 1.754717,  1.7407408, 1.7272727, 1.7142857,
954       1.7017543, 1.6896552, 1.6779661, 1.6666666, 2.4634147, 2.4285715,
955       2.3953488, 2.3636363, 2.3333333, 2.3043478, 2.2765958, 2.25,
956       2.2244897, 2.2,       2.1764705, 2.1538463, 2.1320755, 2.1111112,
957       2.090909,  2.0714285, 2.0526316, 2.0344827, 2.0169492, 2.0};
958     nntrainer::Tensor answer(ref_dim, answer_data);
959     int status = t.divide_i(m);
960     EXPECT_EQ(status, ML_ERROR_NONE);
961     EXPECT_EQ(t, answer);
962   }
963   {
964     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
965     nntrainer::Tensor t = ranged(3, 2, 4, 5);
966     t.add_i(1);
967     nntrainer::Tensor m = ranged(3, 2, 4, 1);
968     m.add_i(1);
969     float answer_data[] = {
970       1.0,       2.0,       3.0,       4.0,       5.0,       3.0,
971       3.5,       4.0,       4.5,       5.0,       3.6666667, 4.0,
972       4.3333335, 4.6666665, 5.0,       4.0,       4.25,      4.5,
973       4.75,      5.0,       4.2,       4.4,       4.6,       4.8,
974       5.0,       4.3333335, 4.5,       4.6666665, 4.8333335, 5.0,
975       4.428571,  4.571429,  4.714286,  4.857143,  5.0,       4.5,
976       4.625,     4.75,      4.875,     5.0,       4.5555553, 4.6666665,
977       4.7777777, 4.888889,  5.0,       4.6,       4.7,       4.8,
978       4.9,       5.0,       4.6363635, 4.7272725, 4.818182,  4.909091,
979       5.0,       4.6666665, 4.75,      4.8333335, 4.9166665, 5.0,
980       4.6923075, 4.769231,  4.8461537, 4.923077,  5.0,       4.714286,
981       4.785714,  4.857143,  4.928571,  5.0,       4.733333,  4.8,
982       4.866667,  4.9333334, 5.0,       4.75,      4.8125,    4.875,
983       4.9375,    5.0,       4.7647057, 4.8235292, 4.882353,  4.9411764,
984       5.0,       4.7777777, 4.8333335, 4.888889,  4.9444447, 5.0,
985       4.7894735, 4.8421054, 4.894737,  4.9473686, 5.0,       4.8,
986       4.85,      4.9,       4.95,      5.0,       4.8095236, 4.857143,
987       4.904762,  4.952381,  5.0,       4.818182,  4.8636365, 4.909091,
988       4.9545455, 5.0,       4.826087,  4.869565,  4.9130435, 4.9565215,
989       5.0,       4.8333335, 4.875,     4.9166665, 4.9583335, 5.0};
990     nntrainer::Tensor answer(ref_dim, answer_data);
991     int status = t.divide_i(m);
992     EXPECT_EQ(status, ML_ERROR_NONE);
993     EXPECT_EQ(t, answer);
994   }
995   {
996     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
997     nntrainer::Tensor t = ranged(3, 2, 4, 5);
998     t.add_i(1);
999     nntrainer::Tensor m = ranged(3, 1, 1, 5);
1000     m.add_i(1);
1001     float answer_data[] = {
1002       1.0,       1.0,       1.0,       1.0,       1.0,       6.0,
1003       3.5,       2.6666667, 2.25,      2.0,       11.0,      6.0,
1004       4.3333335, 3.5,       3.0,       16.0,      8.5,       6.0,
1005       4.75,      4.0,       21.0,      11.0,      7.6666665, 6.0,
1006       5.0,       26.0,      13.5,      9.333333,  7.25,      6.0,
1007       31.0,      16.0,      11.0,      8.5,       7.0,       36.0,
1008       18.5,      12.666667, 9.75,      8.0,       6.8333335, 6.0,
1009       5.375,     4.888889,  4.5,       7.6666665, 6.714286,  6.0,
1010       5.4444447, 5.0,       8.5,       7.428571,  6.625,     6.0,
1011       5.5,       9.333333,  8.142858,  7.25,      6.5555553, 6.0,
1012       10.166667, 8.857142,  7.875,     7.111111,  6.5,       11.0,
1013       9.571428,  8.5,       7.6666665, 7.0,       11.833333, 10.285714,
1014       9.125,     8.222222,  7.5,       12.666667, 11.0,      9.75,
1015       8.777778,  8.0,       7.3636365, 6.8333335, 6.3846154, 6.0,
1016       5.6666665, 7.818182,  7.25,      6.769231,  6.357143,  6.0,
1017       8.272727,  7.6666665, 7.1538463, 6.714286,  6.3333335, 8.727273,
1018       8.083333,  7.5384617, 7.071429,  6.6666665, 9.181818,  8.5,
1019       7.923077,  7.428571,  7.0,       9.636364,  8.916667,  8.307693,
1020       7.785714,  7.3333335, 10.090909, 9.333333,  8.692307,  8.142858,
1021       7.6666665, 10.545455, 9.75,      9.076923,  8.5,       8.0};
1022     nntrainer::Tensor answer(ref_dim, answer_data);
1023     int status = t.divide_i(m);
1024     EXPECT_EQ(status, ML_ERROR_NONE);
1025     EXPECT_EQ(t, answer);
1026   }
1027   {
1028     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
1029     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1030     t.add_i(1);
1031     nntrainer::Tensor m = ranged(1, 2, 1, 5);
1032     m.add_i(1);
1033     float answer_data[] = {
1034       1.0,       1.0,       1.0,       1.0,       1.0,       6.0,
1035       3.5,       2.6666667, 2.25,      2.0,       11.0,      6.0,
1036       4.3333335, 3.5,       3.0,       16.0,      8.5,       6.0,
1037       4.75,      4.0,       3.5,       3.142857,  2.875,     2.6666667,
1038       2.5,       4.3333335, 3.857143,  3.5,       3.2222223, 3.0,
1039       5.1666665, 4.571429,  4.125,     3.7777777, 3.5,       6.0,
1040       5.285714,  4.75,      4.3333335, 4.0,       41.0,      21.0,
1041       14.333333, 11.0,      9.0,       46.0,      23.5,      16.0,
1042       12.25,     10.0,      51.0,      26.0,      17.666666, 13.5,
1043       11.0,      56.0,      28.5,      19.333334, 14.75,     12.0,
1044       10.166667, 8.857142,  7.875,     7.111111,  6.5,       11.0,
1045       9.571428,  8.5,       7.6666665, 7.0,       11.833333, 10.285714,
1046       9.125,     8.222222,  7.5,       12.666667, 11.0,      9.75,
1047       8.777778,  8.0,       81.0,      41.0,      27.666666, 21.0,
1048       17.0,      86.0,      43.5,      29.333334, 22.25,     18.0,
1049       91.0,      46.0,      31.0,      23.5,      19.0,      96.0,
1050       48.5,      32.666668, 24.75,     20.0,      16.833334, 14.571428,
1051       12.875,    11.555555, 10.5,      17.666666, 15.285714, 13.5,
1052       12.111111, 11.0,      18.5,      16.0,      14.125,    12.666667,
1053       11.5,      19.333334, 16.714285, 14.75,     13.222222, 12.0};
1054     nntrainer::Tensor answer(ref_dim, answer_data);
1055     int status = t.divide_i(m);
1056     EXPECT_EQ(status, ML_ERROR_NONE);
1057     EXPECT_EQ(t, answer);
1058   }
1059   {
1060     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
1061     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1062     t.add_i(1);
1063     nntrainer::Tensor m = ranged(3, 1, 4, 1);
1064     m.add_i(1);
1065     float answer_data[] = {
1066       1.0,       2.0,       3.0,       4.0,       5.0,       3.0,
1067       3.5,       4.0,       4.5,       5.0,       3.6666667, 4.0,
1068       4.3333335, 4.6666665, 5.0,       4.0,       4.25,      4.5,
1069       4.75,      5.0,       21.0,      22.0,      23.0,      24.0,
1070       25.0,      13.0,      13.5,      14.0,      14.5,      15.0,
1071       10.333333, 10.666667, 11.0,      11.333333, 11.666667, 9.0,
1072       9.25,      9.5,       9.75,      10.0,      8.2,       8.4,
1073       8.6,       8.8,       9.0,       7.6666665, 7.8333335, 8.0,
1074       8.166667,  8.333333,  7.285714,  7.428571,  7.571429,  7.714286,
1075       7.857143,  7.0,       7.125,     7.25,      7.375,     7.5,
1076       12.2,      12.4,      12.6,      12.8,      13.0,      11.0,
1077       11.166667, 11.333333, 11.5,      11.666667, 10.142858, 10.285714,
1078       10.428572, 10.571428, 10.714286, 9.5,       9.625,     9.75,
1079       9.875,     10.0,      9.0,       9.111111,  9.222222,  9.333333,
1080       9.444445,  8.6,       8.7,       8.8,       8.9,       9.0,
1081       8.272727,  8.363636,  8.454545,  8.545455,  8.636364,  8.0,
1082       8.083333,  8.166667,  8.25,      8.333333,  11.222222, 11.333333,
1083       11.444445, 11.555555, 11.666667, 10.6,      10.7,      10.8,
1084       10.9,      11.0,      10.090909, 10.181818, 10.272727, 10.363636,
1085       10.454545, 9.666667,  9.75,      9.833333,  9.916667,  10.0};
1086     nntrainer::Tensor answer(ref_dim, answer_data);
1087     int status = t.divide_i(m);
1088     EXPECT_EQ(status, ML_ERROR_NONE);
1089     EXPECT_EQ(t, answer);
1090   }
1091   {
1092     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
1093     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1094     t.add_i(1);
1095     nntrainer::Tensor m = ranged(1, 1, 1, 5);
1096     m.add_i(1);
1097     float answer_data[] = {
1098       1.0,   1.0,  1.0,       1.0,  1.0,  6.0,   3.5,  2.6666667, 2.25,  2.0,
1099       11.0,  6.0,  4.3333335, 3.5,  3.0,  16.0,  8.5,  6.0,       4.75,  4.0,
1100       21.0,  11.0, 7.6666665, 6.0,  5.0,  26.0,  13.5, 9.333333,  7.25,  6.0,
1101       31.0,  16.0, 11.0,      8.5,  7.0,  36.0,  18.5, 12.666667, 9.75,  8.0,
1102       41.0,  21.0, 14.333333, 11.0, 9.0,  46.0,  23.5, 16.0,      12.25, 10.0,
1103       51.0,  26.0, 17.666666, 13.5, 11.0, 56.0,  28.5, 19.333334, 14.75, 12.0,
1104       61.0,  31.0, 21.0,      16.0, 13.0, 66.0,  33.5, 22.666666, 17.25, 14.0,
1105       71.0,  36.0, 24.333334, 18.5, 15.0, 76.0,  38.5, 26.0,      19.75, 16.0,
1106       81.0,  41.0, 27.666666, 21.0, 17.0, 86.0,  43.5, 29.333334, 22.25, 18.0,
1107       91.0,  46.0, 31.0,      23.5, 19.0, 96.0,  48.5, 32.666668, 24.75, 20.0,
1108       101.0, 51.0, 34.333332, 26.0, 21.0, 106.0, 53.5, 36.0,      27.25, 22.0,
1109       111.0, 56.0, 37.666668, 28.5, 23.0, 116.0, 58.5, 39.333332, 29.75, 24.0};
1110     nntrainer::Tensor answer(ref_dim, answer_data);
1111     int status = t.divide_i(m);
1112     EXPECT_EQ(status, ML_ERROR_NONE);
1113     EXPECT_EQ(t, answer);
1114   }
1115   {
1116     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
1117     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1118     t.add_i(1);
1119     nntrainer::Tensor m = ranged(1, 2, 1, 1);
1120     m.add_i(1);
1121     float answer_data[] = {
1122       1.0,  2.0,  3.0,  4.0,   5.0,  6.0,  7.0,  8.0,  9.0,  10.0, 11.0, 12.0,
1123       13.0, 14.0, 15.0, 16.0,  17.0, 18.0, 19.0, 20.0, 10.5, 11.0, 11.5, 12.0,
1124       12.5, 13.0, 13.5, 14.0,  14.5, 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0,
1125       18.5, 19.0, 19.5, 20.0,  41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0,
1126       49.0, 50.0, 51.0, 52.0,  53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0,
1127       30.5, 31.0, 31.5, 32.0,  32.5, 33.0, 33.5, 34.0, 34.5, 35.0, 35.5, 36.0,
1128       36.5, 37.0, 37.5, 38.0,  38.5, 39.0, 39.5, 40.0, 81.0, 82.0, 83.0, 84.0,
1129       85.0, 86.0, 87.0, 88.0,  89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0,
1130       97.0, 98.0, 99.0, 100.0, 50.5, 51.0, 51.5, 52.0, 52.5, 53.0, 53.5, 54.0,
1131       54.5, 55.0, 55.5, 56.0,  56.5, 57.0, 57.5, 58.0, 58.5, 59.0, 59.5, 60.0};
1132     nntrainer::Tensor answer(ref_dim, answer_data);
1133     int status = t.divide_i(m);
1134     EXPECT_EQ(status, ML_ERROR_NONE);
1135     EXPECT_EQ(t, answer);
1136   }
1137   {
1138     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
1139     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1140     t.add_i(1);
1141     nntrainer::Tensor m = ranged(3, 1, 1, 1);
1142     m.add_i(1);
1143     float answer_data[] = {
1144       1.0,       2.0,       3.0,  4.0,       5.0,       6.0,
1145       7.0,       8.0,       9.0,  10.0,      11.0,      12.0,
1146       13.0,      14.0,      15.0, 16.0,      17.0,      18.0,
1147       19.0,      20.0,      21.0, 22.0,      23.0,      24.0,
1148       25.0,      26.0,      27.0, 28.0,      29.0,      30.0,
1149       31.0,      32.0,      33.0, 34.0,      35.0,      36.0,
1150       37.0,      38.0,      39.0, 40.0,      20.5,      21.0,
1151       21.5,      22.0,      22.5, 23.0,      23.5,      24.0,
1152       24.5,      25.0,      25.5, 26.0,      26.5,      27.0,
1153       27.5,      28.0,      28.5, 29.0,      29.5,      30.0,
1154       30.5,      31.0,      31.5, 32.0,      32.5,      33.0,
1155       33.5,      34.0,      34.5, 35.0,      35.5,      36.0,
1156       36.5,      37.0,      37.5, 38.0,      38.5,      39.0,
1157       39.5,      40.0,      27.0, 27.333334, 27.666666, 28.0,
1158       28.333334, 28.666666, 29.0, 29.333334, 29.666666, 30.0,
1159       30.333334, 30.666666, 31.0, 31.333334, 31.666666, 32.0,
1160       32.333332, 32.666668, 33.0, 33.333332, 33.666668, 34.0,
1161       34.333332, 34.666668, 35.0, 35.333332, 35.666668, 36.0,
1162       36.333332, 36.666668, 37.0, 37.333332, 37.666668, 38.0,
1163       38.333332, 38.666668, 39.0, 39.333332, 39.666668, 40.0};
1164     nntrainer::Tensor answer(ref_dim, answer_data);
1165     int status = t.divide_i(m);
1166     EXPECT_EQ(status, ML_ERROR_NONE);
1167     EXPECT_EQ(t, answer);
1168   }
1169   {
1170     nntrainer::TensorDim ref_dim(3, 5, 1, 4);
1171     nntrainer::Tensor t = ranged(3, 5, 1, 4);
1172     t.add_i(1);
1173     nntrainer::Tensor m = ranged(3, 1, 1, 4);
1174     m.add_i(1);
1175     float answer_data[] = {
1176       1.0,       1.0,       1.0,       1.0,       5.0,       3.0,
1177       2.3333333, 2.0,       9.0,       5.0,       3.6666667, 3.0,
1178       13.0,      7.0,       5.0,       4.0,       17.0,      9.0,
1179       6.3333335, 5.0,       4.2,       3.6666667, 3.2857144, 3.0,
1180       5.0,       4.3333335, 3.857143,  3.5,       5.8,       5.0,
1181       4.428571,  4.0,       6.6,       5.6666665, 5.0,       4.5,
1182       7.4,       6.3333335, 5.571429,  5.0,       4.5555553, 4.2,
1183       3.909091,  3.6666667, 5.0,       4.6,       4.2727275, 4.0,
1184       5.4444447, 5.0,       4.6363635, 4.3333335, 5.888889,  5.4,
1185       5.0,       4.6666665, 6.3333335, 5.8,       5.3636365, 5.0};
1186     nntrainer::Tensor answer(ref_dim, answer_data);
1187     int status = t.divide_i(m);
1188     EXPECT_EQ(status, ML_ERROR_NONE);
1189     EXPECT_EQ(t, answer);
1190   }
1191 }
1192
1193 TEST(nntrainer_Tensor, divide_i_broadcast_not_supported_01_n) {
1194   nntrainer::Tensor target(3, 1, 3, 1);
1195   nntrainer::Tensor target2(3, 1, 3, 3);
1196
1197   EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER);
1198 }
1199
1200 TEST(nntrainer_Tensor, divide_i_broadcast_not_broadcastable_02_n) {
1201   nntrainer::Tensor target(3, 2, 4, 5);
1202   nntrainer::Tensor target2(3, 2, 3, 1);
1203
1204   EXPECT_EQ(target.divide_i(target2), ML_ERROR_INVALID_PARAMETER);
1205 }
1206
1207 TEST(nntrainer_Tensor, add_i_01_p) {
1208   int status = ML_ERROR_NONE;
1209   int batch = 3;
1210   int height = 3;
1211   int width = 10;
1212   int channel = 1;
1213
1214   nntrainer::Tensor target(batch, channel, height, width);
1215   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel);
1216
1217   nntrainer::Tensor original(batch, channel, height, width);
1218   original.copy(target);
1219
1220   status = target.add_i(2.1);
1221   EXPECT_EQ(status, ML_ERROR_NONE);
1222
1223   float *previous = original.getData();
1224   ASSERT_NE(nullptr, previous);
1225   float *data = target.getData();
1226   ASSERT_NE(nullptr, data);
1227
1228   for (int i = 0; i < batch * height * width; ++i) {
1229     EXPECT_FLOAT_EQ(data[i], previous[i] + (float)2.1);
1230   }
1231 }
1232
1233 TEST(nntrainer_Tensor, add_i_02_p) {
1234   int status = ML_ERROR_NONE;
1235   int batch = 3;
1236   int height = 3;
1237   int width = 10;
1238   int channel = 1;
1239
1240   nntrainer::Tensor target(batch, channel, height, width);
1241   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1);
1242
1243   nntrainer::Tensor original(batch, height, width);
1244   original.copy(target);
1245
1246   status = target.add_i(target, 3.0);
1247   EXPECT_EQ(status, ML_ERROR_NONE);
1248
1249   float *previous = original.getData();
1250   ASSERT_NE(nullptr, previous);
1251   float *data = target.getData();
1252   ASSERT_NE(nullptr, data);
1253
1254   for (int i = 0; i < batch * height * width; ++i) {
1255     EXPECT_FLOAT_EQ(data[i], previous[i] * 4.0);
1256   }
1257 }
1258
1259 /**
1260  * @brief operand dimension is not right
1261  */
1262 TEST(nntrainer_Tensor, add_i_01_n) {
1263   int status = ML_ERROR_NONE;
1264   int batch = 3;
1265   int height = 3;
1266   int width = 10;
1267   int channel = 1;
1268
1269   nntrainer::Tensor target(batch, channel, height, width);
1270   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1);
1271
1272   nntrainer::Tensor target2(batch, height - 2, width - 3);
1273
1274   status = target.add_i(target2);
1275   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
1276 }
1277
1278 TEST(nntrainer_Tensor, add_i_broadcast_01_p) {
1279   nntrainer::TensorDim ref_dim{3, 2, 4, 5};
1280   {
1281     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1282     nntrainer::Tensor m = ranged(1, 2, 4, 5);
1283     float answer_data[] = {
1284       0,   2,   4,   6,   8,   10,  12,  14,  16,  18,  20,  22,  24,  26,
1285       28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,
1286       56,  58,  60,  62,  64,  66,  68,  70,  72,  74,  76,  78,  40,  42,
1287       44,  46,  48,  50,  52,  54,  56,  58,  60,  62,  64,  66,  68,  70,
1288       72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98,
1289       100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 80,  82,  84,  86,
1290       88,  90,  92,  94,  96,  98,  100, 102, 104, 106, 108, 110, 112, 114,
1291       116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142,
1292       144, 146, 148, 150, 152, 154, 156, 158};
1293     nntrainer::Tensor answer(ref_dim, answer_data);
1294     int status = t.add_i(m);
1295     EXPECT_EQ(status, ML_ERROR_NONE);
1296     EXPECT_EQ(t, answer);
1297   }
1298   {
1299     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1300     nntrainer::Tensor m = ranged(3, 1, 4, 5);
1301     float answer_data[] = {
1302       0,   2,   4,   6,   8,   10,  12,  14,  16,  18,  20,  22,  24,  26,
1303       28,  30,  32,  34,  36,  38,  20,  22,  24,  26,  28,  30,  32,  34,
1304       36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62,
1305       64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,
1306       92,  94,  96,  98,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98,
1307       100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
1308       128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154,
1309       156, 158, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162,
1310       164, 166, 168, 170, 172, 174, 176, 178};
1311     nntrainer::Tensor answer(ref_dim, answer_data);
1312     int status = t.add_i(m);
1313     EXPECT_EQ(status, ML_ERROR_NONE);
1314     EXPECT_EQ(t, answer);
1315   }
1316   {
1317     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1318     nntrainer::Tensor m = ranged(3, 2, 4, 1);
1319     float answer_data[] = {
1320       0,   1,   2,   3,   4,   6,   7,   8,   9,   10,  12,  13,  14,  15,
1321       16,  18,  19,  20,  21,  22,  24,  25,  26,  27,  28,  30,  31,  32,
1322       33,  34,  36,  37,  38,  39,  40,  42,  43,  44,  45,  46,  48,  49,
1323       50,  51,  52,  54,  55,  56,  57,  58,  60,  61,  62,  63,  64,  66,
1324       67,  68,  69,  70,  72,  73,  74,  75,  76,  78,  79,  80,  81,  82,
1325       84,  85,  86,  87,  88,  90,  91,  92,  93,  94,  96,  97,  98,  99,
1326       100, 102, 103, 104, 105, 106, 108, 109, 110, 111, 112, 114, 115, 116,
1327       117, 118, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 133,
1328       134, 135, 136, 138, 139, 140, 141, 142};
1329     nntrainer::Tensor answer(ref_dim, answer_data);
1330     int status = t.add_i(m);
1331     EXPECT_EQ(status, ML_ERROR_NONE);
1332     EXPECT_EQ(t, answer);
1333   }
1334   {
1335     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1336     nntrainer::Tensor m = ranged(3, 1, 1, 5);
1337     float answer_data[] = {
1338       0,   2,   4,   6,   8,   5,   7,   9,   11,  13,  10,  12,  14,  16,
1339       18,  15,  17,  19,  21,  23,  20,  22,  24,  26,  28,  25,  27,  29,
1340       31,  33,  30,  32,  34,  36,  38,  35,  37,  39,  41,  43,  45,  47,
1341       49,  51,  53,  50,  52,  54,  56,  58,  55,  57,  59,  61,  63,  60,
1342       62,  64,  66,  68,  65,  67,  69,  71,  73,  70,  72,  74,  76,  78,
1343       75,  77,  79,  81,  83,  80,  82,  84,  86,  88,  90,  92,  94,  96,
1344       98,  95,  97,  99,  101, 103, 100, 102, 104, 106, 108, 105, 107, 109,
1345       111, 113, 110, 112, 114, 116, 118, 115, 117, 119, 121, 123, 120, 122,
1346       124, 126, 128, 125, 127, 129, 131, 133};
1347     nntrainer::Tensor answer(ref_dim, answer_data);
1348     int status = t.add_i(m);
1349     EXPECT_EQ(status, ML_ERROR_NONE);
1350     EXPECT_EQ(t, answer);
1351   }
1352   {
1353     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1354     nntrainer::Tensor m = ranged(1, 2, 1, 5);
1355     float answer_data[] = {
1356       0,   2,   4,   6,   8,   5,   7,   9,   11,  13,  10,  12,  14,  16,
1357       18,  15,  17,  19,  21,  23,  25,  27,  29,  31,  33,  30,  32,  34,
1358       36,  38,  35,  37,  39,  41,  43,  40,  42,  44,  46,  48,  40,  42,
1359       44,  46,  48,  45,  47,  49,  51,  53,  50,  52,  54,  56,  58,  55,
1360       57,  59,  61,  63,  65,  67,  69,  71,  73,  70,  72,  74,  76,  78,
1361       75,  77,  79,  81,  83,  80,  82,  84,  86,  88,  80,  82,  84,  86,
1362       88,  85,  87,  89,  91,  93,  90,  92,  94,  96,  98,  95,  97,  99,
1363       101, 103, 105, 107, 109, 111, 113, 110, 112, 114, 116, 118, 115, 117,
1364       119, 121, 123, 120, 122, 124, 126, 128};
1365     nntrainer::Tensor answer(ref_dim, answer_data);
1366     int status = t.add_i(m);
1367     EXPECT_EQ(status, ML_ERROR_NONE);
1368     EXPECT_EQ(t, answer);
1369   }
1370   {
1371     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1372     nntrainer::Tensor m = ranged(3, 1, 4, 1);
1373     float answer_data[] = {
1374       0,   1,   2,   3,   4,   6,   7,   8,   9,   10,  12,  13,  14,  15,
1375       16,  18,  19,  20,  21,  22,  20,  21,  22,  23,  24,  26,  27,  28,
1376       29,  30,  32,  33,  34,  35,  36,  38,  39,  40,  41,  42,  44,  45,
1377       46,  47,  48,  50,  51,  52,  53,  54,  56,  57,  58,  59,  60,  62,
1378       63,  64,  65,  66,  64,  65,  66,  67,  68,  70,  71,  72,  73,  74,
1379       76,  77,  78,  79,  80,  82,  83,  84,  85,  86,  88,  89,  90,  91,
1380       92,  94,  95,  96,  97,  98,  100, 101, 102, 103, 104, 106, 107, 108,
1381       109, 110, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 120, 121,
1382       122, 123, 124, 126, 127, 128, 129, 130};
1383     nntrainer::Tensor answer(ref_dim, answer_data);
1384     int status = t.add_i(m);
1385     EXPECT_EQ(status, ML_ERROR_NONE);
1386     EXPECT_EQ(t, answer);
1387   }
1388   {
1389     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1390     nntrainer::Tensor m = ranged(1, 1, 1, 5);
1391     float answer_data[] = {
1392       0,   2,   4,   6,   8,   5,   7,   9,   11,  13,  10,  12,  14,  16,
1393       18,  15,  17,  19,  21,  23,  20,  22,  24,  26,  28,  25,  27,  29,
1394       31,  33,  30,  32,  34,  36,  38,  35,  37,  39,  41,  43,  40,  42,
1395       44,  46,  48,  45,  47,  49,  51,  53,  50,  52,  54,  56,  58,  55,
1396       57,  59,  61,  63,  60,  62,  64,  66,  68,  65,  67,  69,  71,  73,
1397       70,  72,  74,  76,  78,  75,  77,  79,  81,  83,  80,  82,  84,  86,
1398       88,  85,  87,  89,  91,  93,  90,  92,  94,  96,  98,  95,  97,  99,
1399       101, 103, 100, 102, 104, 106, 108, 105, 107, 109, 111, 113, 110, 112,
1400       114, 116, 118, 115, 117, 119, 121, 123};
1401     nntrainer::Tensor answer(ref_dim, answer_data);
1402     int status = t.add_i(m);
1403     EXPECT_EQ(status, ML_ERROR_NONE);
1404     EXPECT_EQ(t, answer);
1405   }
1406   {
1407     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1408     nntrainer::Tensor m = ranged(1, 2, 1, 1);
1409     float answer_data[] = {
1410       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
1411       14,  15,  16,  17,  18,  19,  21,  22,  23,  24,  25,  26,  27,  28,
1412       29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  40,  41,
1413       42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
1414       56,  57,  58,  59,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
1415       71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  80,  81,  82,  83,
1416       84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
1417       98,  99,  101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
1418       113, 114, 115, 116, 117, 118, 119, 120};
1419     nntrainer::Tensor answer(ref_dim, answer_data);
1420     int status = t.add_i(m);
1421     EXPECT_EQ(status, ML_ERROR_NONE);
1422     EXPECT_EQ(t, answer);
1423   }
1424   {
1425     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1426     nntrainer::Tensor m = ranged(3, 1, 1, 1);
1427     float answer_data[] = {
1428       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
1429       14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
1430       28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  41,  42,
1431       43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
1432       57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
1433       71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  82,  83,  84,  85,
1434       86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
1435       100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
1436       114, 115, 116, 117, 118, 119, 120, 121};
1437     nntrainer::Tensor answer(ref_dim, answer_data);
1438     int status = t.add_i(m);
1439     EXPECT_EQ(status, ML_ERROR_NONE);
1440     EXPECT_EQ(t, answer);
1441   }
1442   {
1443     nntrainer::Tensor t = ranged(3, 2, 4, 5);
1444     nntrainer::Tensor m = ranged(1, 1, 1, 1);
1445     m.add_i(1.0);
1446     float answer_data[] = {
1447       1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
1448       15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
1449       29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,
1450       43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,
1451       57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,
1452       71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
1453       85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
1454       99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
1455       113, 114, 115, 116, 117, 118, 119, 120};
1456     nntrainer::Tensor answer(ref_dim, answer_data);
1457     int status = t.add_i(m);
1458     EXPECT_EQ(status, ML_ERROR_NONE);
1459     EXPECT_EQ(t, answer);
1460   }
1461   {
1462     nntrainer::TensorDim ref_dim(3, 5, 1, 4);
1463     nntrainer::Tensor t = ranged(3, 5, 1, 4);
1464     nntrainer::Tensor m = ranged(3, 1, 1, 4);
1465     float answer_data[] = {0,  2,  4,  6,  4,  6,  8,  10, 8,  10, 12, 14,
1466                            12, 14, 16, 18, 16, 18, 20, 22, 24, 26, 28, 30,
1467                            28, 30, 32, 34, 32, 34, 36, 38, 36, 38, 40, 42,
1468                            40, 42, 44, 46, 48, 50, 52, 54, 52, 54, 56, 58,
1469                            56, 58, 60, 62, 60, 62, 64, 66, 64, 66, 68, 70};
1470     nntrainer::Tensor answer(ref_dim, answer_data);
1471     int status = t.add_i(m);
1472     EXPECT_EQ(status, ML_ERROR_NONE);
1473     EXPECT_EQ(t, answer);
1474   }
1475   {
1476     nntrainer::TensorDim ref_dim(1, 1, 2, 1);
1477     nntrainer::Tensor t = ranged(1, 1, 2, 1);
1478     nntrainer::Tensor m = ranged(1, 1, 2, 1);
1479     float answer_data[] = {0.0, 2.0};
1480     nntrainer::Tensor answer(ref_dim, answer_data);
1481     int status = t.add_i(m);
1482     EXPECT_EQ(status, ML_ERROR_NONE);
1483     EXPECT_EQ(t, answer);
1484   }
1485   {
1486     nntrainer::TensorDim ref_dim(16, 1, 1, 1);
1487     nntrainer::Tensor t = ranged(16, 1, 1, 1);
1488     nntrainer::Tensor m = ranged(1, 1, 1, 1);
1489     float answer_data[] = {0.0, 1.0, 2.0,  3.0,  4.0,  5.0,  6.0,  7.0,
1490                            8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0};
1491     nntrainer::Tensor answer(ref_dim, answer_data);
1492     int status = t.add_i(m);
1493     EXPECT_EQ(status, ML_ERROR_NONE);
1494     EXPECT_EQ(t, answer);
1495   }
1496 }
1497
1498 TEST(nntrainer_Tensor, add_i_broadcast_not_supported_01_n) {
1499   nntrainer::Tensor target(3, 1, 3, 1);
1500   nntrainer::Tensor target2(3, 1, 3, 3);
1501
1502   EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER);
1503 }
1504
1505 TEST(nntrainer_Tensor, add_i_broadcast_not_broadcastable_02_n) {
1506   nntrainer::Tensor target(3, 2, 4, 5);
1507   nntrainer::Tensor target2(3, 2, 3, 1);
1508
1509   EXPECT_EQ(target.add_i(target2), ML_ERROR_INVALID_PARAMETER);
1510 }
1511
1512 TEST(nntrainer_Tensor, add_01_p) {
1513   int status = ML_ERROR_NONE;
1514   int batch = 3;
1515   int channel = 1;
1516   int height = 3;
1517   int width = 10;
1518
1519   nntrainer::Tensor input(batch, channel, height, width);
1520   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1521
1522   nntrainer::Tensor result = input.add(1.0);
1523
1524   float *data = result.getData();
1525   ASSERT_NE(nullptr, data);
1526   float *indata = input.getData();
1527   ASSERT_NE(nullptr, indata);
1528
1529   for (int i = 0; i < batch * height * width; ++i) {
1530     if (data[i] != indata[i] + (float)1.0) {
1531       status = ML_ERROR_RESULT_OUT_OF_RANGE;
1532       break;
1533     }
1534   }
1535
1536   EXPECT_EQ(status, ML_ERROR_NONE);
1537 }
1538
1539 TEST(nntrainer_Tensor, add_02_p) {
1540   int status = ML_ERROR_NONE;
1541   int batch = 3;
1542   int channel = 1;
1543   int height = 3;
1544   int width = 10;
1545
1546   nntrainer::Tensor input(batch, channel, height, width);
1547   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1548
1549   nntrainer::Tensor result = input.add(input);
1550
1551   float *data = result.getData();
1552   ASSERT_NE(nullptr, data);
1553   float *indata = input.getData();
1554   ASSERT_NE(nullptr, indata);
1555
1556   for (int i = 0; i < batch * height * width; ++i) {
1557     if (data[i] != indata[i] + indata[i]) {
1558       status = ML_ERROR_RESULT_OUT_OF_RANGE;
1559       break;
1560     }
1561   }
1562
1563   EXPECT_EQ(status, ML_ERROR_NONE);
1564 }
1565
1566 TEST(nntrainer_Tensor, add_03_n) {
1567   int batch = 3;
1568   int channel = 1;
1569   int height = 3;
1570   int width = 10;
1571
1572   nntrainer::Tensor input(batch, channel, height, width);
1573   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1574
1575   nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1);
1576
1577   EXPECT_THROW({ input.add(test); }, std::invalid_argument);
1578 }
1579
1580 TEST(nntrainer_Tensor, add_04_n) {
1581   int batch = 3;
1582   int channel = 1;
1583   int height = 3;
1584   int width = 10;
1585
1586   nntrainer::TensorDim dim(batch, channel, height, width);
1587
1588   nntrainer::Tensor input(batch, channel, height, 2 * width);
1589   nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false);
1590   nntrainer::Tensor test(dim);
1591
1592   EXPECT_THROW(shared_input.add(test), std::invalid_argument);
1593 }
1594
1595 TEST(nntrainer_Tensor, add_05_n) {
1596   int batch = 3;
1597   int channel = 1;
1598   int height = 3;
1599   int width = 10;
1600
1601   nntrainer::TensorDim dim(batch, channel, height, width);
1602
1603   nntrainer::Tensor input(dim);
1604   nntrainer::Tensor test(batch, channel, height, 2 * width);
1605   nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false);
1606
1607   EXPECT_THROW(input.add(shared_test), std::invalid_argument);
1608 }
1609
1610 TEST(nntrainer_Tensor, add_06_n) {
1611   int batch = 3;
1612   int channel = 1;
1613   int height = 3;
1614   int width = 10;
1615
1616   nntrainer::TensorDim dim(batch, channel, height, width);
1617
1618   nntrainer::Tensor input(dim, false);
1619   nntrainer::Tensor test(dim);
1620   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1);
1621
1622   EXPECT_THROW(input.add(test), std::invalid_argument);
1623 }
1624
1625 TEST(nntrainer_Tensor, add_07_n) {
1626   int batch = 3;
1627   int channel = 1;
1628   int height = 3;
1629   int width = 10;
1630
1631   nntrainer::TensorDim dim(batch, channel, height, width);
1632
1633   nntrainer::Tensor input(dim);
1634   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1635   nntrainer::Tensor test(dim, false);
1636
1637   EXPECT_THROW(input.add(test), std::invalid_argument);
1638 }
1639
1640 TEST(nntrainer_Tensor, add_08_n) {
1641   int batch = 3;
1642   int channel = 1;
1643   int height = 3;
1644   int width = 10;
1645
1646   nntrainer::TensorDim dim(batch, channel, height, width);
1647
1648   nntrainer::Tensor input(dim);
1649   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1650   nntrainer::Tensor test(dim);
1651   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2);
1652   nntrainer::Tensor output(dim, false);
1653
1654   EXPECT_THROW(input.add(test, output), std::invalid_argument);
1655 }
1656
1657 TEST(nntrainer_Tensor, pow_01_p) {
1658
1659   nntrainer::Tensor input = constant(4.0, 3, 2, 4, 5);
1660
1661   nntrainer::Tensor actual, expected;
1662
1663   actual = input.pow(0.5f);
1664   expected = constant(2.0, 3, 2, 4, 5);
1665   EXPECT_EQ(actual, expected);
1666
1667   actual = input.pow(2.0f);
1668   expected = constant(16.0, 3, 2, 4, 5);
1669   EXPECT_EQ(actual, expected);
1670
1671   actual = input.pow(-0.5f);
1672   expected = constant(0.5, 3, 2, 4, 5);
1673   EXPECT_EQ(actual, expected);
1674 }
1675
1676 TEST(nntrainer_Tensor, erf_01_p) {
1677   int batch = 1;
1678   int channel = 1;
1679   int height = 2;
1680   int width = 2;
1681
1682   nntrainer::TensorDim dim(batch, channel, height, width);
1683
1684   nntrainer::Tensor input(dim);
1685   GEN_TEST_INPUT(input, k + l * 0.5 + 0.5);
1686   nntrainer::Tensor actual = input.erf();
1687   nntrainer::Tensor expected(
1688     std::vector<std::vector<std::vector<std::vector<float>>>>(
1689       {{{{0.5205, 0.8427}, {0.966105, 0.995322}}}}));
1690
1691   EXPECT_EQ(actual, expected);
1692 }
1693
1694 TEST(nntrainer_Tensor, subtract_i_01_p) {
1695   int status = ML_ERROR_NONE;
1696   int batch = 3;
1697   int height = 3;
1698   int width = 10;
1699   int channel = 1;
1700
1701   nntrainer::Tensor target(batch, channel, height, width);
1702   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel);
1703
1704   nntrainer::Tensor original(batch, height, width);
1705   original.copy(target);
1706
1707   status = target.subtract_i(2.1);
1708   EXPECT_EQ(status, ML_ERROR_NONE);
1709
1710   float *previous = original.getData();
1711   ASSERT_NE(nullptr, previous);
1712   float *data = target.getData();
1713   ASSERT_NE(nullptr, data);
1714
1715   for (int i = 0; i < batch * height * width; ++i) {
1716     EXPECT_FLOAT_EQ(data[i], previous[i] - (float)2.1);
1717   }
1718 }
1719
1720 TEST(nntrainer_Tensor, subtract_i_02_p) {
1721   int status = ML_ERROR_NONE;
1722   int batch = 3;
1723   int height = 3;
1724   int width = 10;
1725   int channel = 1;
1726
1727   nntrainer::Tensor target(batch, channel, height, width);
1728   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel);
1729
1730   status = target.subtract_i(target);
1731   EXPECT_EQ(status, ML_ERROR_NONE);
1732
1733   float *data = target.getData();
1734   ASSERT_NE(nullptr, data);
1735
1736   for (int i = 0; i < batch * height * width; ++i) {
1737     EXPECT_FLOAT_EQ(data[i], 0);
1738   }
1739 }
1740
1741 TEST(nntrainer_Tensor, subtract_i_03_n) {
1742   int status = ML_ERROR_NONE;
1743   int batch = 3;
1744   int height = 3;
1745   int width = 10;
1746   int channel = 1;
1747
1748   nntrainer::Tensor target(batch, channel, height, width);
1749   GEN_TEST_INPUT(target, i * (batch * height) + j * (width) + k + 1 + channel);
1750
1751   nntrainer::Tensor target2(batch, channel, height - 1, width - 3);
1752
1753   status = target.subtract_i(target2);
1754   EXPECT_EQ(status, ML_ERROR_INVALID_PARAMETER);
1755 }
1756
1757 TEST(nntrainer_Tensor, subtract_01_p) {
1758   int status = ML_ERROR_NONE;
1759   int batch = 3;
1760   int channel = 1;
1761   int height = 3;
1762   int width = 10;
1763
1764   nntrainer::Tensor input(batch, channel, height, width);
1765   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1766
1767   nntrainer::Tensor result = input.subtract(1.0);
1768
1769   float *data = result.getData();
1770   ASSERT_NE(nullptr, data);
1771   float *indata = input.getData();
1772   ASSERT_NE(nullptr, indata);
1773
1774   for (int i = 0; i < batch * height * width; ++i) {
1775     if (data[i] != indata[i] - 1.0) {
1776       status = ML_ERROR_RESULT_OUT_OF_RANGE;
1777       break;
1778     }
1779   }
1780
1781   EXPECT_EQ(status, ML_ERROR_NONE);
1782 }
1783
1784 TEST(nntrainer_Tensor, subtract_02_p) {
1785   int batch = 3;
1786   int channel = 1;
1787   int height = 3;
1788   int width = 10;
1789
1790   nntrainer::Tensor input(batch, channel, height, width);
1791   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1792
1793   nntrainer::Tensor result = input.subtract(input);
1794
1795   EXPECT_EQ(constant(0.0, batch, channel, height, width), result);
1796 }
1797
1798 TEST(nntrainer_Tensor, subtract_03_n) {
1799   int batch = 3;
1800   int channel = 1;
1801   int height = 3;
1802   int width = 10;
1803
1804   nntrainer::Tensor input(batch, channel, height, width);
1805   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1806
1807   nntrainer::Tensor test(batch - 1, channel, height - 1, width - 1);
1808
1809   EXPECT_THROW({ input.subtract(test); }, std::invalid_argument);
1810 }
1811
1812 TEST(nntrainer_Tensor, subtract_04_n) {
1813   int batch = 3;
1814   int channel = 1;
1815   int height = 3;
1816   int width = 10;
1817
1818   nntrainer::TensorDim dim(batch, channel, height, width);
1819
1820   nntrainer::Tensor input(batch, channel, height, 2 * width);
1821   nntrainer::Tensor shared_input = input.getSharedDataTensor(dim, 0, false);
1822   nntrainer::Tensor test(dim);
1823
1824   EXPECT_THROW(shared_input.subtract(test), std::invalid_argument);
1825 }
1826
1827 TEST(nntrainer_Tensor, subtract_05_n) {
1828   int batch = 3;
1829   int channel = 1;
1830   int height = 3;
1831   int width = 10;
1832
1833   nntrainer::TensorDim dim(batch, channel, height, width);
1834
1835   nntrainer::Tensor input(dim);
1836   nntrainer::Tensor test(batch, channel, height, 2 * width);
1837   nntrainer::Tensor shared_test = test.getSharedDataTensor(dim, 0, false);
1838
1839   EXPECT_THROW(input.subtract(shared_test), std::invalid_argument);
1840 }
1841
1842 TEST(nntrainer_Tensor, subtract_06_n) {
1843   int batch = 3;
1844   int channel = 1;
1845   int height = 3;
1846   int width = 10;
1847
1848   nntrainer::TensorDim dim(batch, channel, height, width);
1849
1850   nntrainer::Tensor input(dim, false);
1851   nntrainer::Tensor test(dim);
1852   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 1);
1853
1854   EXPECT_THROW(input.subtract(test), std::invalid_argument);
1855 }
1856
1857 TEST(nntrainer_Tensor, subtract_07_n) {
1858   int batch = 3;
1859   int channel = 1;
1860   int height = 3;
1861   int width = 10;
1862
1863   nntrainer::TensorDim dim(batch, channel, height, width);
1864
1865   nntrainer::Tensor input(dim);
1866   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1867   nntrainer::Tensor test(dim, false);
1868
1869   EXPECT_THROW(input.subtract(test), std::invalid_argument);
1870 }
1871
1872 TEST(nntrainer_Tensor, subtract_08_n) {
1873   int batch = 3;
1874   int channel = 1;
1875   int height = 3;
1876   int width = 10;
1877
1878   nntrainer::TensorDim dim(batch, channel, height, width);
1879
1880   nntrainer::Tensor input(dim);
1881   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1882   nntrainer::Tensor test(dim);
1883   GEN_TEST_INPUT(test, i * (batch * height) + j * (width) + k + 2);
1884   nntrainer::Tensor output(dim, false);
1885
1886   EXPECT_THROW(input.subtract(test, output), std::invalid_argument);
1887 }
1888
1889 TEST(nntrainer_Tensor, subtract_float_01_p) {
1890   int batch = 3;
1891   int channel = 1;
1892   int height = 3;
1893   int width = 10;
1894
1895   nntrainer::Tensor input(batch, channel, height, width);
1896   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k + 1);
1897
1898   nntrainer::Tensor expected(batch, channel, height, width);
1899   GEN_TEST_INPUT(expected, i * (batch * height) + j * (width) + k);
1900
1901   nntrainer::Tensor result = input.subtract(1.0);
1902
1903   EXPECT_EQ(result, expected);
1904 }
1905
1906 TEST(nntrainer_Tensor, sum_01_n) {
1907   int batch = 3;
1908   int channel = 1;
1909   int height = 3;
1910   int width = 10;
1911
1912   nntrainer::Tensor input(batch, channel, height, width);
1913   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
1914
1915   EXPECT_THROW({ input.sum(4); }, std::out_of_range);
1916 }
1917
1918 TEST(nntrainer_Tensor, sum_02_n) {
1919   int batch = 3;
1920   int channel = 1;
1921   int height = 3;
1922   int width = 10;
1923
1924   nntrainer::Tensor input(batch, channel, height, width);
1925   GEN_TEST_INPUT(input, i * (batch * height) + j * (width) + k);
1926
1927   EXPECT_THROW({ input.sum(-1); }, std::out_of_range);
1928 }
1929
1930 TEST(nntrainer_Tensor, sum_02_p) {
1931   int batch = 3;
1932   int channel = 2;
1933   int height = 2;
1934   int width = 10;
1935
1936   nntrainer::Tensor ans0(
1937     std::vector<std::vector<std::vector<std::vector<float>>>>(
1938       {{{{39, 42, 45, 48, 51, 54, 57, 60, 63, 66},
1939          {69, 72, 75, 78, 81, 84, 87, 90, 93, 96}},
1940         {{57, 60, 63, 66, 69, 72, 75, 78, 81, 84},
1941          {87, 90, 93, 96, 99, 102, 105, 108, 111, 114}}}}));
1942
1943   nntrainer::Tensor ans1(
1944     std::vector<std::vector<std::vector<std::vector<float>>>>(
1945       {{{{8, 10, 12, 14, 16, 18, 20, 22, 24, 26},
1946          {28, 30, 32, 34, 36, 38, 40, 42, 44, 46}}},
1947        {{{32, 34, 36, 38, 40, 42, 44, 46, 48, 50},
1948          {52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}},
1949        {{{56, 58, 60, 62, 64, 66, 68, 70, 72, 74},
1950          {76, 78, 80, 82, 84, 86, 88, 90, 92, 94}}}}));
1951
1952   nntrainer::Tensor ans2(
1953     std::vector<std::vector<std::vector<std::vector<float>>>>(
1954       {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}},
1955         {{24, 26, 28, 30, 32, 34, 36, 38, 40, 42}}},
1956        {{{36, 38, 40, 42, 44, 46, 48, 50, 52, 54}},
1957         {{48, 50, 52, 54, 56, 58, 60, 62, 64, 66}}},
1958        {{{60, 62, 64, 66, 68, 70, 72, 74, 76, 78}},
1959         {{72, 74, 76, 78, 80, 82, 84, 86, 88, 90}}}}));
1960
1961   nntrainer::Tensor ans3(
1962     std::vector<std::vector<std::vector<std::vector<float>>>>(
1963       {{{{55}, {155}}, {{115}, {215}}},
1964        {{{175}, {275}}, {{235}, {335}}},
1965        {{{295}, {395}}, {{355}, {455}}}}));
1966
1967   nntrainer::Tensor input(batch, channel, height, width);
1968   GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (batch * height) +
1969                           k * (width) + l + 1);
1970
1971   nntrainer::Tensor result0 = input.sum(0);
1972   nntrainer::Tensor result1 = input.sum(1);
1973   nntrainer::Tensor result2 = input.sum(2);
1974   nntrainer::Tensor result3 = input.sum(3);
1975
1976   EXPECT_EQ(ans0, result0);
1977   EXPECT_EQ(ans1, result1);
1978   EXPECT_EQ(ans2, result2);
1979   EXPECT_EQ(ans3, result3);
1980 }
1981
1982 TEST(nntrainer_Tensor, sum_03_p) {
1983   const int batch = 3;
1984   const int channel = 2;
1985   const int height = 1;
1986   const int width = 10;
1987
1988   nntrainer::Tensor input(batch, channel, height, width);
1989   GEN_TEST_INPUT(input, i * (height * channel * width) + j * (height * width) +
1990                           k * (width) + l + 1);
1991   // Test for alpha == 1 and beta == 0 and dimension of reduced axis == 1
1992   {
1993     nntrainer::Tensor ans_0_1_0(
1994       std::vector<std::vector<std::vector<std::vector<float>>>>(
1995         {{{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}},
1996           {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}}}));
1997
1998     nntrainer::Tensor ans_1_1_0(
1999       std::vector<std::vector<std::vector<std::vector<float>>>>(
2000         {{{{12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}},
2001          {{{52, 54, 56, 58, 60, 62, 64, 66, 68, 70}}},
2002          {{{92, 94, 96, 98, 100, 102, 104, 106, 108, 110}}}}));
2003
2004     nntrainer::Tensor ans_2_1_0(
2005       std::vector<std::vector<std::vector<std::vector<float>>>>(
2006         {{{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
2007           {{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}}},
2008          {{{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}},
2009           {{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}}},
2010          {{{41, 42, 43, 44, 45, 46, 47, 48, 49, 50}},
2011           {{51, 52, 53, 54, 55, 56, 57, 58, 59, 60}}}}));
2012
2013     nntrainer::Tensor ans_3_1_0(
2014       std::vector<std::vector<std::vector<std::vector<float>>>>(
2015         {{{{55}}, {{155}}}, {{{255}}, {{355}}}, {{{455}}, {{555}}}}));
2016
2017     nntrainer::Tensor result_0_1_0 = input.sum(0, 1);
2018     nntrainer::Tensor result_1_1_0 = input.sum(1, 1);
2019     nntrainer::Tensor result_2_1_0 = input.sum(2, 1);
2020     nntrainer::Tensor result_3_1_0 = input.sum(3, 1);
2021
2022     EXPECT_EQ(ans_0_1_0, result_0_1_0);
2023     EXPECT_EQ(ans_1_1_0, result_1_1_0);
2024     EXPECT_EQ(ans_2_1_0, result_2_1_0);
2025     EXPECT_EQ(ans_3_1_0, result_3_1_0);
2026   }
2027
2028   // Test for alpha == 1 and beta == 2 and dimension of reduced axis == 1
2029   {
2030     nntrainer::Tensor ans_0_1_2(
2031       std::vector<std::vector<std::vector<std::vector<float>>>>(
2032         {{{{65, 70, 75, 80, 85, 90, 95, 100, 105, 110}},
2033           {{115, 120, 125, 130, 135, 140, 145, 150, 155, 160}}}}));
2034
2035     nntrainer::Tensor ans_1_1_2(
2036       std::vector<std::vector<std::vector<std::vector<float>>>>(
2037         {{{{14, 18, 22, 26, 30, 34, 38, 42, 46, 50}}},
2038          {{{74, 78, 82, 86, 90, 94, 98, 102, 106, 110}}},
2039          {{{134, 138, 142, 146, 150, 154, 158, 162, 166, 170}}}}));
2040
2041     nntrainer::Tensor ans_2_1_2(
2042       std::vector<std::vector<std::vector<std::vector<float>>>>(
2043         {{{{3, 6, 9, 12, 15, 18, 21, 24, 27, 30}},
2044           {{33, 36, 39, 42, 45, 48, 51, 54, 57, 60}}},
2045          {{{63, 66, 69, 72, 75, 78, 81, 84, 87, 90}},
2046           {{93, 96, 99, 102, 105, 108, 111, 114, 117, 120}}},
2047          {{{123, 126, 129, 132, 135, 138, 141, 144, 147, 150}},
2048           {{153, 156, 159, 162, 165, 168, 171, 174, 177, 180}}}}));
2049
2050     nntrainer::Tensor ans_3_1_2(
2051       std::vector<std::vector<std::vector<std::vector<float>>>>(
2052         {{{{57}}, {{159}}}, {{{261}}, {{363}}}, {{{465}}, {{567}}}}));
2053
2054     nntrainer::Tensor output_0_1_2(1, channel, height, width);
2055     {
2056       const int batch = 1;
2057       GEN_TEST_INPUT(output_0_1_2, i * (channel * height * width) +
2058                                      j * (height * width) + k * (width) + l +
2059                                      1);
2060     }
2061     nntrainer::Tensor output_1_1_2(batch, 1, height, width);
2062     {
2063       const int channel = 1;
2064       GEN_TEST_INPUT(output_1_1_2, i * (channel * height * width) +
2065                                      j * (height * width) + k * (width) + l +
2066                                      1);
2067     }
2068     nntrainer::Tensor output_2_1_2(batch, channel, 1, width);
2069     {
2070       const int height = 1;
2071       GEN_TEST_INPUT(output_2_1_2, i * (channel * height * width) +
2072                                      j * (height * width) + k * (width) + l +
2073                                      1);
2074     }
2075     nntrainer::Tensor output_3_1_2(batch, channel, height, 1);
2076     {
2077       const int width = 1;
2078       GEN_TEST_INPUT(output_3_1_2, i * (channel * height * width) +
2079                                      j * (height * width) + k * (width) + l +
2080                                      1);
2081     }
2082     nntrainer::Tensor result_0_1_2 = input.sum(0, output_0_1_2, 1, 2);
2083     nntrainer::Tensor result_1_1_2 = input.sum(1, output_1_1_2, 1, 2);
2084     nntrainer::Tensor result_2_1_2 = input.sum(2, output_2_1_2, 1, 2);
2085     nntrainer::Tensor result_3_1_2 = input.sum(3, output_3_1_2, 1, 2);
2086
2087     EXPECT_EQ(ans_0_1_2, result_0_1_2);
2088     EXPECT_EQ(ans_1_1_2, result_1_1_2);
2089     EXPECT_EQ(ans_2_1_2, result_2_1_2);
2090     EXPECT_EQ(ans_3_1_2, result_3_1_2);
2091   }
2092
2093   // Test for alpha == 2 and beta == 0
2094   {
2095     nntrainer::Tensor ans_0_2_0(
2096       std::vector<std::vector<std::vector<std::vector<float>>>>(
2097         {{{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}},
2098           {{186, 192, 198, 204, 210, 216, 222, 228, 234, 240}}}}));
2099
2100     nntrainer::Tensor ans_1_2_0(
2101       std::vector<std::vector<std::vector<std::vector<float>>>>(
2102         {{{{24, 28, 32, 36, 40, 44, 48, 52, 56, 60}}},
2103          {{{104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
2104          {{{184, 188, 192, 196, 200, 204, 208, 212, 216, 220}}}}));
2105
2106     nntrainer::Tensor ans_2_2_0(
2107       std::vector<std::vector<std::vector<std::vector<float>>>>(
2108         {{{{2, 4, 6, 8, 10, 12, 14, 16, 18, 20}},
2109           {{22, 24, 26, 28, 30, 32, 34, 36, 38, 40}}},
2110          {{{42, 44, 46, 48, 50, 52, 54, 56, 58, 60}},
2111           {{62, 64, 66, 68, 70, 72, 74, 76, 78, 80}}},
2112          {{{82, 84, 86, 88, 90, 92, 94, 96, 98, 100}},
2113           {{102, 104, 106, 108, 110, 112, 114, 116, 118, 120}}}}));
2114
2115     nntrainer::Tensor ans_3_2_0(
2116       std::vector<std::vector<std::vector<std::vector<float>>>>(
2117         {{{{110}}, {{310}}}, {{{510}}, {{710}}}, {{{910}}, {{1110}}}}));
2118
2119     nntrainer::Tensor result_0_2_0 = input.sum(0, 2);
2120     nntrainer::Tensor result_1_2_0 = input.sum(1, 2);
2121     nntrainer::Tensor result_2_2_0 = input.sum(2, 2);
2122     nntrainer::Tensor result_3_2_0 = input.sum(3, 2);
2123
2124     EXPECT_EQ(ans_0_2_0, result_0_2_0);
2125     EXPECT_EQ(ans_1_2_0, result_1_2_0);
2126     EXPECT_EQ(ans_2_2_0, result_2_2_0);
2127     EXPECT_EQ(ans_3_2_0, result_3_2_0);
2128   }
2129
2130   // Test for alpha == 2 and beta == 2
2131   {
2132     nntrainer::Tensor ans_0_2_2(
2133       std::vector<std::vector<std::vector<std::vector<float>>>>(
2134         {{{{128, 136, 144, 152, 160, 168, 176, 184, 192, 200}},
2135           {{208, 216, 224, 232, 240, 248, 256, 264, 272, 280}}}}));
2136
2137     nntrainer::Tensor ans_1_2_2(
2138       std::vector<std::vector<std::vector<std::vector<float>>>>(
2139         {{{{26, 32, 38, 44, 50, 56, 62, 68, 74, 80}}},
2140          {{{126, 132, 138, 144, 150, 156, 162, 168, 174, 180}}},
2141          {{{226, 232, 238, 244, 250, 256, 262, 268, 274, 280}}}}));
2142
2143     nntrainer::Tensor ans_2_2_2(
2144       std::vector<std::vector<std::vector<std::vector<float>>>>(
2145         {{{{4, 8, 12, 16, 20, 24, 28, 32, 36, 40}},
2146           {{44, 48, 52, 56, 60, 64, 68, 72, 76, 80}}},
2147          {{{84, 88, 92, 96, 100, 104, 108, 112, 116, 120}},
2148           {{124, 128, 132, 136, 140, 144, 148, 152, 156, 160}}},
2149          {{{164, 168, 172, 176, 180, 184, 188, 192, 196, 200}},
2150           {{204, 208, 212, 216, 220, 224, 228, 232, 236, 240}}}}));
2151
2152     nntrainer::Tensor ans_3_2_2(
2153       std::vector<std::vector<std::vector<std::vector<float>>>>(
2154         {{{{112}}, {{314}}}, {{{516}}, {{718}}}, {{{920}}, {{1122}}}}));
2155
2156     nntrainer::Tensor output_0_2_2(1, channel, height, width);
2157     {
2158       const int batch = 1;
2159       GEN_TEST_INPUT(output_0_2_2, i * (channel * height * width) +
2160                                      j * (height * width) + k * (width) + l +
2161                                      1);
2162     }
2163     nntrainer::Tensor output_1_2_2(batch, 1, height, width);
2164     {
2165       const int channel = 1;
2166       GEN_TEST_INPUT(output_1_2_2, i * (channel * height * width) +
2167                                      j * (height * width) + k * (width) + l +
2168                                      1);
2169     }
2170     nntrainer::Tensor output_2_2_2(batch, channel, 1, width);
2171     {
2172       const int height = 1;
2173       GEN_TEST_INPUT(output_2_2_2, i * (channel * height * width) +
2174                                      j * (height * width) + k * (width) + l +
2175                                      1);
2176     }
2177     nntrainer::Tensor output_3_2_2(batch, channel, height, 1);
2178     {
2179       const int width = 1;
2180       GEN_TEST_INPUT(output_3_2_2, i * (channel * height * width) +
2181                                      j * (height * width) + k * (width) + l +
2182                                      1);
2183     }
2184     nntrainer::Tensor result_0_2_2 = input.sum(0, output_0_2_2, 2, 2);
2185     nntrainer::Tensor result_1_2_2 = input.sum(1, output_1_2_2, 2, 2);
2186     nntrainer::Tensor result_2_2_2 = input.sum(2, output_2_2_2, 2, 2);
2187     nntrainer::Tensor result_3_2_2 = input.sum(3, output_3_2_2, 2, 2);
2188
2189     EXPECT_EQ(ans_0_2_2, result_0_2_2);
2190     EXPECT_EQ(ans_1_2_2, result_1_2_2);
2191     EXPECT_EQ(ans_2_2_2, result_2_2_2);
2192     EXPECT_EQ(ans_3_2_2, result_3_2_2);
2193   }
2194 }
2195
2196 TEST(nntrainer_Tensor, sum_04_p) {
2197   int status = ML_ERROR_NONE;
2198   int batch = 3;
2199   int channel = 2;
2200   int height = 2;
2201   int width = 10;
2202
2203   nntrainer::Tensor input(batch, channel, height, width);
2204   GEN_TEST_INPUT(input, i * (batch * height * channel) + j * (height * width) +
2205                           k * width + l + 1);
2206
2207   nntrainer::Tensor result = input.sum_by_batch();
2208   if (result.getValue(0, 0, 0, 0) != 820 ||
2209       result.getValue(1, 0, 0, 0) != 1300 ||
2210       result.getValue(2, 0, 0, 0) != 1780)
2211     status = ML_ERROR_RESULT_OUT_OF_RANGE;
2212
2213   EXPECT_EQ(status, ML_ERROR_NONE);
2214 }
2215
2216 TEST(nntrainer_Tensor, multiple_sum_invalid_args_01_n) {
2217   nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1);
2218   EXPECT_THROW(t.sum(std::vector<unsigned int>()), std::invalid_argument);
2219 }
2220
2221 TEST(nntrainer_Tensor, multiple_sum_out_of_range_n) {
2222   nntrainer::Tensor t = constant(1.0, 1, 1, 1, 1);
2223   EXPECT_THROW(t.sum({7}), std::out_of_range);
2224 }
2225
2226 TEST(nntrainer_Tensor, multiple_sum_p) {
2227   nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7);
2228   nntrainer::Tensor actual, expected;
2229
2230   actual = t.sum({0, 1});
2231   expected = constant(2 * 3, 1, 1, 5, 7);
2232   EXPECT_EQ(actual, expected);
2233
2234   actual = t.sum({1, 2, 3});
2235   expected = constant(3 * 5 * 7, 2, 1, 1, 1);
2236   EXPECT_EQ(actual, expected);
2237
2238   actual = t.sum({3, 1});
2239   expected = constant(7 * 3, 2, 1, 5, 1);
2240   EXPECT_EQ(actual, expected);
2241
2242   actual = t.sum({3, 1}, 0.5);
2243   expected = constant(7 * 3 * 0.5, 2, 1, 5, 1);
2244   EXPECT_EQ(actual, expected);
2245 }
2246
2247 TEST(nntrainer_Tensor, average_p) {
2248   nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7);
2249
2250   nntrainer::Tensor actual, expected;
2251
2252   actual = t.average();
2253   expected = constant(1.0, 1, 1, 1, 1);
2254   EXPECT_EQ(actual, expected);
2255
2256   int idx = 0;
2257   t = t.apply([&](float in) { return idx++ % 2; });
2258
2259   actual = t.average();
2260   expected = constant(0.5, 1, 1, 1, 1);
2261   EXPECT_EQ(actual, expected);
2262 }
2263
2264 TEST(nntrainer_Tensor, average_axis_p) {
2265   nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2);
2266   int idx = 0;
2267   std::function<float(float)> f = [&](float in) { return idx++ % 2; };
2268   t = t.apply(f);
2269
2270   nntrainer::Tensor actual, expected;
2271
2272   actual = t.average(0);
2273   expected = constant(0, 1, 2, 2, 2).apply(f);
2274   EXPECT_EQ(actual, expected);
2275
2276   actual = t.average(1);
2277   expected = constant(0, 2, 1, 2, 2).apply(f);
2278   EXPECT_EQ(actual, expected);
2279
2280   actual = t.average(2);
2281   expected = constant(0, 2, 2, 1, 2).apply(f);
2282   EXPECT_EQ(actual, expected);
2283
2284   actual = t.average(3);
2285   expected = constant(0.5, 2, 2, 2, 1);
2286   EXPECT_EQ(actual, expected);
2287 }
2288
2289 TEST(nntrainer_Tensor, average_axis_out_of_range_01_n) {
2290   nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2);
2291   EXPECT_THROW(t.average(-1), std::out_of_range);
2292 }
2293
2294 TEST(nntrainer_Tensor, average_axis_out_of_range_02_n) {
2295   nntrainer::Tensor t = constant(1.0, 2, 2, 2, 2);
2296   EXPECT_THROW(t.average(7), std::out_of_range);
2297 }
2298
2299 TEST(nntrainer_Tensor, average_multiple_axes_p) {
2300   nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7);
2301   nntrainer::Tensor actual, expected;
2302
2303   actual = t.average({0, 1, 2});
2304   expected = constant(1.0, 1, 1, 1, 7);
2305   EXPECT_EQ(actual, expected);
2306
2307   actual = t.average({0, 1, 2, 3});
2308   expected = constant(1.0, 1, 1, 1, 1);
2309   EXPECT_EQ(actual, expected);
2310
2311   actual = t.average({3, 1});
2312   expected = constant(1.0, 2, 1, 5, 1);
2313   EXPECT_EQ(actual, expected);
2314
2315   actual = t.average({3, 1, 1, 1, 3});
2316   expected = constant(1.0, 2, 1, 5, 1);
2317   EXPECT_EQ(actual, expected);
2318 }
2319
2320 TEST(nntrainer_Tensor, average_multiple_axes_01_n) {
2321   nntrainer::Tensor t = constant(1.0, 2, 3, 5, 7);
2322   EXPECT_THROW(t.average({5, 7}), std::out_of_range);
2323 }
2324
2325 TEST(nntrainer_Tensor, dot_01_n) {
2326   nntrainer::Tensor input(2, 3, 4, 5);
2327   nntrainer::Tensor m(1, 3, 4, 5);
2328   EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error);
2329 }
2330
2331 TEST(nntrainer_Tensor, dot_02_n) {
2332   nntrainer::Tensor input(2, 3, 4, 5);
2333   nntrainer::Tensor m(1, 3, 4, 5);
2334   EXPECT_THROW(nntrainer::Tensor result = input.dot(m, true),
2335                std::runtime_error);
2336 }
2337
2338 TEST(nntrainer_Tensor, dot_02_p) {
2339   nntrainer::Tensor input(2, 3, 4, 5);
2340   nntrainer::Tensor m(1, 3, 4, 5);
2341   EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true));
2342 }
2343
2344 TEST(nntrainer_Tensor, dot_03_p) {
2345   nntrainer::Tensor input(1, 3, 4, 5);
2346   nntrainer::Tensor m(1, 3, 4, 5);
2347   EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, true));
2348 }
2349
2350 TEST(nntrainer_Tensor, dot_04_n) {
2351   nntrainer::Tensor input(2, 3, 4, 5);
2352   nntrainer::Tensor m(1, 1, 4, 5);
2353   EXPECT_THROW(nntrainer::Tensor result = input.dot(m), std::runtime_error);
2354   EXPECT_NO_THROW(nntrainer::Tensor result = input.dot(m, false, true));
2355 }
2356
2357 TEST(nntrainer_Tensor, dot_05_p) {
2358   int status = ML_ERROR_NONE;
2359   int batch = 2;
2360   int channel = 3;
2361   int height = 4;
2362   int width = 5;
2363   float ans[2][3][4][24] = {0};
2364
2365   nntrainer::Tensor input(batch, channel, height, width);
2366   GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) +
2367                           k * (width) + l + 1);
2368   nntrainer::Tensor weight(batch, channel, height, width);
2369   GEN_TEST_INPUT(weight, i * (channel * width * height) + j * (height * width) +
2370                            k * (width) + l + 1);
2371   weight.reshape({1, 1, 24, 5});
2372
2373   nntrainer::Tensor result = input.dot(weight, false, true);
2374
2375   for (int b = 0; b < batch; b++) {
2376     for (int c = 0; c < channel; c++) {
2377       for (int h = 0; h < height; h++) {
2378         for (int k = 0; k < batch * channel * height; k++) {
2379           ans[b][c][h][k] = 0;
2380           for (int w = 0; w < width; w++) {
2381             float val1 = input.getValue(b, c, h, w);
2382             float val2 = weight.getValue(0, 0, k, w);
2383             ans[b][c][h][k] += val1 * val2;
2384           }
2385         }
2386       }
2387     }
2388   }
2389
2390   for (unsigned int i = 0; i < result.batch(); ++i) {
2391     for (unsigned int c = 0; c < result.channel(); ++c) {
2392       for (unsigned int j = 0; j < result.height(); ++j) {
2393         for (unsigned int k = 0; k < result.width(); ++k) {
2394           float val1 = ans[i][c][j][k];
2395           float val2 = result.getValue(i, c, j, k);
2396           if (val1 != val2) {
2397             status = ML_ERROR_RESULT_OUT_OF_RANGE;
2398             goto end_dot_01_p;
2399           }
2400         }
2401       }
2402     }
2403   }
2404 end_dot_01_p:
2405   EXPECT_EQ(status, ML_ERROR_NONE);
2406 }
2407
2408 TEST(nntrainer_Tensor, dot_06_p) {
2409   int status = ML_ERROR_NONE;
2410   int batch = 3;
2411   int channel = 1;
2412   int height = 1;
2413   int width = 3;
2414   float ans[3][1][1][3] = {
2415     {{{30, 36, 42}}}, {{{66, 81, 96}}}, {{{102, 126, 150}}}};
2416
2417   nntrainer::Tensor input(batch, channel, height, width);
2418   GEN_TEST_INPUT(input, i * (channel * width * height) + j * (height * width) +
2419                           k * (width) + l + 1);
2420
2421   nntrainer::Tensor result = input.dot(input);
2422
2423   for (unsigned int i = 0; i < result.batch(); ++i) {
2424     for (unsigned int j = 0; j < result.height(); ++j) {
2425       for (unsigned int k = 0; k < result.width(); ++k) {
2426         if (ans[i][0][j][k] != result.getValue(i, 0, j, k)) {
2427           status = ML_ERROR_RESULT_OUT_OF_RANGE;
2428           goto end_dot_01_p;
2429         }
2430       }
2431     }
2432   }
2433 end_dot_01_p:
2434   EXPECT_EQ(status, ML_ERROR_NONE);
2435 }
2436
2437 TEST(nntrainer_Tensor, dot_transpose_p) {
2438   {
2439     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2440     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2441     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2442     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2443     float answer_data[] = {20, 23,  26,  29,  56,  68,  80,  92,
2444                            92, 113, 134, 155, 128, 158, 188, 218};
2445     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data);
2446     nntrainer::Tensor ret = a.dot(b, true, true);
2447     EXPECT_EQ(ret, answer);
2448   }
2449   {
2450     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2451     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2452     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2453     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2454     float answer_data[] = {20, 23,  26,  29,  56,  68,  80,  92,
2455                            92, 113, 134, 155, 128, 158, 188, 218};
2456     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data);
2457     nntrainer::Tensor ret = a.dot(b, true, false);
2458     EXPECT_EQ(ret, answer);
2459   }
2460   {
2461     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2462     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2463     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2464     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2465     float answer_data[] = {20, 23,  26,  29,  56,  68,  80,  92,
2466                            92, 113, 134, 155, 128, 158, 188, 218};
2467     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data);
2468     nntrainer::Tensor ret = a.dot(b, false, true);
2469     EXPECT_EQ(ret, answer);
2470   }
2471   {
2472     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2473     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2474     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2475     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2476     float answer_data[] = {20, 23,  26,  29,  56,  68,  80,  92,
2477                            92, 113, 134, 155, 128, 158, 188, 218};
2478     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 4), answer_data);
2479     nntrainer::Tensor ret = a.dot(b, false, false);
2480     EXPECT_EQ(ret, answer);
2481   }
2482   {
2483     float a_data[] = {0, 3, 1, 4, 2, 5};
2484     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2485     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2486     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2487     float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92};
2488     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data);
2489     nntrainer::Tensor ret = a.dot(b, true, true);
2490     EXPECT_EQ(ret, answer);
2491   }
2492   {
2493     float a_data[] = {0, 3, 1, 4, 2, 5};
2494     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2495     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2496     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2497     float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92};
2498     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data);
2499     nntrainer::Tensor ret = a.dot(b, true, false);
2500     EXPECT_EQ(ret, answer);
2501   }
2502   {
2503     float a_data[] = {0, 1, 2, 3, 4, 5};
2504     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2505     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2506     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2507     float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92};
2508     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data);
2509     nntrainer::Tensor ret = a.dot(b, false, true);
2510     EXPECT_EQ(ret, answer);
2511   }
2512   {
2513     float a_data[] = {0, 1, 2, 3, 4, 5};
2514     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2515     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2516     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2517     float answer_data[] = {20, 23, 26, 29, 56, 68, 80, 92};
2518     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 4), answer_data);
2519     nntrainer::Tensor ret = a.dot(b, false, false);
2520     EXPECT_EQ(ret, answer);
2521   }
2522   {
2523     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2524     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2525     float b_data[] = {0, 2, 4, 1, 3, 5};
2526     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2527     float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94};
2528     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data);
2529     nntrainer::Tensor ret = a.dot(b, true, true);
2530     EXPECT_EQ(ret, answer);
2531   }
2532   {
2533     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2534     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2535     float b_data[] = {0, 1, 2, 3, 4, 5};
2536     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2537     float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94};
2538     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data);
2539     nntrainer::Tensor ret = a.dot(b, true, false);
2540     EXPECT_EQ(ret, answer);
2541   }
2542   {
2543     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2544     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2545     float b_data[] = {0, 2, 4, 1, 3, 5};
2546     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2547     float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94};
2548     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data);
2549     nntrainer::Tensor ret = a.dot(b, false, true);
2550     EXPECT_EQ(ret, answer);
2551   }
2552   {
2553     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2554     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2555     float b_data[] = {0, 1, 2, 3, 4, 5};
2556     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2557     float answer_data[] = {10, 13, 28, 40, 46, 67, 64, 94};
2558     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 2), answer_data);
2559     nntrainer::Tensor ret = a.dot(b, false, false);
2560     EXPECT_EQ(ret, answer);
2561   }
2562   {
2563     float a_data[] = {0, 3, 1, 4, 2, 5};
2564     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2565     float b_data[] = {0, 2, 4, 1, 3, 5};
2566     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2567     float answer_data[] = {10, 13, 28, 40};
2568     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data);
2569     nntrainer::Tensor ret = a.dot(b, true, true);
2570     EXPECT_EQ(ret, answer);
2571   }
2572   {
2573     float a_data[] = {0, 3, 1, 4, 2, 5};
2574     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2575     float b_data[] = {0, 1, 2, 3, 4, 5};
2576     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2577     float answer_data[] = {10, 13, 28, 40};
2578     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data);
2579     nntrainer::Tensor ret = a.dot(b, true, false);
2580     EXPECT_EQ(ret, answer);
2581   }
2582   {
2583     float a_data[] = {0, 1, 2, 3, 4, 5};
2584     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2585     float b_data[] = {0, 2, 4, 1, 3, 5};
2586     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2587     float answer_data[] = {10, 13, 28, 40};
2588     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data);
2589     nntrainer::Tensor ret = a.dot(b, false, true);
2590     EXPECT_EQ(ret, answer);
2591   }
2592   {
2593     float a_data[] = {0, 1, 2, 3, 4, 5};
2594     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2595     float b_data[] = {0, 1, 2, 3, 4, 5};
2596     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2597     float answer_data[] = {10, 13, 28, 40};
2598     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 2), answer_data);
2599     nntrainer::Tensor ret = a.dot(b, false, false);
2600     EXPECT_EQ(ret, answer);
2601   }
2602 }
2603
2604 TEST(nntrainer_Tensor, dot_shortcuts_p) {
2605   {
2606     float a_data[] = {0, 1, 2};
2607     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2608     float b_data[] = {0, 1, 2};
2609     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2610     float answer_data[] = {5};
2611     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data);
2612     nntrainer::Tensor ret = a.dot(b, false, false);
2613     EXPECT_EQ(ret, answer);
2614   }
2615   {
2616     float a_data[] = {0, 1, 2};
2617     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2618     float b_data[] = {0, 1, 2};
2619     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2620     float answer_data[] = {5};
2621     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data);
2622     nntrainer::Tensor ret = a.dot(b, true, false);
2623     EXPECT_EQ(ret, answer);
2624   }
2625   {
2626     float a_data[] = {0, 1, 2};
2627     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2628     float b_data[] = {0, 1, 2};
2629     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2630     float answer_data[] = {5};
2631     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data);
2632     nntrainer::Tensor ret = a.dot(b, false, true);
2633     EXPECT_EQ(ret, answer);
2634   }
2635   {
2636     float a_data[] = {0, 1, 2};
2637     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2638     float b_data[] = {0, 1, 2};
2639     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2640     float answer_data[] = {5};
2641     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 1), answer_data);
2642     nntrainer::Tensor ret = a.dot(b, true, true);
2643     EXPECT_EQ(ret, answer);
2644   }
2645   {
2646     float a_data[] = {0, 1, 2, 3, 4, 5};
2647     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2648     float b_data[] = {0, 1, 2};
2649     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2650     float answer_data[] = {5, 14};
2651     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data);
2652     nntrainer::Tensor ret = a.dot(b, false, false);
2653     EXPECT_EQ(ret, answer);
2654   }
2655   {
2656     float a_data[] = {0, 3, 1, 4, 2, 5};
2657     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2658     float b_data[] = {0, 1, 2};
2659     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2660     float answer_data[] = {5, 14};
2661     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data);
2662     nntrainer::Tensor ret = a.dot(b, true, false);
2663     EXPECT_EQ(ret, answer);
2664   }
2665   {
2666     float a_data[] = {0, 1, 2, 3, 4, 5};
2667     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 2, 3), a_data);
2668     float b_data[] = {0, 1, 2};
2669     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2670     float answer_data[] = {5, 14};
2671     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data);
2672     nntrainer::Tensor ret = a.dot(b, false, true);
2673     EXPECT_EQ(ret, answer);
2674   }
2675   {
2676     float a_data[] = {0, 3, 1, 4, 2, 5};
2677     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 2), a_data);
2678     float b_data[] = {0, 1, 2};
2679     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2680     float answer_data[] = {5, 14};
2681     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 2, 1), answer_data);
2682     nntrainer::Tensor ret = a.dot(b, true, true);
2683     EXPECT_EQ(ret, answer);
2684   }
2685   {
2686     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2687     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2688     float b_data[] = {0, 1, 2};
2689     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2690     float answer_data[] = {5, 14, 23, 32};
2691     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data);
2692     nntrainer::Tensor ret = a.dot(b, false, false);
2693     EXPECT_EQ(ret, answer);
2694   }
2695   {
2696     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2697     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2698     float b_data[] = {0, 1, 2};
2699     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 1), b_data);
2700     float answer_data[] = {5, 14, 23, 32};
2701     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data);
2702     nntrainer::Tensor ret = a.dot(b, true, false);
2703     EXPECT_EQ(ret, answer);
2704   }
2705   {
2706     float a_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2707     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 4, 3), a_data);
2708     float b_data[] = {0, 1, 2};
2709     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2710     float answer_data[] = {5, 14, 23, 32};
2711     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data);
2712     nntrainer::Tensor ret = a.dot(b, false, true);
2713     EXPECT_EQ(ret, answer);
2714   }
2715   {
2716     float a_data[] = {0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11};
2717     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 4), a_data);
2718     float b_data[] = {0, 1, 2};
2719     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 1, 3), b_data);
2720     float answer_data[] = {5, 14, 23, 32};
2721     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 4, 1), answer_data);
2722     nntrainer::Tensor ret = a.dot(b, true, true);
2723     EXPECT_EQ(ret, answer);
2724   }
2725   {
2726     float a_data[] = {0, 1, 2};
2727     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2728     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2729     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2730     float answer_data[] = {20, 23, 26, 29};
2731     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2732     nntrainer::Tensor ret = a.dot(b, false, false);
2733     EXPECT_EQ(ret, answer);
2734   }
2735   {
2736     float a_data[] = {0, 1, 2};
2737     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2738     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2739     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2740     float answer_data[] = {20, 23, 26, 29};
2741     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2742     nntrainer::Tensor ret = a.dot(b, true, false);
2743     EXPECT_EQ(ret, answer);
2744   }
2745   {
2746     float a_data[] = {0, 1, 2};
2747     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2748     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2749     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2750     float answer_data[] = {20, 23, 26, 29};
2751     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2752     nntrainer::Tensor ret = a.dot(b, false, true);
2753     EXPECT_EQ(ret, answer);
2754   }
2755   {
2756     float a_data[] = {0, 1, 2};
2757     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2758     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2759     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2760     float answer_data[] = {20, 23, 26, 29};
2761     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2762     nntrainer::Tensor ret = a.dot(b, true, true);
2763     EXPECT_EQ(ret, answer);
2764   }
2765   {
2766     float a_data[] = {0, 1, 2};
2767     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2768     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2769     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2770     float answer_data[] = {20, 23, 26, 29};
2771     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2772     nntrainer::Tensor ret = a.dot(b, false, false);
2773     EXPECT_EQ(ret, answer);
2774   }
2775   {
2776     float a_data[] = {0, 1, 2};
2777     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2778     float b_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
2779     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 4), b_data);
2780     float answer_data[] = {20, 23, 26, 29};
2781     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2782     nntrainer::Tensor ret = a.dot(b, true, false);
2783     EXPECT_EQ(ret, answer);
2784   }
2785   {
2786     float a_data[] = {0, 1, 2};
2787     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2788     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2789     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2790     float answer_data[] = {20, 23, 26, 29};
2791     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2792     nntrainer::Tensor ret = a.dot(b, false, true);
2793     EXPECT_EQ(ret, answer);
2794   }
2795   {
2796     float a_data[] = {0, 1, 2};
2797     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2798     float b_data[] = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11};
2799     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 4, 3), b_data);
2800     float answer_data[] = {20, 23, 26, 29};
2801     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 4), answer_data);
2802     nntrainer::Tensor ret = a.dot(b, true, true);
2803     EXPECT_EQ(ret, answer);
2804   }
2805   {
2806     float a_data[] = {0, 1, 2};
2807     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2808     float b_data[] = {0, 1, 2, 3, 4, 5};
2809     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2810     float answer_data[] = {10, 13};
2811     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data);
2812     nntrainer::Tensor ret = a.dot(b, false, false);
2813     EXPECT_EQ(ret, answer);
2814   }
2815   {
2816     float a_data[] = {0, 1, 2};
2817     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2818     float b_data[] = {0, 1, 2, 3, 4, 5};
2819     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 3, 2), b_data);
2820     float answer_data[] = {10, 13};
2821     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data);
2822     nntrainer::Tensor ret = a.dot(b, true, false);
2823     EXPECT_EQ(ret, answer);
2824   }
2825   {
2826     float a_data[] = {0, 1, 2};
2827     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 1, 3), a_data);
2828     float b_data[] = {0, 2, 4, 1, 3, 5};
2829     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2830     float answer_data[] = {10, 13};
2831     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data);
2832     nntrainer::Tensor ret = a.dot(b, false, true);
2833     EXPECT_EQ(ret, answer);
2834   }
2835   {
2836     float a_data[] = {0, 1, 2};
2837     nntrainer::Tensor a(nntrainer::TensorDim(1, 1, 3, 1), a_data);
2838     float b_data[] = {0, 2, 4, 1, 3, 5};
2839     nntrainer::Tensor b(nntrainer::TensorDim(1, 1, 2, 3), b_data);
2840     float answer_data[] = {10, 13};
2841     nntrainer::Tensor answer(nntrainer::TensorDim(1, 1, 1, 2), answer_data);
2842     nntrainer::Tensor ret = a.dot(b, true, true);
2843     EXPECT_EQ(ret, answer);
2844   }
2845 }
2846
2847 TEST(nntrainer_Tensor, transpose_p) {
2848   nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2849
2850   /// plain transpose
2851   {
2852     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2853     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2854     float answer_data[] = {
2855       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
2856       14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
2857       28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
2858       42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
2859       56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
2860       70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
2861       84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
2862       98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
2863       112, 113, 114, 115, 116, 117, 118, 119};
2864     nntrainer::Tensor answer({3, 2, 4, 5}, answer_data);
2865     nntrainer::Tensor m = t.transpose("0:1:2");
2866     EXPECT_EQ(answer, m);
2867   }
2868   {
2869     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2870     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2871     float answer_data[] = {
2872       0,   5,   10,  15,  1,   6,   11,  16,  2,   7,   12,  17,  3,   8,
2873       13,  18,  4,   9,   14,  19,  20,  25,  30,  35,  21,  26,  31,  36,
2874       22,  27,  32,  37,  23,  28,  33,  38,  24,  29,  34,  39,  40,  45,
2875       50,  55,  41,  46,  51,  56,  42,  47,  52,  57,  43,  48,  53,  58,
2876       44,  49,  54,  59,  60,  65,  70,  75,  61,  66,  71,  76,  62,  67,
2877       72,  77,  63,  68,  73,  78,  64,  69,  74,  79,  80,  85,  90,  95,
2878       81,  86,  91,  96,  82,  87,  92,  97,  83,  88,  93,  98,  84,  89,
2879       94,  99,  100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117,
2880       103, 108, 113, 118, 104, 109, 114, 119};
2881     nntrainer::Tensor answer({3, 2, 5, 4}, answer_data);
2882     nntrainer::Tensor m = t.transpose("0:2:1");
2883     EXPECT_EQ(answer, m);
2884   }
2885   {
2886     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2887     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2888     float answer_data[] = {
2889       0,   1,   2,   3,   4,   20,  21,  22,  23,  24,  5,   6,   7,   8,
2890       9,   25,  26,  27,  28,  29,  10,  11,  12,  13,  14,  30,  31,  32,
2891       33,  34,  15,  16,  17,  18,  19,  35,  36,  37,  38,  39,  40,  41,
2892       42,  43,  44,  60,  61,  62,  63,  64,  45,  46,  47,  48,  49,  65,
2893       66,  67,  68,  69,  50,  51,  52,  53,  54,  70,  71,  72,  73,  74,
2894       55,  56,  57,  58,  59,  75,  76,  77,  78,  79,  80,  81,  82,  83,
2895       84,  100, 101, 102, 103, 104, 85,  86,  87,  88,  89,  105, 106, 107,
2896       108, 109, 90,  91,  92,  93,  94,  110, 111, 112, 113, 114, 95,  96,
2897       97,  98,  99,  115, 116, 117, 118, 119};
2898     nntrainer::Tensor answer({3, 4, 2, 5}, answer_data);
2899     nntrainer::Tensor m = t.transpose("1:0:2");
2900     EXPECT_EQ(answer, m);
2901   }
2902   {
2903     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2904     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2905     float answer_data[] = {
2906       0,  20,  1,  21,  2,  22,  3,  23,  4,  24,  5,  25,  6,  26,  7,  27,
2907       8,  28,  9,  29,  10, 30,  11, 31,  12, 32,  13, 33,  14, 34,  15, 35,
2908       16, 36,  17, 37,  18, 38,  19, 39,  40, 60,  41, 61,  42, 62,  43, 63,
2909       44, 64,  45, 65,  46, 66,  47, 67,  48, 68,  49, 69,  50, 70,  51, 71,
2910       52, 72,  53, 73,  54, 74,  55, 75,  56, 76,  57, 77,  58, 78,  59, 79,
2911       80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107,
2912       88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115,
2913       96, 116, 97, 117, 98, 118, 99, 119};
2914     nntrainer::Tensor answer({3, 4, 5, 2}, answer_data);
2915     nntrainer::Tensor m = t.transpose("1:2:0");
2916     EXPECT_EQ(answer, m);
2917   }
2918   {
2919     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2920     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2921     float answer_data[] = {
2922       0,  5,  10,  15,  20,  25,  30,  35, 1,  6,   11,  16,  21,  26,  31,
2923       36, 2,  7,   12,  17,  22,  27,  32, 37, 3,   8,   13,  18,  23,  28,
2924       33, 38, 4,   9,   14,  19,  24,  29, 34, 39,  40,  45,  50,  55,  60,
2925       65, 70, 75,  41,  46,  51,  56,  61, 66, 71,  76,  42,  47,  52,  57,
2926       62, 67, 72,  77,  43,  48,  53,  58, 63, 68,  73,  78,  44,  49,  54,
2927       59, 64, 69,  74,  79,  80,  85,  90, 95, 100, 105, 110, 115, 81,  86,
2928       91, 96, 101, 106, 111, 116, 82,  87, 92, 97,  102, 107, 112, 117, 83,
2929       88, 93, 98,  103, 108, 113, 118, 84, 89, 94,  99,  104, 109, 114, 119};
2930     nntrainer::Tensor answer({3, 5, 2, 4}, answer_data);
2931     nntrainer::Tensor m = t.transpose("2:0:1");
2932     EXPECT_EQ(answer, m);
2933   }
2934   {
2935     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2936     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2937     float answer_data[] = {
2938       0,  20,  5,  25,  10, 30,  15, 35,  1,  21,  6,  26,  11, 31,  16, 36,
2939       2,  22,  7,  27,  12, 32,  17, 37,  3,  23,  8,  28,  13, 33,  18, 38,
2940       4,  24,  9,  29,  14, 34,  19, 39,  40, 60,  45, 65,  50, 70,  55, 75,
2941       41, 61,  46, 66,  51, 71,  56, 76,  42, 62,  47, 67,  52, 72,  57, 77,
2942       43, 63,  48, 68,  53, 73,  58, 78,  44, 64,  49, 69,  54, 74,  59, 79,
2943       80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116,
2944       82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118,
2945       84, 104, 89, 109, 94, 114, 99, 119};
2946     nntrainer::Tensor answer({3, 5, 4, 2}, answer_data);
2947     nntrainer::Tensor m = t.transpose("2:1:0");
2948     EXPECT_EQ(answer, m);
2949   }
2950
2951   /// outplace transpose
2952   {
2953     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2954     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2955     nntrainer::Tensor m = ranged(3, 2, 4, 5);
2956     float answer_data[] = {
2957       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
2958       14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
2959       28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
2960       42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
2961       56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
2962       70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
2963       84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
2964       98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
2965       112, 113, 114, 115, 116, 117, 118, 119};
2966     nntrainer::Tensor answer({3, 2, 4, 5}, answer_data);
2967     t.transpose("0:1:2", m);
2968     EXPECT_EQ(answer, m);
2969   }
2970   {
2971     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2972     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2973     nntrainer::Tensor m = ranged(3, 2, 5, 4);
2974     float answer_data[] = {
2975       0,   5,   10,  15,  1,   6,   11,  16,  2,   7,   12,  17,  3,   8,
2976       13,  18,  4,   9,   14,  19,  20,  25,  30,  35,  21,  26,  31,  36,
2977       22,  27,  32,  37,  23,  28,  33,  38,  24,  29,  34,  39,  40,  45,
2978       50,  55,  41,  46,  51,  56,  42,  47,  52,  57,  43,  48,  53,  58,
2979       44,  49,  54,  59,  60,  65,  70,  75,  61,  66,  71,  76,  62,  67,
2980       72,  77,  63,  68,  73,  78,  64,  69,  74,  79,  80,  85,  90,  95,
2981       81,  86,  91,  96,  82,  87,  92,  97,  83,  88,  93,  98,  84,  89,
2982       94,  99,  100, 105, 110, 115, 101, 106, 111, 116, 102, 107, 112, 117,
2983       103, 108, 113, 118, 104, 109, 114, 119};
2984     nntrainer::Tensor answer({3, 2, 5, 4}, answer_data);
2985     t.transpose("0:2:1", m);
2986     EXPECT_EQ(answer, m);
2987   }
2988   {
2989     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
2990     nntrainer::Tensor t = ranged(3, 2, 4, 5);
2991     nntrainer::Tensor m = ranged(3, 4, 2, 5);
2992     float answer_data[] = {
2993       0,   1,   2,   3,   4,   20,  21,  22,  23,  24,  5,   6,   7,   8,
2994       9,   25,  26,  27,  28,  29,  10,  11,  12,  13,  14,  30,  31,  32,
2995       33,  34,  15,  16,  17,  18,  19,  35,  36,  37,  38,  39,  40,  41,
2996       42,  43,  44,  60,  61,  62,  63,  64,  45,  46,  47,  48,  49,  65,
2997       66,  67,  68,  69,  50,  51,  52,  53,  54,  70,  71,  72,  73,  74,
2998       55,  56,  57,  58,  59,  75,  76,  77,  78,  79,  80,  81,  82,  83,
2999       84,  100, 101, 102, 103, 104, 85,  86,  87,  88,  89,  105, 106, 107,
3000       108, 109, 90,  91,  92,  93,  94,  110, 111, 112, 113, 114, 95,  96,
3001       97,  98,  99,  115, 116, 117, 118, 119};
3002     nntrainer::Tensor answer({3, 4, 2, 5}, answer_data);
3003     t.transpose("1:0:2", m);
3004     EXPECT_EQ(answer, m);
3005   }
3006   {
3007     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3008     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3009     nntrainer::Tensor m = ranged(3, 4, 5, 2);
3010     float answer_data[] = {
3011       0,  20,  1,  21,  2,  22,  3,  23,  4,  24,  5,  25,  6,  26,  7,  27,
3012       8,  28,  9,  29,  10, 30,  11, 31,  12, 32,  13, 33,  14, 34,  15, 35,
3013       16, 36,  17, 37,  18, 38,  19, 39,  40, 60,  41, 61,  42, 62,  43, 63,
3014       44, 64,  45, 65,  46, 66,  47, 67,  48, 68,  49, 69,  50, 70,  51, 71,
3015       52, 72,  53, 73,  54, 74,  55, 75,  56, 76,  57, 77,  58, 78,  59, 79,
3016       80, 100, 81, 101, 82, 102, 83, 103, 84, 104, 85, 105, 86, 106, 87, 107,
3017       88, 108, 89, 109, 90, 110, 91, 111, 92, 112, 93, 113, 94, 114, 95, 115,
3018       96, 116, 97, 117, 98, 118, 99, 119};
3019     nntrainer::Tensor answer({3, 4, 5, 2}, answer_data);
3020     t.transpose("1:2:0", m);
3021     EXPECT_EQ(answer, m);
3022   }
3023   {
3024     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3025     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3026     nntrainer::Tensor m = ranged(3, 5, 2, 4);
3027     float answer_data[] = {
3028       0,  5,  10,  15,  20,  25,  30,  35, 1,  6,   11,  16,  21,  26,  31,
3029       36, 2,  7,   12,  17,  22,  27,  32, 37, 3,   8,   13,  18,  23,  28,
3030       33, 38, 4,   9,   14,  19,  24,  29, 34, 39,  40,  45,  50,  55,  60,
3031       65, 70, 75,  41,  46,  51,  56,  61, 66, 71,  76,  42,  47,  52,  57,
3032       62, 67, 72,  77,  43,  48,  53,  58, 63, 68,  73,  78,  44,  49,  54,
3033       59, 64, 69,  74,  79,  80,  85,  90, 95, 100, 105, 110, 115, 81,  86,
3034       91, 96, 101, 106, 111, 116, 82,  87, 92, 97,  102, 107, 112, 117, 83,
3035       88, 93, 98,  103, 108, 113, 118, 84, 89, 94,  99,  104, 109, 114, 119};
3036     nntrainer::Tensor answer({3, 5, 2, 4}, answer_data);
3037     t.transpose("2:0:1", m);
3038     EXPECT_EQ(answer, m);
3039   }
3040   {
3041     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3042     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3043     nntrainer::Tensor m = ranged(3, 5, 4, 2);
3044     float answer_data[] = {
3045       0,  20,  5,  25,  10, 30,  15, 35,  1,  21,  6,  26,  11, 31,  16, 36,
3046       2,  22,  7,  27,  12, 32,  17, 37,  3,  23,  8,  28,  13, 33,  18, 38,
3047       4,  24,  9,  29,  14, 34,  19, 39,  40, 60,  45, 65,  50, 70,  55, 75,
3048       41, 61,  46, 66,  51, 71,  56, 76,  42, 62,  47, 67,  52, 72,  57, 77,
3049       43, 63,  48, 68,  53, 73,  58, 78,  44, 64,  49, 69,  54, 74,  59, 79,
3050       80, 100, 85, 105, 90, 110, 95, 115, 81, 101, 86, 106, 91, 111, 96, 116,
3051       82, 102, 87, 107, 92, 112, 97, 117, 83, 103, 88, 108, 93, 113, 98, 118,
3052       84, 104, 89, 109, 94, 114, 99, 119};
3053     nntrainer::Tensor answer({3, 5, 4, 2}, answer_data);
3054     t.transpose("2:1:0", m);
3055     EXPECT_EQ(answer, m);
3056   }
3057 }
3058
3059 TEST(nntrainer_Tensor, tranpose_dimension_not_match_n) {
3060   nntrainer::Tensor a(3, 2, 4, 5);
3061   nntrainer::Tensor b(3, 1, 2, 3);
3062
3063   EXPECT_THROW(a.transpose("0:1:2", b), std::invalid_argument);
3064 }
3065
3066 TEST(nntrainer_Tensor, set_01_p) {
3067   nntrainer::Tensor tensor = nntrainer::Tensor(1, 1, 1, 1);
3068
3069   tensor.setZero();
3070   EXPECT_EQ(tensor.getValue(0, 0, 0, 0), 0.0);
3071
3072   tensor.setRandUniform(-0.5, 0);
3073   float val = tensor.getValue(0, 0, 0, 0);
3074   EXPECT_TRUE(val >= -0.5 && val < 0);
3075 }
3076
3077 TEST(nntrainer_Tensor, save_read_01_p) {
3078   int batch = 3;
3079   int channel = 4;
3080   int height = 5;
3081   int width = 6;
3082   nntrainer::Tensor target(3, 4, 5, 6);
3083   nntrainer::Tensor readed(3, 4, 5, 6);
3084
3085   GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) +
3086                            k * (width) + l + 1);
3087
3088   std::ofstream save_file("save.bin", std::ios::out | std::ios::binary);
3089   target.save(save_file);
3090   save_file.close();
3091
3092   std::ifstream read_file("save.bin");
3093   readed.read(read_file);
3094   read_file.close();
3095
3096   EXPECT_EQ(target, readed);
3097
3098   int status = std::remove("save.bin");
3099
3100   ASSERT_EQ(status, 0);
3101 }
3102
3103 TEST(nntrainer_Tensor, save_read_01_n) {
3104   int batch = 3;
3105   int channel = 4;
3106   int height = 5;
3107   int width = 6;
3108   nntrainer::Tensor target(3, 4, 5, 6);
3109   nntrainer::Tensor readed(3, 4, 1, 1);
3110
3111   GEN_TEST_INPUT(target, i * (channel * width * height) + j * (height * width) +
3112                            k * (width) + l + 1);
3113
3114   std::ofstream save_file("save.bin", std::ios::out | std::ios::binary);
3115   target.save(save_file);
3116   save_file.close();
3117
3118   std::ifstream read_file("save.bin");
3119   readed.read(read_file);
3120   read_file.close();
3121
3122   EXPECT_NE(target, readed);
3123
3124   int status = std::remove("save.bin");
3125
3126   ASSERT_EQ(status, 0);
3127 }
3128
3129 TEST(nntrainer_Tensor, copy_and_shares_variable_p) {
3130   nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6);
3131   nntrainer::Tensor B = A.clone();
3132   nntrainer::Tensor C = A;
3133
3134   C.setValue(1, 1, 1, 1, 2.0f);
3135
3136   EXPECT_EQ(A, C);
3137   EXPECT_NE(B, C);
3138
3139   C.reshape(nntrainer::TensorDim(3, 4, 6, 5));
3140   EXPECT_EQ(A.getDim(), B.getDim());
3141   EXPECT_NE(A.getDim(), C.getDim());
3142 }
3143
3144 TEST(nntrainer_Tensor, reshape_n_01) {
3145   nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6);
3146
3147   EXPECT_THROW(A.reshape(nntrainer::TensorDim(9, 9, 9, 9)),
3148                std::invalid_argument);
3149 }
3150
3151 TEST(nntrainer_Tensor, reshape_n_02) {
3152   nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6);
3153   nntrainer::TensorDim A_dim = A.getDim();
3154
3155   /** Changing the dim of a tensor only affects local copy of the dim */
3156   A_dim.setTensorDim(1, 100);
3157   EXPECT_EQ(A_dim.getTensorDim(1), 100u);
3158
3159   nntrainer::TensorDim A_dim_2 = A.getDim();
3160   EXPECT_EQ(A_dim_2.getTensorDim(1), 4u);
3161 }
3162
3163 TEST(nntrainer_Tensor, copy_and_reshape_n) {
3164   nntrainer::Tensor A = constant(1.0f, 3, 4, 5, 6);
3165   nntrainer::Tensor B = A;
3166   nntrainer::Tensor C = A.clone();
3167
3168   EXPECT_THROW(B.reshape(nntrainer::TensorDim(9, 9, 9, 9)),
3169                std::invalid_argument);
3170 }
3171
3172 /// @note this test case demonstrates it is dangerous to use sharedConstTensor
3173 /// to const correct the inner data.
3174 TEST(nntrainer_Tensor, constructor_from_shared_const_ptr_shares_variable_n) {
3175   nntrainer::sharedConstTensor A =
3176     MAKE_SHARED_TENSOR(constant(1.0f, 3, 4, 5, 6));
3177
3178   nntrainer::Tensor B = *A;
3179   nntrainer::Tensor C = A->clone();
3180
3181   B.setValue(2, 3, 4, 5, 2.0f);
3182   EXPECT_EQ(*A, B);
3183   EXPECT_NE(*A, C);
3184
3185   C.reshape(nntrainer::TensorDim(3, 4, 6, 5));
3186   EXPECT_EQ(A->getDim(), B.getDim());
3187   EXPECT_NE(A->getDim(), C.getDim());
3188 }
3189
3190 TEST(nntrainer_Tensor, print_small_size) {
3191   nntrainer::Tensor target = constant(1.0, 3, 1, 2, 3);
3192
3193   std::stringstream ss, expected;
3194   ss << target;
3195
3196   expected << '<' << typeid(target).name() << " at " << &target << ">\n"
3197            << "data addr: " << target.getData() << '\n'
3198            << "Shape: 3:1:2:3\n"
3199            << "         1          1          1 \n"
3200            << "         1          1          1 \n"
3201            << "\n"
3202            << "-------\n"
3203            << "         1          1          1 \n"
3204            << "         1          1          1 \n"
3205            << "\n"
3206            << "-------\n"
3207            << "         1          1          1 \n"
3208            << "         1          1          1 \n"
3209            << "\n"
3210            << "-------\n";
3211
3212   EXPECT_EQ(ss.str(), expected.str());
3213 }
3214
3215 // TEST(nntrainer_Tensor, print_large_size) {
3216 //   nntrainer::Tensor target = constant(1.2, 3, 10, 10, 10);
3217
3218 //   std::stringstream ss, expected;
3219
3220 //   expected << '<' << typeid(target).name() << " at " << &target << ">\n"
3221 //            << "data addr: " << target.getData() << '\n'
3222 //            << "Shape: 3:10:10:10\n"
3223 //            << "[1.2 1.2 1.2 ... 1.2 1.2 1.2]\n";
3224 //   ss << target;
3225
3226 //   EXPECT_EQ(ss.str(), expected.str());
3227 // }
3228
3229 TEST(nntrainer_Tensor, DISABLED_equation_test_01_p) {
3230   nntrainer::Tensor a, b, c;
3231   nntrainer::Tensor ret1, ret2;
3232
3233   a = randUniform(4, 6, 7, 3, -100, 100);
3234   b = randUniform(4, 6, 7, 3, -100, 100);
3235   c = randUniform(4, 6, 7, 3, -100, 100);
3236
3237   ret1 = a.subtract(b).multiply(c);
3238   ret2 = a.multiply(c).subtract(b.multiply(c));
3239
3240   float *data1 = ret1.getData();
3241   float *data2 = ret2.getData();
3242   EXPECT_EQ(ret1, ret2);
3243
3244   for (unsigned int i = 0; i < ret1.size(); ++i) {
3245     EXPECT_FLOAT_EQ(data1[i], data2[i]);
3246   }
3247 }
3248
3249 TEST(nntrainer_Tensor, fill_p) {
3250   /// same dimension, buffer size
3251   {
3252     nntrainer::Tensor target(3, 2, 4, 5);
3253     nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f);
3254     target.fill(original, false);
3255
3256     EXPECT_EQ(target, original);
3257   }
3258
3259   /// same dimension, buffer size is different (not tested)
3260   {
3261     /// there is no way to make non contiguous tensor publicily yet
3262     EXPECT_TRUE(true);
3263   }
3264
3265   /// uninitialized with initialized flag is true
3266   {
3267     nntrainer::Tensor target;
3268     nntrainer::Tensor original = randUniform(3, 2, 4, 5, -1.0f, 1.0f);
3269     target.fill(original, true);
3270
3271     EXPECT_EQ(target, original);
3272   }
3273 }
3274
3275 TEST(nntrainer_Tensor, fill_uninitialized_n) {
3276   nntrainer::Tensor target;
3277   nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f);
3278   EXPECT_THROW(target.fill(original, false), std::invalid_argument);
3279 }
3280
3281 TEST(nntrainer_Tensor, fill_different_dimension_n) {
3282   nntrainer::Tensor target(3, 1, 3, 2);
3283   nntrainer::Tensor original = randUniform(3, 1, 2, 3, -1.0f, 1.0f);
3284   EXPECT_THROW(target.fill(original, false), std::invalid_argument);
3285 }
3286
3287 TEST(nntrainer_Tensor, DISABLED_fill_non_contiguous_n) {
3288   /// there is no way to make non contiguous tensor publicily yet
3289   EXPECT_TRUE(false);
3290 }
3291
3292 TEST(nntrainer_Tensor, DISABLED_fill_different_buffer_size_n) {
3293   /// there is no way to make same dimension, diffrent buffersized tensor
3294   /// publicily yet
3295   EXPECT_TRUE(false);
3296 }
3297
3298 TEST(nntrainer_Tensor, empty_01) {
3299   nntrainer::Tensor t;
3300
3301   EXPECT_TRUE(t.empty());
3302 }
3303
3304 TEST(nntrainer_Tensor, empty_02) {
3305   nntrainer::Tensor t({1, 2, 3, 4}, false);
3306
3307   EXPECT_FALSE(t.empty());
3308 }
3309
3310 TEST(nntrainer_Tensor, empty_03) {
3311   nntrainer::Tensor t({1, 2, 3, 4}, true);
3312
3313   EXPECT_FALSE(t.empty());
3314 }
3315
3316 TEST(nntrainer_Tensor, allocate_01_n) {
3317   nntrainer::Tensor t;
3318   EXPECT_FALSE(t.isAllocated());
3319
3320   t.allocate();
3321   EXPECT_FALSE(t.isAllocated());
3322 }
3323
3324 TEST(nntrainer_Tensor, allocate_02_p) {
3325   nntrainer::Tensor t({1, 2, 3, 4}, false);
3326   EXPECT_FALSE(t.isAllocated());
3327
3328   t.allocate();
3329   EXPECT_TRUE(t.isAllocated());
3330 }
3331
3332 TEST(nntrainer_Tensor, allocate_03_p) {
3333   nntrainer::Tensor t({1, 2, 3, 4}, true);
3334   EXPECT_TRUE(t.isAllocated());
3335
3336   t.allocate();
3337   EXPECT_TRUE(t.isAllocated());
3338 }
3339
3340 TEST(nntrainer_Tensor, initialize_01_p) {
3341   nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES);
3342
3343   nntrainer::Tensor golden(1, 2, 3, 4);
3344   golden.setValue(1);
3345
3346   EXPECT_EQ(golden, t);
3347 }
3348
3349 TEST(nntrainer_Tensor, initialize_02_p) {
3350   nntrainer::Tensor t({1, 2, 3, 4}, true);
3351
3352   nntrainer::Tensor golden(1, 2, 3, 4);
3353   golden.setValue(1);
3354
3355   EXPECT_NE(golden, t);
3356
3357   t.initialize(nntrainer::Tensor::Initializer::ONES);
3358   EXPECT_EQ(golden, t);
3359 }
3360
3361 TEST(nntrainer_Tensor, initialize_03_p) {
3362   nntrainer::Tensor t({1, 2, 3, 4}, false,
3363                       nntrainer::Tensor::Initializer::ONES);
3364   t.allocate();
3365
3366   nntrainer::Tensor golden(1, 2, 3, 4);
3367   golden.setValue(1);
3368
3369   EXPECT_EQ(golden, t);
3370 }
3371
3372 TEST(nntrainer_Tensor, initialize_04_p) {
3373   nntrainer::Tensor t({1, 2, 3, 4}, false);
3374   t.initialize(nntrainer::Tensor::Initializer::ONES);
3375   t.allocate();
3376
3377   nntrainer::Tensor golden(1, 2, 3, 4);
3378   golden.setValue(1);
3379
3380   EXPECT_EQ(golden, t);
3381 }
3382
3383 TEST(nntrainer_Tensor, initialize_05_p) {
3384   nntrainer::Tensor t({1, 2, 3, 4}, false);
3385   t.allocate();
3386
3387   nntrainer::Tensor golden(1, 2, 3, 4);
3388   golden.setValue(1.f);
3389
3390   /**
3391    * Ideally, it should be NE, but it can be equal due to no initialization
3392    * EXPECT_NE(golden, t);
3393    */
3394
3395   t.initialize(nntrainer::Tensor::Initializer::ONES);
3396   EXPECT_EQ(golden, t);
3397 }
3398
3399 TEST(nntrainer_Tensor, initialize_06_n) {
3400   nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES);
3401   nntrainer::Tensor golden({1, 2, 3, 4}, true,
3402                            nntrainer::Tensor::Initializer::ZEROS);
3403
3404   EXPECT_NE(golden, t);
3405
3406   golden.initialize(nntrainer::Tensor::Initializer::ONES);
3407   EXPECT_EQ(golden, t);
3408 }
3409
3410 TEST(nntrainer_Tensor, initialize_07_p) {
3411   nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES);
3412
3413   nntrainer::Tensor golden(1, 2, 3, 4);
3414   golden.setValue(1);
3415
3416   EXPECT_EQ(golden, t);
3417
3418   t.setValue(0, 0, 0, 0, 0);
3419   t.setValue(0, 0, 0, t.size() - 1, 0);
3420   EXPECT_NE(golden, t);
3421
3422   t.initialize();
3423   EXPECT_EQ(golden, t);
3424 }
3425
3426 TEST(nntrainer_Tensor, initialize_08_p) {
3427   nntrainer::Tensor t({1, 2, 3, 4}, true, nntrainer::Tensor::Initializer::ONES);
3428
3429   nntrainer::Tensor golden(1, 2, 3, 4, nntrainer::Tformat::NCHW, nntrainer::DataType::FP32);
3430   golden.setValue(1);
3431   EXPECT_EQ(golden, t);
3432
3433   t.initialize(nntrainer::Tensor::Initializer::HE_NORMAL);
3434   EXPECT_NE(golden, t);
3435
3436
3437   t.initialize();
3438   EXPECT_NE(golden, t);
3439
3440   t.initialize(nntrainer::Tensor::Initializer::ONES);
3441   EXPECT_EQ(golden, t);
3442
3443   t.initialize();
3444   EXPECT_EQ(golden, t);
3445 }
3446
3447 TEST(nntrainer_Tensor, split_01_p) {
3448   {
3449     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3450     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3451     std::vector<nntrainer::Tensor> answer;
3452     answer.reserve(3);
3453     {
3454       float answer_data[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
3455                              10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
3456                              20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
3457                              30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
3458       answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data);
3459     }
3460     {
3461       float answer_data[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
3462                              50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
3463                              60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
3464                              70, 71, 72, 73, 74, 75, 76, 77, 78, 79};
3465       answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data);
3466     }
3467     {
3468       float answer_data[] = {80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
3469                              90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
3470                              100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
3471                              110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3472       answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data);
3473     }
3474     EXPECT_EQ(t.split(3, 0), answer);
3475   }
3476   {
3477     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3478     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3479     std::vector<nntrainer::Tensor> answer;
3480     answer.reserve(2);
3481     {
3482       float answer_data[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
3483                              12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43,
3484                              44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
3485                              56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87,
3486                              88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99};
3487       answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data);
3488     }
3489     {
3490       float answer_data[] = {20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
3491                              30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
3492                              60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
3493                              70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
3494                              100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
3495                              110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3496       answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data);
3497     }
3498     EXPECT_EQ(t.split(2, 1), answer);
3499   }
3500   {
3501     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3502     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3503     std::vector<nntrainer::Tensor> answer;
3504     answer.reserve(2);
3505     {
3506       float answer_data[] = {
3507         0,  1,  2,  3,  4,  5,   6,   7,   8,   9,   20,  21,  22,  23,  24,
3508         25, 26, 27, 28, 29, 40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
3509         60, 61, 62, 63, 64, 65,  66,  67,  68,  69,  80,  81,  82,  83,  84,
3510         85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109};
3511       answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data);
3512     }
3513     {
3514       float answer_data[] = {
3515         10, 11, 12, 13, 14, 15,  16,  17,  18,  19,  30,  31,  32,  33,  34,
3516         35, 36, 37, 38, 39, 50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
3517         70, 71, 72, 73, 74, 75,  76,  77,  78,  79,  90,  91,  92,  93,  94,
3518         95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3519       answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data);
3520     }
3521     EXPECT_EQ(t.split(2, 2), answer);
3522   }
3523   {
3524     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3525     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3526     std::vector<nntrainer::Tensor> answer;
3527     answer.reserve(5);
3528     {
3529       float answer_data[] = {0,  5,  10, 15, 20,  25,  30,  35,
3530                              40, 45, 50, 55, 60,  65,  70,  75,
3531                              80, 85, 90, 95, 100, 105, 110, 115};
3532       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3533     }
3534     {
3535       float answer_data[] = {1,  6,  11, 16, 21,  26,  31,  36,
3536                              41, 46, 51, 56, 61,  66,  71,  76,
3537                              81, 86, 91, 96, 101, 106, 111, 116};
3538       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3539     }
3540     {
3541       float answer_data[] = {2,  7,  12, 17, 22,  27,  32,  37,
3542                              42, 47, 52, 57, 62,  67,  72,  77,
3543                              82, 87, 92, 97, 102, 107, 112, 117};
3544       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3545     }
3546     {
3547       float answer_data[] = {3,  8,  13, 18, 23,  28,  33,  38,
3548                              43, 48, 53, 58, 63,  68,  73,  78,
3549                              83, 88, 93, 98, 103, 108, 113, 118};
3550       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3551     }
3552     {
3553       float answer_data[] = {4,  9,  14, 19, 24,  29,  34,  39,
3554                              44, 49, 54, 59, 64,  69,  74,  79,
3555                              84, 89, 94, 99, 104, 109, 114, 119};
3556       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3557     }
3558     EXPECT_EQ(t.split(5, 3), answer);
3559   }
3560   {
3561     nntrainer::TensorDim ref_dim(1, 1, 4, 6);
3562     nntrainer::Tensor t = ranged(1, 1, 4, 6);
3563     std::vector<nntrainer::Tensor> answer;
3564     answer.reserve(2);
3565     {
3566       float answer_data[] = {0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20};
3567       answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data);
3568     }
3569     {
3570       float answer_data[] = {3, 4, 5, 9, 10, 11, 15, 16, 17, 21, 22, 23};
3571       answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data);
3572     }
3573     EXPECT_EQ(t.split(2, 3), answer);
3574   }
3575 }
3576
3577 TEST(nntrainer_Tensor, split_02_n) {
3578   nntrainer::Tensor t(1, 1, 1, 1);
3579   EXPECT_THROW(t.split(0, 0), std::invalid_argument);
3580 }
3581
3582 TEST(nntrainer_Tensor, split_03_n) {
3583   nntrainer::Tensor t(3, 1, 1, 1);
3584   EXPECT_THROW(t.split(2, 0), std::invalid_argument);
3585 }
3586
3587 TEST(nntrainer_Tensor, split_04_p) {
3588   {
3589     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3590     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3591     std::vector<nntrainer::Tensor> answer;
3592     answer.reserve(2);
3593     {
3594       float answer_data[] = {
3595         0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
3596         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3597         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
3598         48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
3599         64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79};
3600       answer.emplace_back(ml::train::TensorDim{2, 2, 4, 5}, answer_data);
3601     }
3602     {
3603       float answer_data[] = {80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
3604                              90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
3605                              100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
3606                              110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3607       answer.emplace_back(ml::train::TensorDim{1, 2, 4, 5}, answer_data);
3608     }
3609     EXPECT_EQ(t.split({2, 1}, 0), answer);
3610   }
3611   {
3612     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3613     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3614     std::vector<nntrainer::Tensor> answer;
3615     answer.reserve(2);
3616     {
3617       float answer_data[] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
3618                              12, 13, 14, 15, 16, 17, 18, 19, 40, 41, 42, 43,
3619                              44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
3620                              56, 57, 58, 59, 80, 81, 82, 83, 84, 85, 86, 87,
3621                              88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99};
3622       answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data);
3623     }
3624     {
3625       float answer_data[] = {20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
3626                              30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
3627                              60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
3628                              70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
3629                              100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
3630                              110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3631       answer.emplace_back(ml::train::TensorDim{3, 1, 4, 5}, answer_data);
3632     }
3633     EXPECT_EQ(t.split({1, 1}, 1), answer);
3634   }
3635   {
3636     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3637     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3638     std::vector<nntrainer::Tensor> answer;
3639     answer.reserve(2);
3640     {
3641       float answer_data[] = {
3642         0,  1,  2,  3,  4,  5,   6,   7,   8,   9,   20,  21,  22,  23,  24,
3643         25, 26, 27, 28, 29, 40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
3644         60, 61, 62, 63, 64, 65,  66,  67,  68,  69,  80,  81,  82,  83,  84,
3645         85, 86, 87, 88, 89, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109};
3646       answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data);
3647     }
3648     {
3649       float answer_data[] = {
3650         10, 11, 12, 13, 14, 15,  16,  17,  18,  19,  30,  31,  32,  33,  34,
3651         35, 36, 37, 38, 39, 50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
3652         70, 71, 72, 73, 74, 75,  76,  77,  78,  79,  90,  91,  92,  93,  94,
3653         95, 96, 97, 98, 99, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119};
3654       answer.emplace_back(ml::train::TensorDim{3, 2, 2, 5}, answer_data);
3655     }
3656     EXPECT_EQ(t.split({2, 2}, 2), answer);
3657   }
3658   {
3659     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3660     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3661     std::vector<nntrainer::Tensor> answer;
3662     answer.reserve(3);
3663     {
3664       float answer_data[] = {0,  5,  10, 15, 20,  25,  30,  35,
3665                              40, 45, 50, 55, 60,  65,  70,  75,
3666                              80, 85, 90, 95, 100, 105, 110, 115};
3667       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3668     }
3669     {
3670       float answer_data[] = {
3671         1,   2,   3,   6,   7,   8,   11,  12,  13,  16,  17,  18, 21, 22, 23,
3672         26,  27,  28,  31,  32,  33,  36,  37,  38,  41,  42,  43, 46, 47, 48,
3673         51,  52,  53,  56,  57,  58,  61,  62,  63,  66,  67,  68, 71, 72, 73,
3674         76,  77,  78,  81,  82,  83,  86,  87,  88,  91,  92,  93, 96, 97, 98,
3675         101, 102, 103, 106, 107, 108, 111, 112, 113, 116, 117, 118};
3676       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data);
3677     }
3678     {
3679       float answer_data[] = {4,  9,  14, 19, 24,  29,  34,  39,
3680                              44, 49, 54, 59, 64,  69,  74,  79,
3681                              84, 89, 94, 99, 104, 109, 114, 119};
3682       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3683     }
3684     EXPECT_EQ(t.split({1, 3, 1}, 3), answer);
3685   }
3686   {
3687     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3688     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3689     std::vector<nntrainer::Tensor> answer;
3690     answer.reserve(3);
3691     {
3692       float answer_data[] = {
3693         0,  1,  5,  6,  10, 11, 15, 16, 20,  21,  25,  26,  30,  31,  35,  36,
3694         40, 41, 45, 46, 50, 51, 55, 56, 60,  61,  65,  66,  70,  71,  75,  76,
3695         80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116};
3696       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data);
3697     }
3698     {
3699       float answer_data[] = {
3700         2,  3,  7,  8,  12, 13, 17, 18, 22,  23,  27,  28,  32,  33,  37,  38,
3701         42, 43, 47, 48, 52, 53, 57, 58, 62,  63,  67,  68,  72,  73,  77,  78,
3702         82, 83, 87, 88, 92, 93, 97, 98, 102, 103, 107, 108, 112, 113, 117, 118};
3703       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data);
3704     }
3705     {
3706       float answer_data[] = {4,  9,  14, 19, 24,  29,  34,  39,
3707                              44, 49, 54, 59, 64,  69,  74,  79,
3708                              84, 89, 94, 99, 104, 109, 114, 119};
3709       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 1}, answer_data);
3710     }
3711     EXPECT_EQ(t.split({2, 2, 1}, 3), answer);
3712   }
3713   {
3714     nntrainer::TensorDim ref_dim(3, 2, 4, 5);
3715     nntrainer::Tensor t = ranged(3, 2, 4, 5);
3716     std::vector<nntrainer::Tensor> answer;
3717     answer.reserve(2);
3718     {
3719       float answer_data[] = {
3720         0,  1,  5,  6,  10, 11, 15, 16, 20,  21,  25,  26,  30,  31,  35,  36,
3721         40, 41, 45, 46, 50, 51, 55, 56, 60,  61,  65,  66,  70,  71,  75,  76,
3722         80, 81, 85, 86, 90, 91, 95, 96, 100, 101, 105, 106, 110, 111, 115, 116};
3723       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 2}, answer_data);
3724     }
3725     {
3726       float answer_data[] = {
3727         2,   3,   4,   7,   8,   9,   12,  13,  14,  17,  18,  19, 22, 23, 24,
3728         27,  28,  29,  32,  33,  34,  37,  38,  39,  42,  43,  44, 47, 48, 49,
3729         52,  53,  54,  57,  58,  59,  62,  63,  64,  67,  68,  69, 72, 73, 74,
3730         77,  78,  79,  82,  83,  84,  87,  88,  89,  92,  93,  94, 97, 98, 99,
3731         102, 103, 104, 107, 108, 109, 112, 113, 114, 117, 118, 119};
3732       answer.emplace_back(ml::train::TensorDim{3, 2, 4, 3}, answer_data);
3733     }
3734     EXPECT_EQ(t.split({2, 3}, 3), answer);
3735   }
3736   {
3737     nntrainer::TensorDim ref_dim(1, 1, 4, 6);
3738     nntrainer::Tensor t = ranged(1, 1, 4, 6);
3739     std::vector<nntrainer::Tensor> answer;
3740     answer.reserve(3);
3741     {
3742       float answer_data[] = {0, 6, 12, 18};
3743       answer.emplace_back(ml::train::TensorDim{1, 1, 4, 1}, answer_data);
3744     }
3745     {
3746       float answer_data[] = {1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21};
3747       answer.emplace_back(ml::train::TensorDim{1, 1, 4, 3}, answer_data);
3748     }
3749     {
3750       float answer_data[] = {4, 5, 10, 11, 16, 17, 22, 23};
3751       answer.emplace_back(ml::train::TensorDim{1, 1, 4, 2}, answer_data);
3752     }
3753     EXPECT_EQ(t.split({1, 3, 2}, 3), answer);
3754   }
3755 }
3756
3757 TEST(nntrainer_Tensor, split_05_n) {
3758   nntrainer::Tensor t(3, 1, 1, 1);
3759   EXPECT_THROW(t.split({1, 1}, 0), std::invalid_argument);
3760 }
3761
3762 TEST(nntrainer_Tensor, split_06_n) {
3763   nntrainer::Tensor t(3, 1, 1, 1);
3764   EXPECT_THROW(t.split({2, 0, 1}, 0), std::invalid_argument);
3765 }
3766
3767 TEST(nntrainer_Tensor, split_07_n) {
3768   nntrainer::Tensor t(3, 1, 1, 1);
3769   EXPECT_THROW(t.split({}, 0), std::invalid_argument);
3770 }
3771
3772 TEST(nntrainer_Tensor, cat_01_p) {
3773   {
3774     std::vector<nntrainer::Tensor> inputs;
3775     inputs.reserve(2);
3776     inputs.emplace_back(ranged(2, 1, 1, 2));
3777     inputs.emplace_back(ranged(2, 2, 1, 2));
3778     float answer_data[] = {0, 1, 0, 1, 2, 3, 2, 3, 4, 5, 6, 7};
3779     nntrainer::Tensor answer(ml::train::TensorDim{2, 3, 1, 2}, answer_data);
3780     EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer);
3781   }
3782   {
3783     std::vector<nntrainer::Tensor> inputs;
3784     inputs.reserve(2);
3785     inputs.emplace_back(ranged(3, 2, 4, 5));
3786     inputs.emplace_back(ranged(2, 2, 4, 5));
3787     float answer_data[] = {
3788       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
3789       15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
3790       30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
3791       45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
3792       60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
3793       75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
3794       90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104,
3795       105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
3796       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,
3797       15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
3798       30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,
3799       45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
3800       60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
3801       75,  76,  77,  78,  79};
3802     nntrainer::Tensor answer(ml::train::TensorDim{5, 2, 4, 5}, answer_data);
3803     EXPECT_EQ(nntrainer::Tensor::cat(inputs, 0), answer);
3804   }
3805   {
3806     std::vector<nntrainer::Tensor> inputs;
3807     inputs.reserve(2);
3808     inputs.emplace_back(ranged(3, 3, 4, 5));
3809     inputs.emplace_back(ranged(3, 2, 4, 5));
3810     float answer_data[] = {
3811       0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
3812       14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
3813       28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
3814       42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
3815       56,  57,  58,  59,  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
3816       10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,
3817       24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,
3818       38,  39,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,
3819       72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,
3820       86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
3821       100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
3822       114, 115, 116, 117, 118, 119, 40,  41,  42,  43,  44,  45,  46,  47,
3823       48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
3824       62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,
3825       76,  77,  78,  79,  120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
3826       130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
3827       144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
3828       158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
3829       172, 173, 174, 175, 176, 177, 178, 179, 80,  81,  82,  83,  84,  85,
3830       86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,
3831       100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
3832       114, 115, 116, 117, 118, 119};
3833     nntrainer::Tensor answer(ml::train::TensorDim{3, 5, 4, 5}, answer_data);
3834     EXPECT_EQ(nntrainer::Tensor::cat(inputs, 1), answer);
3835   }
3836   {
3837     std::vector<nntrainer::Tensor> inputs;
3838     inputs.reserve(2);
3839     inputs.emplace_back(ranged(3, 2, 1, 5));
3840     inputs.emplace_back(ranged(3, 2, 2, 5));
3841     float answer_data[] = {
3842       0,  1,  2,  3,  4,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  5,  6,  7,
3843       8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 20,
3844       21, 22, 23, 24, 25, 26, 27, 28, 29, 15, 16, 17, 18, 19, 30, 31, 32, 33,
3845       34, 35, 36, 37, 38, 39, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45, 46,
3846       47, 48, 49, 25, 26, 27, 28, 29, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59};
3847     nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 3, 5}, answer_data);
3848     EXPECT_EQ(nntrainer::Tensor::cat(inputs, 2), answer);
3849   }
3850   {
3851     std::vector<nntrainer::Tensor> inputs;
3852     inputs.reserve(3);
3853     inputs.emplace_back(ranged(3, 2, 4, 1));
3854     inputs.emplace_back(ranged(3, 2, 4, 3));
3855     inputs.emplace_back(ranged(3, 2, 4, 2));
3856     float answer_data[] = {
3857       0,  0,  1,  2,  0,  1,  1,  3,  4,  5,  2,  3,  2,  6,  7,  8,  4,  5,
3858       3,  9,  10, 11, 6,  7,  4,  12, 13, 14, 8,  9,  5,  15, 16, 17, 10, 11,
3859       6,  18, 19, 20, 12, 13, 7,  21, 22, 23, 14, 15, 8,  24, 25, 26, 16, 17,
3860       9,  27, 28, 29, 18, 19, 10, 30, 31, 32, 20, 21, 11, 33, 34, 35, 22, 23,
3861       12, 36, 37, 38, 24, 25, 13, 39, 40, 41, 26, 27, 14, 42, 43, 44, 28, 29,
3862       15, 45, 46, 47, 30, 31, 16, 48, 49, 50, 32, 33, 17, 51, 52, 53, 34, 35,
3863       18, 54, 55, 56, 36, 37, 19, 57, 58, 59, 38, 39, 20, 60, 61, 62, 40, 41,
3864       21, 63, 64, 65, 42, 43, 22, 66, 67, 68, 44, 45, 23, 69, 70, 71, 46, 47};
3865     nntrainer::Tensor answer(ml::train::TensorDim{3, 2, 4, 6}, answer_data);
3866     EXPECT_EQ(nntrainer::Tensor::cat(inputs, 3), answer);
3867   }
3868 }
3869
3870 TEST(nntrainer_Tensor, cat_02_n) {
3871   {
3872     std::vector<nntrainer::Tensor> inputs;
3873     inputs.reserve(2);
3874     inputs.emplace_back(nntrainer::Tensor(2, 1, 1, 2));
3875     inputs.emplace_back(nntrainer::Tensor(2, 2, 1, 2));
3876     EXPECT_THROW(nntrainer::Tensor::cat(inputs, 2), std::invalid_argument);
3877   }
3878 }
3879
3880 TEST(nntrainer_Tensor, zoneout_mask_01_n) {
3881   const float zoneout_rate = 0.3f;
3882   nntrainer::Tensor t(10, 10, 10, 10);
3883   nntrainer::Tensor opposite(20, 20, 20, 20);
3884   EXPECT_THROW(t.zoneout_mask(opposite, zoneout_rate), std::invalid_argument);
3885 }
3886
3887 TEST(nntrainer_Tensor, zoneout_mask_02_p) {
3888   const float zoneout_rate = 0.3f;
3889   nntrainer::Tensor t(10, 10, 10, 10);
3890   nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate);
3891   constexpr float epsilon = 1e-3;
3892
3893   EXPECT_EQ(t.size(), opposite.size());
3894
3895   auto is_near = [epsilon](float val1, float val2) {
3896     return val2 - epsilon < val1 && val1 < val2 + epsilon;
3897   };
3898
3899   for (unsigned int i = 0; i < opposite.size(); ++i) {
3900     if (is_near(opposite.getValue(i), 0.0f)) {
3901       EXPECT_NEAR(t.getValue(i), 1.0f, epsilon);
3902     } else if (is_near(opposite.getValue(i), 1.0f)) {
3903       EXPECT_NEAR(t.getValue(i), 0.0f, epsilon);
3904     } else {
3905       FAIL() << "This should not be happen";
3906     }
3907   }
3908 }
3909
3910 TEST(nntrainer_Tensor, zoneout_mask_03_p) {
3911   const float zoneout_rate = 0.3f;
3912   nntrainer::Tensor t(10, 10, 100, 100);
3913   nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate);
3914   constexpr float epsilon = 1e-3;
3915
3916   auto is_near = [epsilon](float val1, float val2) {
3917     return val2 - epsilon < val1 && val1 < val2 + epsilon;
3918   };
3919   auto percentage = [](unsigned int dividend, unsigned int divisor) {
3920     return (float)dividend / (float)divisor;
3921   };
3922
3923   {
3924     unsigned int zeros = 0;
3925     unsigned int ones = 0;
3926     for (unsigned int i = 0; i < opposite.size(); ++i) {
3927       if (is_near(opposite.getValue(i), 0.0f)) {
3928         ++zeros;
3929       } else if (is_near(opposite.getValue(i), 1.0f)) {
3930         ++ones;
3931       } else {
3932         FAIL() << "This should not be happen";
3933       }
3934     }
3935     EXPECT_NEAR(percentage(zeros, opposite.size()), 1.0f - zoneout_rate,
3936                 epsilon);
3937
3938     // main test
3939     EXPECT_NEAR(percentage(ones, opposite.size()), zoneout_rate, epsilon);
3940   }
3941
3942   {
3943     unsigned int zeros = 0;
3944     unsigned int ones = 0;
3945     for (unsigned int i = 0; i < t.size(); ++i) {
3946       if (is_near(t.getValue(i), 0.0f)) {
3947         ++zeros;
3948       } else if (is_near(t.getValue(i), 1.0f)) {
3949         ++ones;
3950       } else {
3951         FAIL() << "This should not be happen";
3952       }
3953     }
3954     EXPECT_NEAR(percentage(zeros, t.size()), zoneout_rate, epsilon);
3955
3956     // main test
3957     EXPECT_NEAR(percentage(ones, t.size()), 1.0f - zoneout_rate, epsilon);
3958   }
3959 }
3960
3961 TEST(nntrainer_Tensor, zoneout_mask_04_n) {
3962   const float zoneout_rate = 0.3f;
3963   nntrainer::Tensor t(10, 10, 100, 100);
3964   nntrainer::Tensor opposite = t.zoneout_mask(zoneout_rate);
3965   constexpr float epsilon = 1e-3;
3966
3967   auto is_near = [epsilon](float val1, float val2) {
3968     return val2 - epsilon < val1 && val1 < val2 + epsilon;
3969   };
3970   auto percentage = [](unsigned int dividend, unsigned int divisor) {
3971     return (float)dividend / (float)divisor;
3972   };
3973
3974   {
3975     unsigned int zeros = 0;
3976     unsigned int ones = 0;
3977     for (unsigned int i = 0; i < opposite.size(); ++i) {
3978       if (is_near(opposite.getValue(i), 0.0f)) {
3979         ++zeros;
3980       } else if (is_near(opposite.getValue(i), 1.0f)) {
3981         ++ones;
3982       } else {
3983         FAIL() << "This should not be happen";
3984       }
3985     }
3986     EXPECT_FALSE(
3987       is_near(percentage(ones, opposite.size()), 1.0f - zoneout_rate));
3988   }
3989
3990   {
3991     unsigned int zeros = 0;
3992     unsigned int ones = 0;
3993     for (unsigned int i = 0; i < t.size(); ++i) {
3994       if (is_near(t.getValue(i), 0.0f)) {
3995         ++zeros;
3996       } else if (is_near(t.getValue(i), 1.0f)) {
3997         ++ones;
3998       } else {
3999         FAIL() << "This should not be happen";
4000       }
4001     }
4002     EXPECT_FALSE(is_near(percentage(ones, t.size()), zoneout_rate));
4003   }
4004 }
4005
4006 TEST(nntrainer_Tensor, TensorMap_p) {
4007   float dat[] = {1, 2, 3};
4008
4009   {
4010     nntrainer::Tensor a = nntrainer::Tensor::Map(dat, 3 * sizeof(float), {3});
4011     /// check if a.getData() has same address with dat
4012     EXPECT_EQ(dat, a.getData());
4013     {
4014       /// check if b.getData() has same address with data
4015       nntrainer::Tensor b = a;
4016       EXPECT_EQ(dat, b.getData());
4017     }
4018   }
4019   /// check if dat is accessible after destruction of all the tensor
4020   EXPECT_FLOAT_EQ(dat[2], 3);
4021 }
4022
4023 TEST(nntrainer_Tensor, TensorWrap_01_n) {
4024   float dat[] = {1, 2, 3};
4025   EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, nntrainer::TensorDim({})),
4026                std::invalid_argument);
4027 }
4028
4029 TEST(nntrainer_Tensor, TensorWrap_02_n) {
4030   float dat[] = {1, 2, 3};
4031   EXPECT_THROW(nntrainer::Tensor::Map(dat, 3, {4}), std::invalid_argument);
4032 }
4033
4034 TEST(nntrainer_Tensor, TensorPaddedValue_p) {
4035   nntrainer::Tensor a = ranged(1, 1, 3, 3);
4036   float default_padded = -1;
4037
4038   for (int i = 0; i < 5; ++i) {
4039     for (int j = 0; j < 5; ++j) {
4040       float expected = default_padded;
4041       if (1 <= i && i <= 3 && 1 <= j && j <= 3) {
4042         expected = (i - 1) * 3 + (j - 1);
4043       }
4044       float actual = a.getValuePaddedVirtual<float>(0, 0, i, j, 1, 1, default_padded);
4045       EXPECT_FLOAT_EQ(actual, expected);
4046     }
4047   }
4048 }
4049
4050 GTEST_API_ int main(int argc, char **argv) {
4051   int result = -1;
4052
4053   try {
4054     testing::InitGoogleTest(&argc, argv);
4055   } catch (...) {
4056     std::cerr << "Error duing InitGoogleTest" << std::endl;
4057     return 0;
4058   }
4059
4060   try {
4061     result = RUN_ALL_TESTS();
4062   } catch (...) {
4063     std::cerr << "Error duing RUN_ALL_TESTS()" << std::endl;
4064   }
4065
4066   return result;
4067 }