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.
18 #include "NNPackages.h"
20 #include <nnfw_internal.h>
22 #include "CircleGen.h"
24 TEST_F(RegressionTest, github_1535)
26 auto package_path = NNPackages::get().getModelAbsolutePath(NNPackages::ADD);
28 nnfw_session *session1 = nullptr;
29 NNFW_ENSURE_SUCCESS(nnfw_create_session(&session1));
30 NNFW_ENSURE_SUCCESS(nnfw_load_model_from_file(session1, package_path.c_str()));
31 NNFW_ENSURE_SUCCESS(nnfw_set_available_backends(session1, "cpu;acl_cl;acl_neon"));
32 NNFW_ENSURE_SUCCESS(nnfw_prepare(session1));
34 nnfw_session *session2 = nullptr;
35 NNFW_ENSURE_SUCCESS(nnfw_create_session(&session2));
36 NNFW_ENSURE_SUCCESS(nnfw_load_model_from_file(session2, package_path.c_str()));
37 NNFW_ENSURE_SUCCESS(nnfw_set_available_backends(session2, "cpu"));
38 NNFW_ENSURE_SUCCESS(nnfw_prepare(session2));
40 NNFW_ENSURE_SUCCESS(nnfw_close_session(session1));
41 NNFW_ENSURE_SUCCESS(nnfw_close_session(session2));
46 TEST_F(RegressionTest, neg_github_3826)
48 // Model is not important
50 int in = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
51 int out = cgen.addTensor({{1, 1, 1, 1}, circle::TensorType::TensorType_FLOAT32});
52 cgen.addOperatorAveragePool2D({{in}, {out}}, circle::Padding_SAME, 2, 2, 2, 2,
53 circle::ActivationFunctionType_NONE);
54 cgen.setInputsAndOutputs({in}, {out});
55 auto cbuf = cgen.finish();
57 nnfw_session *session = nullptr;
58 NNFW_ENSURE_SUCCESS(nnfw_create_session(&session));
59 NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(session, cbuf.buffer(), cbuf.size()));
60 // To test when there is no backends loaded for the session
61 NNFW_ENSURE_SUCCESS(nnfw_set_available_backends(session, "unavailable_backend"));
62 ASSERT_EQ(nnfw_prepare(session), NNFW_STATUS_ERROR);
63 NNFW_ENSURE_SUCCESS(nnfw_close_session(session));
66 TEST_F(RegressionTest, github_11748)
68 // At the 1st call, input tensor is static. From the 2nd call, input tensor becomes dynamic.
69 // the following model and calling sequence were what nnstreamer people used for their test case.
71 int lhs = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32});
73 std::vector<float> rhs_data{2};
74 uint32_t rhs_buf = cgen.addBuffer(rhs_data);
75 int rhs = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32, rhs_buf});
77 int out = cgen.addTensor({{1}, circle::TensorType::TensorType_FLOAT32});
78 cgen.addOperatorAdd({{lhs, rhs}, {out}}, circle::ActivationFunctionType_NONE);
79 cgen.setInputsAndOutputs({lhs}, {out});
80 auto cbuf = cgen.finish();
82 nnfw_session *session = nullptr;
83 NNFW_ENSURE_SUCCESS(nnfw_create_session(&session));
84 NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(session, cbuf.buffer(), cbuf.size()));
85 // To test when there is no backends loaded for the session
86 NNFW_ENSURE_SUCCESS(nnfw_set_available_backends(session, "cpu"));
87 NNFW_ENSURE_SUCCESS(nnfw_prepare(session));
89 uint32_t input_num = -1;
90 NNFW_ENSURE_SUCCESS(nnfw_input_size(session, &input_num));
92 nnfw_tensorinfo t_input;
93 NNFW_ENSURE_SUCCESS(nnfw_input_tensorinfo(session, 0, &t_input));
95 uint32_t output_num = -1;
96 NNFW_ENSURE_SUCCESS(nnfw_output_size(session, &output_num));
98 nnfw_tensorinfo t_output;
99 NNFW_ENSURE_SUCCESS(nnfw_output_tensorinfo(session, 0, &t_output));
101 // when new_dim == 1, input tensor is static. From 2, input tensor becomes dynamic.
102 for (int32_t new_dim = 1; new_dim <= 4; new_dim++)
104 nnfw_tensorinfo t_new_input;
105 t_new_input.dtype = t_input.dtype;
106 t_new_input.rank = 1;
107 t_new_input.dims[0] = new_dim;
108 NNFW_ENSURE_SUCCESS(nnfw_set_input_tensorinfo(session, 0, &t_new_input));
110 NNFW_ENSURE_SUCCESS(nnfw_input_size(session, &input_num));
111 NNFW_ENSURE_SUCCESS(nnfw_input_tensorinfo(session, 0, &t_input));
113 ASSERT_EQ(input_num, 1);
114 ASSERT_EQ(t_input.rank, t_new_input.rank);
115 ASSERT_EQ(t_input.dims[0], new_dim);
117 uint8_t input_buf[new_dim * sizeof(float)];
119 nnfw_set_input(session, 0, t_input.dtype, &input_buf, new_dim * sizeof(float)));
121 uint8_t output_buf[new_dim * sizeof(float)];
123 nnfw_set_output(session, 0, t_output.dtype, &output_buf, new_dim * sizeof(float)));
125 NNFW_ENSURE_SUCCESS(nnfw_run(session));
127 NNFW_ENSURE_SUCCESS(nnfw_output_size(session, &output_num));
128 NNFW_ENSURE_SUCCESS(nnfw_output_tensorinfo(session, 0, &t_output));
130 ASSERT_EQ(output_num, 1);
131 ASSERT_EQ(t_output.rank, t_new_input.rank);
132 ASSERT_EQ(t_output.dims[0], new_dim);
134 // seems weird calling but anyway nnstreamer people case calls this again.
135 // Anyways, runtime should work
137 nnfw_set_input(session, 0, t_input.dtype, &input_buf, new_dim * sizeof(float)));
139 nnfw_set_output(session, 0, t_output.dtype, &output_buf, new_dim * sizeof(float)));
140 NNFW_ENSURE_SUCCESS(nnfw_run(session));
143 NNFW_ENSURE_SUCCESS(nnfw_close_session(session));
146 TEST_F(RegressionTest, github_4585)
148 // A single tensor which is an input and an output at the same time
150 int t = cgen.addTensor({{1, 1}, circle::TensorType::TensorType_FLOAT32});
151 cgen.setInputsAndOutputs({t}, {t});
152 auto cbuf = cgen.finish();
154 nnfw_session *session = nullptr;
155 NNFW_ENSURE_SUCCESS(nnfw_create_session(&session));
156 NNFW_ENSURE_SUCCESS(nnfw_load_circle_from_buffer(session, cbuf.buffer(), cbuf.size()));
157 // To test when there is no backends loaded for the session
158 NNFW_ENSURE_SUCCESS(nnfw_set_available_backends(session, "cpu"));
159 NNFW_ENSURE_SUCCESS(nnfw_prepare(session));
161 // Change input tensorinfo (Make dynamic shape inference happen)
162 nnfw_tensorinfo ti_new = {NNFW_TYPE_TENSOR_FLOAT32, 2, {1, 2}};
163 NNFW_ENSURE_SUCCESS(nnfw_set_input_tensorinfo(session, 0, &ti_new));
165 std::vector<float> in_buf{1, 1};
166 std::vector<float> out_buf{-1, -1};
169 nnfw_set_input(session, 0, ti_new.dtype, in_buf.data(), in_buf.size() * sizeof(float)));
171 nnfw_set_output(session, 0, ti_new.dtype, out_buf.data(), out_buf.size() * sizeof(float)));
173 NNFW_ENSURE_SUCCESS(nnfw_run(session));
175 ASSERT_EQ(in_buf, out_buf);
177 NNFW_ENSURE_SUCCESS(nnfw_close_session(session));