1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <fstream>
16
17 #include "nncore_utils.h"
18
19 namespace OHOS {
20 namespace NeuralNetworkRuntime {
21 namespace Test {
TransformUInt32Array(const std::vector<uint32_t> & vector)22 OH_NN_UInt32Array TransformUInt32Array(const std::vector<uint32_t>& vector)
23 {
24 uint32_t* data = (vector.empty()) ? nullptr : const_cast<uint32_t*>(vector.data());
25 return {data, vector.size()};
26 }
27
createTensorDesc(const int32_t * shape,size_t shapeNum,OH_NN_DataType dataType,OH_NN_Format format)28 NN_TensorDesc* createTensorDesc(const int32_t* shape, size_t shapeNum, OH_NN_DataType dataType, OH_NN_Format format)
29 {
30 NN_TensorDesc* tensorDescTmp = OH_NNTensorDesc_Create();
31 if (tensorDescTmp == nullptr) {
32 LOGE("[NNRtTest]OH_NNTensorDesc_Create failed!");
33 return nullptr;
34 }
35
36 OH_NN_ReturnCode ret = OH_NNTensorDesc_SetDataType(tensorDescTmp, dataType);
37 if (ret != OH_NN_SUCCESS) {
38 LOGE("[NNRtTest]OH_NNTensorDesc_SetDataType failed!ret = %d\n", ret);
39 return nullptr;
40 }
41
42 if (shape != nullptr) {
43 ret = OH_NNTensorDesc_SetShape(tensorDescTmp, shape, shapeNum);
44 if (ret != OH_NN_SUCCESS) {
45 LOGE("[NNRtTest]OH_NNTensorDesc_SetShape failed!ret = %d\n", ret);
46 return nullptr;
47 }
48 }
49
50 ret = OH_NNTensorDesc_SetFormat(tensorDescTmp, format);
51 if (ret != OH_NN_SUCCESS) {
52 LOGE("[NNRtTest]OH_NNTensorDesc_SetShape failed!ret = %d\n", ret);
53 return nullptr;
54 }
55
56 return tensorDescTmp;
57 }
58
SingleModelBuildEndStep(OH_NNModel * model,const OHNNGraphArgs & graphArgs)59 int SingleModelBuildEndStep(OH_NNModel *model, const OHNNGraphArgs &graphArgs)
60 {
61 int ret = 0;
62 auto paramIndices = TransformUInt32Array(graphArgs.paramIndices);
63 auto inputIndices = TransformUInt32Array(graphArgs.inputIndices);
64 auto outputIndices = TransformUInt32Array(graphArgs.outputIndices);
65
66 if (graphArgs.addOperation) {
67 ret = OH_NNModel_AddOperation(model, graphArgs.operationType, ¶mIndices, &inputIndices,
68 &outputIndices);
69 if (ret != OH_NN_SUCCESS) {
70 LOGE("[NNRtTest] OH_NNModel_AddOperation failed! ret=%{public}d\n", ret);
71 return ret;
72 }
73 }
74
75 if (graphArgs.specifyIO) {
76 ret = OH_NNModel_SpecifyInputsAndOutputs(model, &inputIndices, &outputIndices);
77 if (ret != OH_NN_SUCCESS) {
78 LOGE("[NNRtTest] OH_NNModel_SpecifyInputsAndOutputs failed! ret=%{public}d\n", ret);
79 return ret;
80 }
81 }
82
83 if (graphArgs.build) {
84 ret = OH_NNModel_Finish(model);
85 if (ret != OH_NN_SUCCESS) {
86 LOGE("[NNRtTest] OH_NNModel_Finish failed! ret=%d\n", ret);
87 return ret;
88 }
89 }
90 return ret;
91 }
92
BuildSingleOpGraph(OH_NNModel * model,const OHNNGraphArgs & graphArgs)93 int BuildSingleOpGraph(OH_NNModel *model, const OHNNGraphArgs &graphArgs)
94 {
95 int ret = 0;
96 for (size_t i = 0; i < graphArgs.operands.size(); i++) {
97 const OHNNOperandTest &operandTem = graphArgs.operands[i];
98 NN_TensorDesc* tensorDesc = createTensorDesc(operandTem.shape.data(),
99 (uint32_t) operandTem.shape.size(),
100 operandTem.dataType, operandTem.format);
101
102 ret = OH_NNModel_AddTensorToModel(model, tensorDesc);
103 if (ret != OH_NN_SUCCESS) {
104 LOGE("[NNRtTest] OH_NNModel_AddTensor failed! ret=%d\n", ret);
105 return ret;
106 }
107
108 ret = OH_NNModel_SetTensorType(model, i, operandTem.type);
109 if (ret != OH_NN_SUCCESS) {
110 LOGE("[NNRtTest] OH_NNBackend_SetModelTensorType failed! ret=%d\n", ret);
111 return ret;
112 }
113
114 if (std::find(graphArgs.paramIndices.begin(), graphArgs.paramIndices.end(), i) !=
115 graphArgs.paramIndices.end()) {
116 ret = OH_NNModel_SetTensorData(model, i, operandTem.data, operandTem.length);
117 if (ret != OH_NN_SUCCESS) {
118 LOGE("[NNRtTest] OH_NNModel_SetTensorData failed! ret=%{public}d\n", ret);
119 return ret;
120 }
121 }
122 OH_NNTensorDesc_Destroy(&tensorDesc);
123 }
124 ret = SingleModelBuildEndStep(model, graphArgs);
125 return ret;
126 }
127
GetDeviceID(size_t * deviceId)128 OH_NN_ReturnCode GetDeviceID(size_t *deviceId)
129 {
130 OH_NN_ReturnCode ret = OH_NN_FAILED;
131 const size_t *devicesID{nullptr};
132 uint32_t devicesCount{0};
133
134 ret = OH_NNDevice_GetAllDevicesID(&devicesID, &devicesCount);
135 if (ret != OH_NN_SUCCESS) {
136 LOGE("[NNRtTest] OH_NNDevice_GetAllDevicesID failed! ret=%d\n", ret);
137 return ret;
138 }
139
140 if (devicesCount <= NO_DEVICE_COUNT) {
141 LOGE("[NNRtTest] devicesCount <= 0 devicesCount=%d\n", devicesCount);
142 return OH_NN_FAILED;
143 }
144
145 const char *name = nullptr;
146 std::string deviceName{"Device-CPU_TestVendor_v2_1"};
147 for (uint32_t i = 0; i < devicesCount; i++) {
148 name = nullptr;
149 ret = OH_NNDevice_GetName(devicesID[i], &name);
150 if (ret != OH_NN_SUCCESS) {
151 LOGE("[NNRtTest] OH_NNDevice_GetName failed! ret=%d\n", ret);
152 return ret;
153 }
154
155 std::string sName(name);
156 if (deviceName == sName) {
157 *deviceId = devicesID[i];
158 return OH_NN_SUCCESS;
159 }
160 }
161 return OH_NN_FAILED;
162 }
163
CompileGraphMock(OH_NNCompilation * compilation,const OHNNCompileParam & compileParam)164 int CompileGraphMock(OH_NNCompilation *compilation, const OHNNCompileParam &compileParam)
165 {
166 int ret = 0;
167
168 // set cache
169 if (!compileParam.cacheDir.empty()) {
170 ret = OH_NNCompilation_SetCache(compilation, compileParam.cacheDir.c_str(),
171 compileParam.cacheVersion);
172 if (ret != OH_NN_SUCCESS) {
173 LOGE("[NNRtTest] OH_NNCompilation_SetCache failed! ret=%d\n", ret);
174 return ret;
175 }
176 }
177
178 // set performance
179 if (compileParam.performanceMode != OH_NN_PERFORMANCE_NONE) {
180 ret = OH_NNCompilation_SetPerformanceMode(compilation, compileParam.performanceMode);
181 if (ret != OH_NN_SUCCESS) {
182 LOGE("[NNRtTest] OH_NNCompilation_SetPerformanceMode failed! ret=%d\n", ret);
183 return ret;
184 }
185 }
186
187 // set priority
188 if (compileParam.priority != OH_NN_PRIORITY_NONE) {
189 ret = OH_NNCompilation_SetPriority(compilation, compileParam.priority);
190 if (ret != OH_NN_SUCCESS) {
191 LOGE("[NNRtTest] OH_NNCompilation_SetPriority failed! ret=%d\n", ret);
192 return ret;
193 }
194 }
195
196 // enable fp16
197 if (compileParam.enableFp16) {
198 ret = OH_NNCompilation_EnableFloat16(compilation, compileParam.enableFp16);
199 if (ret != OH_NN_SUCCESS) {
200 LOGE("[NNRtTest] OH_NNCompilation_EnableFloat16 failed! ret=%d\n", ret);
201 return ret;
202 }
203 }
204
205 // build
206 ret = OH_NNCompilation_Build(compilation);
207 return ret;
208 }
209
Free(OH_NNModel * model,OH_NNCompilation * compilation,OH_NNExecutor * executor)210 void Free(OH_NNModel *model, OH_NNCompilation *compilation, OH_NNExecutor *executor)
211 {
212 if (model != nullptr) {
213 OH_NNModel_Destroy(&model);
214 ASSERT_EQ(nullptr, model);
215 }
216
217 if (compilation != nullptr) {
218 OH_NNCompilation_Destroy(&compilation);
219 ASSERT_EQ(nullptr, compilation);
220 }
221
222 if (executor != nullptr) {
223 OH_NNExecutor_Destroy(&executor);
224 ASSERT_EQ(nullptr, executor);
225 }
226 }
227
FreeTensorDescVec(std::vector<NN_TensorDesc * > tensorDescVec)228 void FreeTensorDescVec(std::vector<NN_TensorDesc*> tensorDescVec)
229 {
230 if (!tensorDescVec.empty()) {
231 for (auto tensorDesc : tensorDescVec) {
232 OH_NNTensorDesc_Destroy(&tensorDesc);
233 ASSERT_EQ(nullptr, tensorDesc);
234 }
235 }
236 }
237 } // namespace Test
238 } // namespace NeuralNetworkRuntime
239 } // namespace OHOS