2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <gtest/gtest.h>
18 #include <nnfw_internal.h>
22 #include "CircleGen.h"
26 * @brief Generated Model test fixture for a one time inference
28 * This fixture is for one-time inference test with variety of generated models.
29 * It is the user's responsiblity to create @c _cbuf , @c _ref_inputs and @c _ref_outputs in the
30 * test body, which are generated circle buffer, model input data and output data respectively.
31 * The rest(calling API functions for execution) is done by @c Setup and @c TearDown .
34 class GenModelTest : public ::testing::Test
37 void SetUp() override { NNFW_ENSURE_SUCCESS(nnfw_create_session(&_so.session)); }
39 void TearDown() override
41 NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(_so.session, _cbuf.buffer(), _cbuf.size()));
42 NNFW_ENSURE_SUCCESS(nnfw_prepare(_so.session));
44 // In/Out buffer settings
47 NNFW_ENSURE_SUCCESS(nnfw_input_size(_so.session, &num_inputs));
48 _so.inputs.resize(num_inputs);
49 for (uint32_t ind = 0; ind < _so.inputs.size(); ind++)
52 NNFW_ENSURE_SUCCESS(nnfw_input_tensorinfo(_so.session, ind, &ti));
53 uint64_t input_elements = num_elems(&ti);
54 _so.inputs[ind].resize(input_elements);
56 ASSERT_EQ(nnfw_set_input(_so.session, ind, ti.dtype, _so.inputs[ind].data(),
57 sizeof(float) * input_elements),
58 NNFW_STATUS_NO_ERROR);
62 NNFW_ENSURE_SUCCESS(nnfw_output_size(_so.session, &num_outputs));
63 _so.outputs.resize(num_outputs);
64 for (uint32_t ind = 0; ind < _so.outputs.size(); ind++)
67 NNFW_ENSURE_SUCCESS(nnfw_output_tensorinfo(_so.session, ind, &ti));
68 uint64_t output_elements = num_elems(&ti);
69 _so.outputs[ind].resize(output_elements);
70 ASSERT_EQ(nnfw_set_output(_so.session, ind, ti.dtype, _so.outputs[ind].data(),
71 sizeof(float) * output_elements),
72 NNFW_STATUS_NO_ERROR);
76 // Set input values, run, and check output values
78 ASSERT_EQ(_so.inputs.size(), _ref_inputs.size());
79 for (uint32_t i = 0; i < _so.inputs.size(); i++)
82 ASSERT_EQ(_so.inputs[i].size(), _ref_inputs[i].size());
83 memcpy(_so.inputs[i].data(), _ref_inputs[i].data(), _so.inputs[i].size() * sizeof(float));
86 NNFW_ENSURE_SUCCESS(nnfw_run(_so.session));
88 ASSERT_EQ(_so.outputs.size(), _ref_outputs.size());
89 for (uint32_t i = 0; i < _so.outputs.size(); i++)
91 // Check output tensor values
92 auto &ref_output = _ref_outputs[i];
93 auto &output = _so.outputs[i];
94 ASSERT_EQ(output.size(), ref_output.size());
95 for (uint32_t e = 0; e < ref_output.size(); e++)
96 ASSERT_FLOAT_EQ(ref_output[e], output[e]);
100 NNFW_ENSURE_SUCCESS(nnfw_close_session(_so.session));
106 std::vector<std::vector<float>> _ref_inputs;
107 std::vector<std::vector<float>> _ref_outputs;
110 TEST_F(GenModelTest, OneOp_Add_VarToConst)
113 std::vector<float> rhs_data{5, 4, 7, 4};
114 uint32_t rhs_buf = cgen.addBuffer(rhs_data);
115 int lhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
116 int rhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32, rhs_buf});
117 int out = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
118 cgen.addOperatorAdd({{lhs, rhs}, {out}}, circle::ActivationFunctionType_NONE);
119 cgen.setInputsAndOutputs({lhs}, {out});
120 _cbuf = cgen.finish();
122 _ref_inputs = {{1, 3, 2, 4}};
123 _ref_outputs = {{6, 7, 9, 8}};
126 TEST_F(GenModelTest, OneOp_Add_VarToVar)
129 int lhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
130 int rhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
131 int out = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
132 cgen.addOperatorAdd({{lhs, rhs}, {out}}, circle::ActivationFunctionType_NONE);
133 cgen.setInputsAndOutputs({lhs, rhs}, {out});
134 _cbuf = cgen.finish();
136 _ref_inputs = {{1, 3, 2, 4}, {5, 4, 7, 4}};
137 _ref_outputs = {{6, 7, 9, 8}};
140 TEST_F(GenModelTest, OneOp_AvgPool2D)
143 int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
144 int out = cgen.addTensor({{1, 1, 1, 1}, circle::TensorType::TensorType_FLOAT32});
145 cgen.addOperatorAveragePool2D({{in}, {out}}, circle::Padding_SAME, 2, 2, 2, 2,
146 circle::ActivationFunctionType_NONE);
147 cgen.setInputsAndOutputs({in}, {out});
148 _cbuf = cgen.finish();
150 _ref_inputs = {{1, 3, 2, 4}};
151 _ref_outputs = {{2.5}};