forked from nudt_dsp/netrans
350 lines
11 KiB
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;
|
|
}
|
|
|