# 应用示例 ## 异步方式运行神经网络模型 ```c #include #include #include #include "model.h" // NPU编译器生成的模型文件 #define MCU_TO_DEV(x) ((unsigned int)x & 0x0fffffff) static float in_data[xxx]; // 模型输入数据 static struct input in __attribute__((aligned(DCACHE_LINE_SIZE))); static struct output out __attribute__((aligned(DCACHE_LINE_SIZE))); static int is_finished = 0; // float32转换成short,snpu输入和输出是short类型数据,如果原始数据是float,需转换 // 详细可参考FAQ部分 static short float32_to_int16(float in_data, int Q) { int int_value = in_data * (1 << Q); return (int_value > 32767) ? 32767 : ((int_value < -32768) ? -32768 : int_value); } static int gx_snpu_float32_to_int16(short *out_data, float *in_data, int Q, int num) { int i; if (in_data == NULL || out_data == NULL) { printf("[%s] error: para null\n", __FUNCTION__); return -1; } for (i = 0; i < num; i++) { out_data[i] = float32_to_int16(in_data[i], Q); } return 0; } // snpu异步任务运行完成后,会调用该回调函数 static int callback(void *private_data) { gx_dcache_invalid_range((void*)&out, sizeof(out)); // 获取snpu计算结果前,需刷cache // 处理输出数据... is_finished = 1; return 0; } int main (int argc, char **argv) { gx_snpu_init(); // 初始化SNPU int ret; GX_SNPU_TASK task; // 将model.h中的各个数组赋值给GX_SNPU_TASK结构体 task.data = (void*)MCU_TO_DEV(data_content); task.cmd = (void*)MCU_TO_DEV(cmd_content); task.weight = (void*)MCU_TO_DEV(weight_content); task.cache = (void*)MCU_TO_DEV(cache_content); task.input = (void*)MCU_TO_DEV(&in); task.output = (void*)MCU_TO_DEV(&out); gx_snpu_float32_to_int16((short*)&in.Feats, (float*)in_data, FEATS_Q, sizeof(in.Feats)/sizeof(short)); // SNPU只支持int16输入 gx_dcache_clean_range((void*)&in, sizeof(in)); // 数据给snpu使用前,需刷cache ret = gx_snpu_run_task(&task, callback, NULL); // 异步方式运行模型 if (ret) { printf("run task failed\n"); return -1; } while (is_finished == 0); // 等待模型运行完成 gx_snpu_exit(); // 退出SNPU return 0; } ``` ## 同步方式运行神经网络模型 ```c #include #include #include #include "model.h" // NPU编译器生成的模型文件 #define MCU_TO_DEV(x) ((unsigned int)x & 0x0fffffff) static float in_data[xxx]; // 模型输入数据 static struct input in __attribute__((aligned(DCACHE_LINE_SIZE))); static struct output out __attribute__((aligned(DCACHE_LINE_SIZE))); // float32转换成short,snpu输入和输出是short类型数据,如果原始数据是float,需转换 // 详细可参考FAQ部分 static short float32_to_int16(float in_data, int Q) { int int_value = in_data * (1 << Q); return (int_value > 32767) ? 32767 : ((int_value < -32768) ? -32768 : int_value); } static int gx_snpu_float32_to_int16(short *out_data, float *in_data, int Q, int num) { int i; if (in_data == NULL || out_data == NULL) { printf("[%s] error: para null\n", __FUNCTION__); return -1; } for (i = 0; i < num; i++) { out_data[i] = float32_to_int16(in_data[i], Q); } return 0; } int main (int argc, char **argv) { gx_snpu_init(); // 初始化SNPU int ret; GX_SNPU_TASK task; // 将model.h中的各个数组赋值给GX_SNPU_TASK结构体 task.data = (void*)MCU_TO_DEV(data_content); task.cmd = (void*)MCU_TO_DEV(cmd_content); task.weight = (void*)MCU_TO_DEV(weight_content); task.cache = (void*)MCU_TO_DEV(cache_content); task.input = (void*)MCU_TO_DEV(&in); task.output = (void*)MCU_TO_DEV(&out); gx_snpu_float32_to_int16((short*)&in.Feats, in_data, FEATS_Q, sizeof(in.Feats)/sizeof(short)); // SNPU只支持int16输入 gx_dcache_clean_range((void*)&in, sizeof(in)); // 数据给snpu使用前,需刷cache ret = gx_snpu_run_task_sync(&task); // 同步方式运行模型 if (ret) { printf("run task failed\n"); return -1; } gx_dcache_invalid_range((void*)&out, sizeof(out)); // 获取snpu计算结果前,需刷cache gx_snpu_exit(); // 退出SNPU return 0; } ```