netrans/bin/vxcode/template/nbg_viplite/main_loop.c

350 lines
11 KiB
C

/****************************************************************************
* Generated by NETRANS #NETRANS_VERSION#
*
* Neural Network application project entry file
****************************************************************************/
/*-------------------------------------------
Includes
-------------------------------------------*/
#include <pnna_lite.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <time.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
#define _BASETSD_H
#include "vnn_global.h"
#include "vnn_pre_process.h"
#include "vnn_post_process.h"
/*-------------------------------------------
Macros and Variables
-------------------------------------------*/
const char *usage =
"Usage: \n\
nbg_name input_data1 input_data2...";
/*-------------------------------------------
Functions
-------------------------------------------*/
#define BILLION 1000000000
static pnna_uint64_t get_perf_count()
{
#if defined(__linux__) || defined(__ANDROID__) || defined(__QNX__) || defined(__CYGWIN__)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (pnna_uint64_t)((pnna_uint64_t)ts.tv_nsec + (pnna_uint64_t)ts.tv_sec * BILLION);
#elif defined(_WIN32) || defined(UNDER_CE)
LARGE_INTEGER freq;
LARGE_INTEGER ln;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&ln);
return (uint64_t)(ln.QuadPart * BILLION / freq.QuadPart);
#endif
}
static pnna_status_e prepare_input_data(
pnna_network_items *network_items,
pnna_uint8_t *data[],
pnna_int32_t iteration)
{
pnna_status_e status = PNNA_SUCCESS;
pnna_int32_t i = 0;
pnna_uint32_t buff_size = 0;
pnna_uint8_t *buff_data = PNNA_NULL;
/* Prepare input data */
for (i = 0; i < network_items->input_count; i++) {
buff_data = (pnna_uint8_t *)pnna_map_buffer( network_items->input_buffers[i] );
buff_size = pnna_get_buffer_size( network_items->input_buffers[i] );
memcpy(buff_data, data[i] + buff_size * iteration, buff_size);
/* Set input */
status = pnna_set_input(network_items->network,
i, network_items->input_buffers[i]);
_CHECK_STATUS(status, final);
}
final:
return status;
}
pnna_status_e vnn_InitNetworkItem(
pnna_network_items **network_items,
int argc,
char **argv)
{
/*
* argv0: execute file
* argv1: nbg file
* argv2~n: inputs n files
* notes: Pls give no less than 1 inputs by network's order,
* if the previous input not given, not give the later one.
* The inputs will be initialized to 0, if not given.
*/
pnna_status_e status = PNNA_SUCCESS;
pnna_network_items *nnItems = NULL;
const char *file_name = NULL;
int input_num = 0, i = 0;
char **inputs = NULL;
int name_len = 0;
file_name = (const char *)argv[1];
input_num = argc - 2;
if (input_num <= 0)
{
status = PNNA_ERROR_INVALID_ARGUMENTS;
goto final;
}
inputs = argv + 2;
nnItems = (pnna_network_items *)malloc(sizeof(pnna_network_items));
memset(nnItems, 0, sizeof(pnna_network_items));
name_len = strlen(file_name);
if (name_len <= 0)
{
if (nnItems) {
free(nnItems);
nnItems = NULL;
}
status = PNNA_ERROR_INVALID_ARGUMENTS;
goto final;
}
nnItems->nbg_name = (char *)malloc(name_len + 1);
memset(nnItems->nbg_name, 0, name_len + 1);
strcpy(nnItems->nbg_name, file_name);
nnItems->input_count = input_num;
nnItems->input_names = (char **)malloc(sizeof(char *) * input_num);
for (i = 0; i < input_num; i++)
{
nnItems->input_names[i] = inputs[i];
}
/* for rnn connection */
{
#EXTERNAL_CONNECTIONS#
nnItems->rnn_conn.conn_cnt = _cnt_of_array(connections);
nnItems->rnn_conn.connections = (vsi_nn_rnn_external_connection_t *)malloc(
nnItems->rnn_conn.conn_cnt * sizeof(vsi_nn_rnn_external_connection_t));
memset(nnItems->rnn_conn.connections, 0x00,
nnItems->rnn_conn.conn_cnt * sizeof(vsi_nn_rnn_external_connection_t));
memcpy(nnItems->rnn_conn.connections, connections,
nnItems->rnn_conn.conn_cnt * sizeof(vsi_nn_rnn_external_connection_t));
}
*network_items = nnItems;
final:
return status;
}
static pnna_status_e vnn_CreateNeuralNetwork(
pnna_network_items *network_items)
{
pnna_status_e status = PNNA_SUCCESS;
pnna_uint64_t tmsStart, tmsEnd;
float msVal, usVal;
tmsStart = get_perf_count();
status = pnna_create_network(network_items->nbg_name, 0,
PNNA_CREATE_NETWORK_FROM_FILE, &network_items->network);
_CHECK_STATUS(status, final);
tmsEnd = get_perf_count();
msVal = (float)(tmsEnd - tmsStart)/1000000;
usVal = (float)(tmsEnd - tmsStart)/1000;
printf("Create Neural Network: %.2fms or %.2fus\n", msVal, usVal);
final:
return status;
}
static pnna_status_e vnn_PreProcessNeuralNetwork(
pnna_network_items *network_items)
{
pnna_status_e status = PNNA_SUCCESS;
/* Create input/output buffers, prepare network */
status = vnn_CreateInOutBufPrepareNetwork( network_items );
_CHECK_STATUS( status, final);
/* Set input/output buffers */
status = vnn_SetNetworkInOut( network_items );
_CHECK_STATUS( status, final);
final:
return status;
}
static pnna_status_e vnn_SwapRnnConnInOut(
pnna_network_items *network_items,
pnna_int32_t iter)
{
pnna_status_e status = PNNA_SUCCESS;
pnna_int32_t i = 0;
for (i = 0; i < network_items->rnn_conn.conn_cnt; i++) {
if ((iter % 2) == 0) {
/* Set input */
status = pnna_set_input(network_items->network, network_items->rnn_conn.connections[i].input,
network_items->output_buffers[network_items->rnn_conn.connections[i].output]);
_CHECK_STATUS(status, final);
/* Set output */
status = pnna_set_output(network_items->network, network_items->rnn_conn.connections[i].output,
network_items->input_buffers[network_items->rnn_conn.connections[i].input]);
_CHECK_STATUS(status, final);
} else {
/* Set input */
status = pnna_set_input(network_items->network, network_items->rnn_conn.connections[i].input,
network_items->input_buffers[network_items->rnn_conn.connections[i].input]);
_CHECK_STATUS(status, final);
/* Set output */
status = pnna_set_output(network_items->network, network_items->rnn_conn.connections[i].output,
network_items->output_buffers[network_items->rnn_conn.connections[i].output]);
_CHECK_STATUS(status, final);
}
}
final:
return status;
}
pnna_status_e vnn_RunNeuralNetwork(
pnna_network_items *network_items)
{
pnna_status_e status = PNNA_SUCCESS;
pnna_int32_t i = 0, iteration_cnt = 1;
char *iters = PNNA_NULL;
pnna_uint8_t *data[_MAX_INPUT_NUM] = {PNNA_NULL};
char *file_name = NULL;
pnna_uint32_t file_size = 0, buff_size = 0;
pnna_uint64_t tmsStart, tmsEnd, sigStart, sigEnd;
float msVal, usVal;
file_name = network_items->input_names[0];
file_size = vnn_LoadDataFromFile(network_items, file_name, &data[0], 0);
_CHECK_PTR( data[0], final );
buff_size = pnna_get_buffer_size( network_items->input_buffers[0] );
iteration_cnt = file_size / buff_size;
iters = getenv("ITERATION");
if (iters)
{
iteration_cnt = atoi(iters);
}
for (i = 1; i < network_items->input_count; i++) {
file_name = network_items->input_names[i];
file_size = vnn_LoadDataFromFile(network_items, file_name, &data[i], i);
_CHECK_PTR( data[i], final );
}
/* Run rnn network */
tmsStart = get_perf_count();
printf("Start run graph [%d] iterations...\n", iteration_cnt);
for(i = 0; i < iteration_cnt; i++) {
/* Prepare input data */
status = prepare_input_data( network_items, data, i );
_CHECK_STATUS( status, final );
sigStart = get_perf_count();
/* Run network */
status = pnna_run_network( network_items->network );
_CHECK_STATUS( status, final );
sigEnd = get_perf_count();
/* Swap rnn connection input/output */
status = vnn_SwapRnnConnInOut( network_items, i );
_CHECK_STATUS( status, final );
msVal = (float)(sigEnd - sigStart)/1000000;
usVal = (float)(sigEnd - sigStart)/1000;
printf("Run the %d iteration: %.2fms or %.2fus\n", (i+1), msVal, usVal);
}
tmsEnd = get_perf_count();
msVal = (float)(tmsEnd - tmsStart)/1000000;
usVal = (float)(tmsEnd - tmsStart)/1000;
printf("pnna run network execution time:\n");
printf("Total %.2fms or %.2fus\n", msVal, usVal);
printf("Average %.2fms or %.2fus\n", (float)msVal/iteration_cnt, (float)usVal/iteration_cnt);
final:
for (i = 0; i < _MAX_INPUT_NUM; i++) {
if (data[i]) {
free( data[i] );
data[i] = PNNA_NULL;
}
}
return status;
}
pnna_status_e vnn_PostProcessNeuralNetwork(
pnna_network_items *network_items)
{
return save_output_data( network_items );
}
pnna_status_e vnn_ReleaseNeuralNetwork(
pnna_network_items *network_items)
{
pnna_status_e status = PNNA_SUCCESS;
status = destroy_network( network_items );
_CHECK_STATUS(status, final);
destroy_network_items( network_items );
status = pnna_destroy();
_CHECK_STATUS(status, final);
final:
return status;
}
/*-------------------------------------------
Main Functions
-------------------------------------------*/
int main
(
int argc,
char **argv
)
{
pnna_status_e status = PNNA_SUCCESS;
pnna_network_items *network_items = PNNA_NULL;
printf("%s\n", usage);
if(argc < 3)
{
printf("Arguments count %d is incorrect!\n", argc);
return -1;
}
/* Initialize pnna lite */
status = pnna_init();
_CHECK_STATUS( status, final );
/* Initialize network items */
status = vnn_InitNetworkItem( &network_items, argc, argv );
_CHECK_STATUS( status, final );
/* Create the neural network */
status = vnn_CreateNeuralNetwork( network_items );
_CHECK_STATUS( status, final );
/* Pre process the input/output data */
status = vnn_PreProcessNeuralNetwork( network_items );
_CHECK_STATUS( status, final );
/* Run the neural network */
status = vnn_RunNeuralNetwork( network_items );
_CHECK_STATUS( status, final );
/* Post process output data */
status = vnn_PostProcessNeuralNetwork( network_items );
_CHECK_STATUS( status, final );
final:
/* Destroy resources */
status = vnn_ReleaseNeuralNetwork( network_items );
return status;
}