Deprecate nGraph v0 ops and builders (#1856)
[platform/upstream/dldt.git] / ngraph / test / backend / product.in.cpp
1 //*****************************************************************************
2 // Copyright 2017-2020 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //*****************************************************************************
16
17 #include "gtest/gtest.h"
18 #include "ngraph/ngraph.hpp"
19 #include "util/all_close.hpp"
20 #include "util/all_close_f.hpp"
21 #include "util/known_element_types.hpp"
22 #include "util/ndarray.hpp"
23 #include "util/test_control.hpp"
24 #include "util/test_tools.hpp"
25
26 NGRAPH_SUPPRESS_DEPRECATED_START
27
28 using namespace std;
29 using namespace ngraph;
30
31 static string s_manifest = "${MANIFEST}";
32
33 // Trivial case with no reduced axes.
34 NGRAPH_TEST(${BACKEND_NAME}, product_trivial)
35 {
36     Shape shape{2, 2};
37     auto A = make_shared<op::Parameter>(element::f32, shape);
38     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{}), ParameterVector{A});
39
40     auto backend = runtime::Backend::create("${BACKEND_NAME}");
41
42     // Create some tensors for input/output
43     auto a = backend->create_tensor(element::f32, shape);
44     copy_data(a, vector<float>{1, 2, 3, 4});
45     auto result = backend->create_tensor(element::f32, shape);
46
47     auto handle = backend->compile(f);
48     handle->call_with_validate({result}, {a});
49     EXPECT_TRUE(test::all_close_f((vector<float>{1, 2, 3, 4}), read_vector<float>(result)));
50 }
51
52 // Failure has been reported at 5D for some reason
53 NGRAPH_TEST(${BACKEND_NAME}, product_trivial_5d)
54 {
55     Shape shape{2, 2, 2, 2, 2};
56     auto A = make_shared<op::Parameter>(element::f32, shape);
57     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{}), ParameterVector{A});
58
59     auto backend = runtime::Backend::create("${BACKEND_NAME}");
60
61     // Create some tensors for input/output
62     auto a = backend->create_tensor(element::f32, shape);
63     copy_data(a, vector<float>{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64                                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1});
65     auto result = backend->create_tensor(element::f32, shape);
66
67     auto handle = backend->compile(f);
68     handle->call_with_validate({result}, {a});
69     EXPECT_TRUE(test::all_close_f((vector<float>{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
70                                                  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}),
71                                   read_vector<float>(result)));
72 }
73
74 NGRAPH_TEST(${BACKEND_NAME}, product_to_scalar)
75 {
76     Shape shape{2, 2};
77     auto A = make_shared<op::Parameter>(element::f32, shape);
78     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
79
80     auto backend = runtime::Backend::create("${BACKEND_NAME}");
81
82     // Create some tensors for input/output
83     auto a = backend->create_tensor(element::f32, shape);
84     copy_data(a, vector<float>{1, 2, 3, 4});
85     auto result = backend->create_tensor(element::f32, Shape{});
86
87     auto handle = backend->compile(f);
88     handle->call_with_validate({result}, {a});
89     EXPECT_TRUE(test::all_close_f((vector<float>{24}), read_vector<float>(result)));
90
91     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
92     // input tensors, so let's do this too.
93     EXPECT_TRUE(test::all_close_f((vector<float>{1, 2, 3, 4}), read_vector<float>(a)));
94 }
95
96 NGRAPH_TEST(${BACKEND_NAME}, product_matrix_columns)
97 {
98     Shape shape_a{3, 2};
99     auto A = make_shared<op::Parameter>(element::f32, shape_a);
100     Shape shape_rt{2};
101     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0}), ParameterVector{A});
102
103     auto backend = runtime::Backend::create("${BACKEND_NAME}");
104
105     // Create some tensors for input/output
106     auto a = backend->create_tensor(element::f32, shape_a);
107     copy_data(a, vector<float>{1, 2, 3, 4, 5, 6});
108     auto result = backend->create_tensor(element::f32, shape_rt);
109
110     auto handle = backend->compile(f);
111     handle->call_with_validate({result}, {a});
112     EXPECT_TRUE(test::all_close_f((vector<float>{15, 48}), read_vector<float>(result)));
113
114     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
115     // input tensors, so let's do this too.
116     EXPECT_TRUE(test::all_close_f((vector<float>{1, 2, 3, 4, 5, 6}), read_vector<float>(a)));
117 }
118
119 NGRAPH_TEST(${BACKEND_NAME}, product_matrix_rows)
120 {
121     Shape shape_a{3, 2};
122     auto A = make_shared<op::Parameter>(element::f32, shape_a);
123     Shape shape_rt{3};
124     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{1}), ParameterVector{A});
125
126     auto backend = runtime::Backend::create("${BACKEND_NAME}");
127
128     // Create some tensors for input/output
129     auto a = backend->create_tensor(element::f32, shape_a);
130     copy_data(a, vector<float>{1, 2, 3, 4, 5, 6});
131     auto result = backend->create_tensor(element::f32, shape_rt);
132
133     auto handle = backend->compile(f);
134     handle->call_with_validate({result}, {a});
135     EXPECT_TRUE(test::all_close_f((vector<float>{2, 12, 30}), read_vector<float>(result)));
136
137     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
138     // input tensors, so let's do this too.
139     EXPECT_TRUE(test::all_close_f((vector<float>{1, 2, 3, 4, 5, 6}), read_vector<float>(a)));
140 }
141
142 NGRAPH_TEST(${BACKEND_NAME}, product_matrix_rows_zero)
143 {
144     Shape shape_a{3, 0};
145     auto A = make_shared<op::Parameter>(element::f32, shape_a);
146     Shape shape_rt{3};
147     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{1}), ParameterVector{A});
148
149     auto backend = runtime::Backend::create("${BACKEND_NAME}");
150
151     // Create some tensors for input/output
152     auto a = backend->create_tensor(element::f32, shape_a);
153     copy_data(a, vector<float>{});
154     auto result = backend->create_tensor(element::f32, shape_rt);
155     copy_data(result, vector<float>({3, 3, 3}));
156
157     auto handle = backend->compile(f);
158     handle->call_with_validate({result}, {a});
159     EXPECT_TRUE(test::all_close_f((vector<float>{1, 1, 1}), read_vector<float>(result)));
160
161     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
162     // input tensors, so let's do this too.
163     EXPECT_TRUE(test::all_close_f((vector<float>{}), read_vector<float>(a)));
164 }
165
166 NGRAPH_TEST(${BACKEND_NAME}, product_matrix_cols_zero)
167 {
168     // Now the reduction (g(x:float32[2,2],y:float32[]) = reduce(x,y,f,axes={})).
169     Shape shape_a{0, 2};
170     auto A = make_shared<op::Parameter>(element::f32, shape_a);
171     Shape shape_rt{2};
172     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0}), ParameterVector{A});
173
174     auto backend = runtime::Backend::create("${BACKEND_NAME}");
175
176     // Create some tensors for input/output
177     auto a = backend->create_tensor(element::f32, shape_a);
178     copy_data(a, vector<float>{});
179     auto result = backend->create_tensor(element::f32, shape_rt);
180     copy_data(result, vector<float>({3, 3}));
181
182     auto handle = backend->compile(f);
183     handle->call_with_validate({result}, {a});
184     EXPECT_TRUE(test::all_close_f((vector<float>{1, 1}), read_vector<float>(result)));
185
186     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
187     // input tensors, so let's do this too.
188     EXPECT_TRUE(test::all_close_f((vector<float>{}), read_vector<float>(a)));
189 }
190
191 NGRAPH_TEST(${BACKEND_NAME}, product_vector_zero)
192 {
193     Shape shape_a{0};
194     auto A = make_shared<op::Parameter>(element::f32, shape_a);
195     Shape shape_rt{};
196     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0}), ParameterVector{A});
197
198     auto backend = runtime::Backend::create("${BACKEND_NAME}");
199
200     // Create some tensors for input/output
201     auto a = backend->create_tensor(element::f32, shape_a);
202     copy_data(a, vector<float>{});
203     auto result = backend->create_tensor(element::f32, shape_rt);
204     copy_data(result, vector<float>({3}));
205
206     auto handle = backend->compile(f);
207     handle->call_with_validate({result}, {a});
208     EXPECT_TRUE(test::all_close_f((vector<float>{1}), read_vector<float>(result)));
209
210     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
211     // input tensors, so let's do this too.
212     EXPECT_TRUE(test::all_close_f((vector<float>{}), read_vector<float>(a)));
213 }
214
215 NGRAPH_TEST(${BACKEND_NAME}, product_matrix_to_scalar_zero_by_zero)
216 {
217     Shape shape_a{0, 0};
218     auto A = make_shared<op::Parameter>(element::f32, shape_a);
219     Shape shape_rt{};
220     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
221
222     auto backend = runtime::Backend::create("${BACKEND_NAME}");
223
224     // Create some tensors for input/output
225     auto a = backend->create_tensor(element::f32, shape_a);
226     copy_data(a, vector<float>{});
227     auto result = backend->create_tensor(element::f32, shape_rt);
228     copy_data(result, vector<float>({3}));
229
230     auto handle = backend->compile(f);
231     handle->call_with_validate({result}, {a});
232     EXPECT_TRUE(test::all_close_f((vector<float>{1}), read_vector<float>(result)));
233
234     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
235     // input tensors, so let's do this too.
236     EXPECT_TRUE(test::all_close_f((vector<float>{}), read_vector<float>(a)));
237 }
238
239 NGRAPH_TEST(${BACKEND_NAME}, product_3d_to_matrix_most_sig)
240 {
241     Shape shape_a{3, 3, 3};
242     auto A = make_shared<op::Parameter>(element::f32, shape_a);
243     Shape shape_rt{3, 3};
244     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0}), ParameterVector{A});
245
246     auto backend = runtime::Backend::create("${BACKEND_NAME}");
247
248     // Create some tensors for input/output
249     auto a = backend->create_tensor(element::f32, shape_a);
250     copy_data(a, vector<float>{1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,
251                                15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27});
252     auto result = backend->create_tensor(element::f32, shape_rt);
253
254     auto handle = backend->compile(f);
255     handle->call_with_validate({result}, {a});
256     EXPECT_TRUE(test::all_close_f((vector<float>{1 * 10 * 19,
257                                                  2 * 11 * 20,
258                                                  3 * 12 * 21,
259                                                  4 * 13 * 22,
260                                                  5 * 14 * 23,
261                                                  6 * 15 * 24,
262                                                  7 * 16 * 25,
263                                                  8 * 17 * 26,
264                                                  9 * 18 * 27}),
265                                   read_vector<float>(result)));
266 }
267
268 NGRAPH_TEST(${BACKEND_NAME}, product_3d_to_matrix_least_sig)
269 {
270     Shape shape_a{3, 3, 3};
271     auto A = make_shared<op::Parameter>(element::f32, shape_a);
272     Shape shape_rt{3, 3};
273     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{2}), ParameterVector{A});
274
275     auto backend = runtime::Backend::create("${BACKEND_NAME}");
276
277     // Create some tensors for input/output
278     auto a = backend->create_tensor(element::f32, shape_a);
279     copy_data(a, vector<float>{1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,
280                                15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27});
281     auto result = backend->create_tensor(element::f32, shape_rt);
282
283     auto handle = backend->compile(f);
284     handle->call_with_validate({result}, {a});
285     EXPECT_TRUE(test::all_close_f((vector<float>{1 * 2 * 3,
286                                                  4 * 5 * 6,
287                                                  7 * 8 * 9,
288                                                  10 * 11 * 12,
289                                                  13 * 14 * 15,
290                                                  16 * 17 * 18,
291                                                  19 * 20 * 21,
292                                                  22 * 23 * 24,
293                                                  25 * 26 * 27}),
294                                   read_vector<float>(result)));
295 }
296
297 NGRAPH_TEST(${BACKEND_NAME}, product_3d_to_vector)
298 {
299     Shape shape_a{3, 3, 3};
300     auto A = make_shared<op::Parameter>(element::f32, shape_a);
301     Shape shape_rt{3};
302     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
303
304     auto backend = runtime::Backend::create("${BACKEND_NAME}");
305
306     // Create some tensors for input/output
307     auto a = backend->create_tensor(element::f32, shape_a);
308     copy_data(a, vector<float>{1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,
309                                15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27});
310     auto result = backend->create_tensor(element::f32, shape_rt);
311
312     auto handle = backend->compile(f);
313     handle->call_with_validate({result}, {a});
314     EXPECT_TRUE(test::all_close_f(
315         (vector<float>{1.0f * 10.0f * 19.0f * 4.0f * 13.0f * 22.0f * 7.0f * 16.0f * 25.0f,
316                        2.0f * 11.0f * 20.0f * 5.0f * 14.0f * 23.0f * 8.0f * 17.0f * 26.0f,
317                        3.0f * 12.0f * 21.0f * 6.0f * 15.0f * 24.0f * 9.0f * 18.0f * 27.0f}),
318         read_vector<float>(result)));
319 }
320
321 NGRAPH_TEST(${BACKEND_NAME}, product_3d_to_scalar)
322 {
323     Shape shape_a{3, 3, 3};
324     auto A = make_shared<op::Parameter>(element::f32, shape_a);
325     Shape shape_rt{};
326     auto f =
327         make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1, 2}), ParameterVector{A});
328
329     auto backend = runtime::Backend::create("${BACKEND_NAME}");
330
331     // Create some tensors for input/output
332     auto a = backend->create_tensor(element::f32, shape_a);
333     copy_data(a, vector<float>{1,  2,  3,  4,  5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
334                                13, 12, 11, 10, 9, 8, 7, 6, 5, 4,  3,  2,  1});
335     auto result = backend->create_tensor(element::f32, shape_rt);
336
337     auto handle = backend->compile(f);
338     handle->call_with_validate({result}, {a});
339     EXPECT_TRUE(test::all_close_f(vector<float>{1.0f * 10.0f * 9.0f * 4.0f * 13.0f * 6.0f * 7.0f *
340                                                 12.0f * 3.0f * 2.0f * 11.0f * 8.0f * 5.0f * 14.0f *
341                                                 5.0f * 8.0f * 11.0f * 2.0f * 3.0f * 12.0f * 7.0f *
342                                                 6.0f * 13.0f * 4.0f * 9.0f * 10.0f * 1.0f},
343                                   read_vector<float>(result)));
344 }
345
346 NGRAPH_TEST(${BACKEND_NAME}, product_3d_eliminate_zero_dim)
347 {
348     Shape shape_a{3, 0, 2};
349     auto A = make_shared<op::Parameter>(element::f32, shape_a);
350     Shape shape_rt{3, 2};
351     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{1}), ParameterVector{A});
352
353     auto backend = runtime::Backend::create("${BACKEND_NAME}");
354
355     // Create some tensors for input/output
356     auto a = backend->create_tensor(element::f32, shape_a);
357     copy_data(a, vector<float>{});
358     auto result = backend->create_tensor(element::f32, shape_rt);
359
360     // Overwrite the initial result vector to make sure we're not just coincidentally getting the
361     // right value.
362     copy_data(result, vector<float>{2112, 2112, 2112, 2112, 2112, 2112});
363
364     auto handle = backend->compile(f);
365     handle->call_with_validate({result}, {a});
366     EXPECT_TRUE(test::all_close_f((vector<float>{1, 1, 1, 1, 1, 1}), read_vector<float>(result)));
367 }
368
369 NGRAPH_TEST(${BACKEND_NAME}, product_2d_to_scalar_int32)
370 {
371     Shape shape_a{3, 3};
372     auto A = make_shared<op::Parameter>(element::i32, shape_a);
373     Shape shape_rt{};
374     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
375
376     auto backend = runtime::Backend::create("${BACKEND_NAME}");
377
378     // Create some tensors for input/output
379     auto a = backend->create_tensor(element::i32, shape_a);
380     copy_data(a, vector<int32_t>{1, 2, 3, 4, 5, 6, 7, 8, 9});
381     auto result = backend->create_tensor(element::i32, shape_rt);
382
383     auto handle = backend->compile(f);
384     handle->call_with_validate({result}, {a});
385     EXPECT_EQ(vector<int32_t>{1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9}, read_vector<int32_t>(result));
386 }
387
388 NGRAPH_TEST(${BACKEND_NAME}, product_to_scalar_int32)
389 {
390     Shape shape{2, 2};
391     auto A = make_shared<op::Parameter>(element::i32, shape);
392     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
393
394     auto backend = runtime::Backend::create("${BACKEND_NAME}");
395
396     // Create some tensors for input/output
397     auto a = backend->create_tensor(element::i32, shape);
398     copy_data(a, vector<int32_t>{1, 2, 3, 4});
399     auto result = backend->create_tensor(element::i32, Shape{});
400
401     auto handle = backend->compile(f);
402     handle->call_with_validate({result}, {a});
403     EXPECT_EQ((vector<int32_t>{24}), read_vector<int32_t>(result));
404
405     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
406     // input tensors, so let's do this too.
407     EXPECT_EQ((vector<int32_t>{1, 2, 3, 4}), read_vector<int32_t>(a));
408 }
409
410 NGRAPH_TEST(${BACKEND_NAME}, product_to_scalar_int8)
411 {
412     Shape shape{2, 2};
413     auto A = make_shared<op::Parameter>(element::i8, shape);
414     auto f = make_shared<Function>(make_shared<op::Product>(A, AxisSet{0, 1}), ParameterVector{A});
415
416     auto backend = runtime::Backend::create("${BACKEND_NAME}");
417
418     // Create some tensors for input/output
419     auto a = backend->create_tensor(element::i8, shape);
420     copy_data(a, vector<int8_t>{1, 2, 3, 4});
421     auto result = backend->create_tensor(element::i8, Shape{});
422
423     auto handle = backend->compile(f);
424     handle->call_with_validate({result}, {a});
425     EXPECT_EQ((vector<int8_t>{24}), read_vector<int8_t>(result));
426
427     // For some reason I'm feeling extra paranoid about making sure reduction doesn't clobber the
428     // input tensors, so let's do this too.
429     EXPECT_EQ((vector<int8_t>{1, 2, 3, 4}), read_vector<int8_t>(a));
430 }