1 /*
2 * Copyright 2023 Unionman Technology Co., Ltd.
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 /*-------------------------------------------
18 Includes
19 -------------------------------------------*/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #ifdef __linux__
24 #include <time.h>
25 #elif defined(_WIN32)
26 #include <windows.h>
27 #endif
28
29 #define _BASETSD_H
30
31 #include "vsi_nn_pub.h"
32
33 #include "vnn_global.h"
34 #include "vnn_pre_process.h"
35 #include "vnn_post_process.h"
36 #include "vnn_Lenet.h"
37
38 /*-------------------------------------------
39 Macros and Variables
40 -------------------------------------------*/
41
42 /*-------------------------------------------
43 Functions
44 -------------------------------------------*/
vnn_ReleaseNeuralNetwork(vsi_nn_graph_t * graph)45 static void vnn_ReleaseNeuralNetwork(vsi_nn_graph_t *graph)
46 {
47 vnn_ReleaseLenet(graph, TRUE);
48 if (vnn_UseImagePreprocessNode()) {
49 vnn_ReleaseBufferImage();
50 }
51 }
52
vnn_PostProcessNeuralNetwork(vsi_nn_graph_t * graph)53 static vsi_status vnn_PostProcessNeuralNetwork(vsi_nn_graph_t *graph)
54 {
55 return vnn_PostProcessLenet(graph);
56 }
57
58 #define BILLION 1000000000
get_perf_count()59 static uint64_t get_perf_count()
60 {
61 #if defined(__linux__) || defined(__ANDROID__) || defined(__QNX__) || defined(__CYGWIN__)
62 struct timespec ts;
63
64 clock_gettime(CLOCK_MONOTONIC, &ts);
65
66 return (uint64_t)((uint64_t)ts.tv_nsec + (uint64_t)ts.tv_sec * BILLION);
67 #elif defined(_WIN32) || defined(UNDER_CE)
68 LARGE_INTEGER ln;
69
70 QueryPerformanceCounter(&ln);
71
72 return (uint64_t)ln.QuadPart;
73 #endif
74 }
75
vnn_VerifyGraph(vsi_nn_graph_t * graph)76 static vsi_status vnn_VerifyGraph(vsi_nn_graph_t *graph)
77 {
78 vsi_status status = VSI_FAILURE;
79 uint64_t tmsStart;
80 uint64_t tmsEnd;
81 uint64_t msVal;
82 uint64_t usVal;
83
84 /* Verify graph */
85 printf("Verify...\n");
86 tmsStart = get_perf_count();
87 status = vsi_nn_VerifyGraph(graph);
88 TEST_CHECK_STATUS(status, final);
89 tmsEnd = get_perf_count();
90 msVal = (tmsEnd - tmsStart) / 1000000.f;
91 usVal = (tmsEnd - tmsStart) / 1000.f;
92 printf("Verify Graph: %ldms or %ldus\n", msVal, usVal);
93
94 final:
95 return status;
96 }
97
vnn_ProcessGraph(vsi_nn_graph_t * graph)98 static vsi_status vnn_ProcessGraph(vsi_nn_graph_t *graph)
99 {
100 vsi_status status = VSI_FAILURE;
101 int32_t i;
102 int32_t loop;
103 char *loop_s;
104 uint64_t tmsStart;
105 uint64_t tmsEnd;
106 uint64_t sigStart;
107 uint64_t sigEnd;
108 float msVal;
109 float usVal;
110
111 status = VSI_FAILURE;
112 loop = 1; /* default loop time is 1 */
113 loop_s = getenv("VNN_LOOP_TIME");
114 if (loop_s) {
115 loop = atoi(loop_s);
116 }
117
118 /* Run graph */
119 tmsStart = get_perf_count();
120 printf("Start run graph [%d] times...\n", loop);
121 for (i = 0; i < loop; i++) {
122 sigStart = get_perf_count();
123 #ifdef VNN_APP_ASYNC_RUN
124 status = vsi_nn_AsyncRunGraph(graph);
125 if (status != VSI_SUCCESS) {
126 printf("Async Run graph the %d time fail\n", i);
127 }
128 TEST_CHECK_STATUS(status, final);
129
130 // do something here...
131
132 status = vsi_nn_AsyncRunWait(graph);
133 if (status != VSI_SUCCESS) {
134 printf("Wait graph the %d time fail\n", i);
135 }
136 #else
137 status = vsi_nn_RunGraph(graph);
138 if (status != VSI_SUCCESS) {
139 printf("Run graph the %d time fail\n", i);
140 }
141 #endif
142 TEST_CHECK_STATUS(status, final);
143
144 sigEnd = get_perf_count();
145 msVal = (sigEnd - sigStart) / 1000000.f;
146 usVal = (sigEnd - sigStart) / 1000.f;
147 printf("Run the %u time: %.2fms or %.2fus\n", (i + 1), msVal, usVal);
148 }
149 tmsEnd = get_perf_count();
150 msVal = (tmsEnd - tmsStart) / 1000000.f;
151 usVal = (tmsEnd - tmsStart) / 1000.f;
152 printf("vxProcessGraph execution time:\n");
153 printf("Total %.2fms or %.2fus\n", msVal, usVal);
154
155 if (loop == 0) {
156 // error
157 return NULL;
158 }
159 printf("Average %.2fms or %.2fus\n", ((float)usVal) / 1000.f / loop, ((float)usVal) / loop);
160
161 final:
162 return status;
163 }
164
vnn_PreProcessNeuralNetwork(vsi_nn_graph_t * graph,int argc,char ** argv)165 static vsi_status vnn_PreProcessNeuralNetwork(vsi_nn_graph_t *graph, int argc, char **argv)
166 {
167 /*
168 * argv0: execute file
169 * argv1: data file
170 * argv2~n: inputs n file
171 */
172 const char **inputs = (const char **)argv + 2;
173 uint32_t input_num = argc - 2;
174
175 return vnn_PreProcessLenet(graph, inputs, input_num);
176 }
177
vnn_CreateNeuralNetwork(const char * data_file_name)178 static vsi_nn_graph_t *vnn_CreateNeuralNetwork(const char *data_file_name)
179 {
180 vsi_nn_graph_t *graph = NULL;
181 uint64_t tmsStart;
182 uint64_t tmsEnd;
183 uint64_t msVal;
184 uint64_t usVal;
185
186 tmsStart = get_perf_count();
187 graph = vnn_CreateLenet(data_file_name, NULL, vnn_GetPreProcessMap(), vnn_GetPreProcessMapCount(),
188 vnn_GetPostProcessMap(), vnn_GetPostProcessMapCount());
189 TEST_CHECK_PTR(graph, final);
190 tmsEnd = get_perf_count();
191 msVal = (tmsEnd - tmsStart) / 1000000.f;
192 usVal = (tmsEnd - tmsStart) / 1000.f;
193 printf("Create Neural Network: %ldms or %ldus\n", msVal, usVal);
194
195 final:
196 return graph;
197 }
198
199 /*-------------------------------------------
200 Main Functions
201 -------------------------------------------*/
main(int argc,char ** argv)202 int main(int argc, char **argv)
203 {
204 vsi_status status = VSI_FAILURE;
205 vsi_nn_graph_t *graph;
206 const char *data_name = NULL;
207
208 if (argc < 3L) {
209 printf("Usage: %s data_file inputs...\n", argv[0]);
210 return -1;
211 }
212
213 data_name = (const char *)argv[1];
214
215 /* Create the neural network */
216 graph = vnn_CreateNeuralNetwork(data_name);
217 TEST_CHECK_PTR(graph, final);
218
219 /* Pre process the image data */
220 status = vnn_PreProcessNeuralNetwork(graph, argc, argv);
221 TEST_CHECK_STATUS(status, final);
222
223 /* Verify graph */
224 status = vnn_VerifyGraph(graph);
225 TEST_CHECK_STATUS(status, final);
226
227 /* Process graph */
228 status = vnn_ProcessGraph(graph);
229 TEST_CHECK_STATUS(status, final);
230
231 vsi_nn_DumpGraphNodeOutputs(graph, "./network_dump", NULL, 0, TRUE, (vsi_nn_dim_fmt_e)0);
232 TEST_CHECK_STATUS(status, final);
233
234 status = vnn_PostProcessLenet(graph);
235 TEST_CHECK_STATUS(status, final);
236
237 final:
238 vnn_ReleaseNeuralNetwork(graph);
239 fflush(stdout);
240 fflush(stderr);
241 return status;
242 }
243