Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / tests / nnfw_api / src / fixtures.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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 #ifndef __NNFW_API_TEST_FIXTURES_H__
18 #define __NNFW_API_TEST_FIXTURES_H__
19
20 #include <array>
21 #include <gtest/gtest.h>
22 #include <nnfw_experimental.h>
23 #include <nnfw_internal.h>
24
25 #include "NNPackages.h"
26 #include "CircleGen.h"
27
28 #define NNFW_ENSURE_SUCCESS(EXPR) ASSERT_EQ((EXPR), NNFW_STATUS_NO_ERROR)
29
30 inline uint64_t num_elems(const nnfw_tensorinfo *ti)
31 {
32   uint64_t n = 1;
33   for (uint32_t i = 0; i < ti->rank; ++i)
34   {
35     n *= ti->dims[i];
36   }
37   return n;
38 }
39
40 struct SessionObject
41 {
42   nnfw_session *session = nullptr;
43   std::vector<std::vector<float>> inputs;
44   std::vector<std::vector<float>> outputs;
45 };
46
47 class ValidationTest : public ::testing::Test
48 {
49 protected:
50   void SetUp() override {}
51 };
52
53 class RegressionTest : public ::testing::Test
54 {
55 protected:
56   void SetUp() override {}
57 };
58
59 class ValidationTestSingleSession : public ValidationTest
60 {
61 protected:
62   nnfw_session *_session = nullptr;
63 };
64
65 class ValidationTestSessionCreated : public ValidationTestSingleSession
66 {
67 protected:
68   void SetUp() override
69   {
70     ValidationTestSingleSession::SetUp();
71     ASSERT_EQ(nnfw_create_session(&_session), NNFW_STATUS_NO_ERROR);
72     ASSERT_NE(_session, nullptr);
73   }
74
75   void TearDown() override
76   {
77     ASSERT_EQ(nnfw_close_session(_session), NNFW_STATUS_NO_ERROR);
78     ValidationTestSingleSession::TearDown();
79   }
80 };
81
82 inline CircleBuffer genAddModel()
83 {
84   CircleGen cgen;
85   std::vector<float> rhs_data{2};
86   uint32_t rhs_buf = cgen.addBuffer(rhs_data);
87   int lhs = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32, 0, "X_input"});
88   int rhs = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32, rhs_buf, "y_var"});
89   int out = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32, 0, "ADD_TOP"});
90   cgen.addOperatorAdd({{lhs, rhs}, {out}}, circle::ActivationFunctionType_NONE);
91   cgen.setInputsAndOutputs({lhs}, {out});
92   return cgen.finish();
93 }
94
95 template <int PackageNo> class ValidationTestModelLoaded : public ValidationTestSessionCreated
96 {
97 protected:
98   void SetUp() override
99   {
100     ValidationTestSessionCreated::SetUp();
101     if (PackageNo == NNPackages::ADD)
102     {
103       auto cbuf = genAddModel();
104       NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(_session, cbuf.buffer(), cbuf.size()));
105     }
106     else
107     {
108       // TODO Eventually, downloaded model tests are removed.
109       NNFW_ENSURE_SUCCESS(nnfw_load_model_from_file(
110         _session, NNPackages::get().getModelAbsolutePath(PackageNo).c_str()));
111     }
112   }
113
114   void TearDown() override { ValidationTestSessionCreated::TearDown(); }
115 };
116
117 template <int PackageNo>
118 class ValidationTestSessionPrepared : public ValidationTestModelLoaded<PackageNo>
119 {
120 protected:
121   using ValidationTestSingleSession::_session;
122
123   void SetUp() override
124   {
125     ValidationTestModelLoaded<PackageNo>::SetUp();
126     nnfw_prepare(_session);
127   }
128
129   void TearDown() override { ValidationTestModelLoaded<PackageNo>::TearDown(); }
130
131   void SetInOutBuffers()
132   {
133     nnfw_tensorinfo ti_input;
134     ASSERT_EQ(nnfw_input_tensorinfo(_session, 0, &ti_input), NNFW_STATUS_NO_ERROR);
135     uint64_t input_elements = num_elems(&ti_input);
136     EXPECT_EQ(input_elements, 1);
137     _input.resize(input_elements);
138     ASSERT_EQ(
139       nnfw_set_input(_session, 0, ti_input.dtype, _input.data(), sizeof(float) * input_elements),
140       NNFW_STATUS_NO_ERROR);
141
142     nnfw_tensorinfo ti_output;
143     ASSERT_EQ(nnfw_output_tensorinfo(_session, 0, &ti_output), NNFW_STATUS_NO_ERROR);
144     uint64_t output_elements = num_elems(&ti_output);
145     EXPECT_EQ(output_elements, 1);
146     _output.resize(output_elements);
147     ASSERT_EQ(nnfw_set_output(_session, 0, ti_output.dtype, _output.data(),
148                               sizeof(float) * output_elements),
149               NNFW_STATUS_NO_ERROR);
150   }
151
152   void SetInOutBuffersDynamic(const nnfw_tensorinfo *ti_input)
153   {
154     NNFW_ENSURE_SUCCESS(nnfw_set_input_tensorinfo(_session, 0, ti_input));
155     uint64_t input_elements = num_elems(ti_input);
156     _input.resize(input_elements);
157     ASSERT_EQ(
158       nnfw_set_input(_session, 0, ti_input->dtype, _input.data(), sizeof(float) * input_elements),
159       NNFW_STATUS_NO_ERROR);
160
161     _output.resize(40000); // Give sufficient size for the output
162     ASSERT_EQ(
163       nnfw_set_output(_session, 0, ti_input->dtype, _output.data(), sizeof(float) * _output.size()),
164       NNFW_STATUS_NO_ERROR);
165   }
166
167 protected:
168   std::vector<float> _input;
169   std::vector<float> _output;
170 };
171
172 template <int PackageNo> class ValidationTestFourModelsSetInput : public ValidationTest
173 {
174 protected:
175   static const uint32_t NUM_SESSIONS = 4;
176
177   void SetUp() override
178   {
179     ValidationTest::SetUp();
180
181     for (auto &obj : _objects)
182     {
183       ASSERT_EQ(nnfw_create_session(&obj.session), NNFW_STATUS_NO_ERROR);
184
185       auto cbuf = genAddModel();
186       NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(obj.session, cbuf.buffer(), cbuf.size()));
187       ASSERT_EQ(nnfw_prepare(obj.session), NNFW_STATUS_NO_ERROR);
188
189       uint32_t num_inputs;
190       ASSERT_EQ(nnfw_input_size(obj.session, &num_inputs), NNFW_STATUS_NO_ERROR);
191       obj.inputs.resize(num_inputs);
192       for (uint32_t ind = 0; ind < obj.inputs.size(); ind++)
193       {
194         nnfw_tensorinfo ti;
195         ASSERT_EQ(nnfw_input_tensorinfo(obj.session, ind, &ti), NNFW_STATUS_NO_ERROR);
196         uint64_t input_elements = num_elems(&ti);
197         obj.inputs[ind].resize(input_elements);
198         ASSERT_EQ(nnfw_set_input(obj.session, ind, ti.dtype, obj.inputs[ind].data(),
199                                  sizeof(float) * input_elements),
200                   NNFW_STATUS_NO_ERROR);
201       }
202
203       uint32_t num_outputs;
204       ASSERT_EQ(nnfw_output_size(obj.session, &num_outputs), NNFW_STATUS_NO_ERROR);
205       obj.outputs.resize(num_outputs);
206       for (uint32_t ind = 0; ind < obj.outputs.size(); ind++)
207       {
208         nnfw_tensorinfo ti;
209         ASSERT_EQ(nnfw_output_tensorinfo(obj.session, ind, &ti), NNFW_STATUS_NO_ERROR);
210         uint64_t output_elements = num_elems(&ti);
211         obj.outputs[ind].resize(output_elements);
212         ASSERT_EQ(nnfw_set_output(obj.session, ind, ti.dtype, obj.outputs[ind].data(),
213                                   sizeof(float) * output_elements),
214                   NNFW_STATUS_NO_ERROR);
215       }
216     }
217   }
218
219   void TearDown() override
220   {
221     for (auto &obj : _objects)
222     {
223       ASSERT_EQ(nnfw_close_session(obj.session), NNFW_STATUS_NO_ERROR);
224     }
225     ValidationTest::TearDown();
226   }
227
228 protected:
229   std::array<SessionObject, NUM_SESSIONS> _objects;
230 };
231
232 class ValidationTestTwoSessions : public ValidationTest
233 {
234 protected:
235   nnfw_session *_session1 = nullptr;
236   nnfw_session *_session2 = nullptr;
237 };
238
239 class ValidationTestTwoSessionsCreated : public ValidationTestTwoSessions
240 {
241 protected:
242   void SetUp() override
243   {
244     ValidationTestTwoSessions::SetUp();
245     ASSERT_EQ(nnfw_create_session(&_session1), NNFW_STATUS_NO_ERROR);
246     ASSERT_EQ(nnfw_create_session(&_session2), NNFW_STATUS_NO_ERROR);
247     ASSERT_NE(_session1, nullptr);
248     ASSERT_NE(_session2, nullptr);
249   }
250
251   void TearDown() override
252   {
253     ASSERT_EQ(nnfw_close_session(_session1), NNFW_STATUS_NO_ERROR);
254     ASSERT_EQ(nnfw_close_session(_session2), NNFW_STATUS_NO_ERROR);
255     ValidationTestTwoSessions::TearDown();
256   }
257 };
258
259 #endif // __NNFW_API_TEST_FIXTURES_H__