123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- /* auto generate by HHB_VERSION "2.0.21" */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdint.h>
- #include <libgen.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <pthread.h>
- #include <memory.h>
- #include "process_linker_types.h"
- #include "io.h"
- #include "shl_ref.h"
- #include "process.h"
- #include "video_mem.h"
- #include "detect.h"
- #include "output_120_out0_nchw_1_2_7668_1.h"
- #define MODULE_NAME "npu_sink_src_test"
- #define MIN(x, y) ((x) < (y) ? (x) : (y))
- #define FILE_LENGTH 1028
- #define SHAPE_LENGHT 128
- #ifndef NULL
- #define NULL ((void *)0)
- #endif
- #define NUM_OF_BUFFERS 5
- #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
- } while (0)
- void *csinn_(char *params);
- void csinn_run(void *data0, void *td);
- void *csinn_nbg(const char *nbg_file_name);
- #define OUT_SIZE1 (1*7668)
- #define OUT_SIZE2 (1917*21)
- int input_size[] = {1 * 3 * 304 * 304, };
- int output_size[] = {OUT_SIZE1, OUT_SIZE1 * 2, 1 * OUT_SIZE2, };
- const char model_name[] = "network";
- #define R_MEAN 127.5
- #define G_MEAN 127.5
- #define B_MEAN 127.5
- #define SCALE (1.0/127.5)
- float mean[] = {B_MEAN, G_MEAN, R_MEAN};
- const char class_name[][FILE_LENGTH] = {
- "background", "aeroplane", "bicycle", "bird", "boat",
- "bottle", "bus", "car", "cat", "chair", "cow", "diningtable",
- "dog", "horse", "motorbike", "person", "pottedplant", "sheep",
- "sofa", "train", "tvmonitor"
- };
- const char shm_sink_name[] = "/ispnpu";
- const char shm_src_name[] = "/npu_g2d";
- #define BASE_MEMORY 0xD8000000
- typedef struct _ServerParams
- {
- char *plinkname;
- int count;
- int frames;
- } ServerParams;
- typedef struct _PlinkChannel
- {
- PlinkChannelID id;
- PlinkHandle plink;
- PlinkPacket pkt;
- int sendid;
- int backid;
- int exit;
- int available_bufs;
- } PlinkChannel;
- typedef struct _FeatureBuffer {
- unsigned int bus_address;
- void *virtual_address;
- unsigned int size;
- } FeatureBuffer;
- void parseParams(int argc, char **argv, ServerParams *params)
- {
- int i = 1;
- memset(params, 0, sizeof(*params));
- params->plinkname = "/tmp/plink_npu_featuremap.test";
- params->frames = 3;
- while (i < argc)
- {
- if (argv[i][0] != '-' || strlen(argv[i]) < 2)
- {
- i++;
- continue;
- }
- if (argv[i][1] == 'l')
- {
- if (++i < argc)
- {
- params->plinkname = argv[i++];
- }
- }
- else if (argv[i][1] == 'n')
- {
- if (++i < argc)
- {
- params->frames = atoi(argv[i++]);
- }
- }
- };
- }
- int checkParams(ServerParams *params)
- {
- if (params->plinkname == NULL)
- return -1;
- return 0;
- }
- void printUsage(char *name)
- {
- printf("usage: %s [options]\n"
- "\n"
- " Available options:\n"
- " -l plink file name (default: /tmp/plink.test)\n"
- " -i input YUV file name (mandatory)\n"
- " -f input color format (default: 2)\n"
- " 2 - I420\n"
- " 3 - NV12\n"
- " -w video width (mandatory)\n"
- " -h video height (mandatory)\n"
- " -s video buffer stride (default: video width)\n"
- " -n number of frames to send (default: 10)\n"
- "\n", name);
- }
- int getBufferSize(ServerParams *params)
- {
- return sizeof(PlinkObjectDetect);
- }
- void constructFeatureInfo(PlinkObjectInfo *info, ServerParams *params, unsigned int bus_address, int face_cnt, int id)
- {
- info->header.type = PLINK_TYPE_OBJECT;
- info->header.size = DATA_SIZE(*info);
- info->header.id = id + 1;
- info->bus_address = bus_address;
- info->object_cnt = face_cnt;
- }
- int getBufferCount(PlinkPacket *pkt)
- {
- int ret = 0;
- for (int i = 0; i < pkt->num; i++)
- {
- PlinkDescHdr *hdr = (PlinkDescHdr *)(pkt->list[i]);
- if (hdr->type == PLINK_TYPE_MESSAGE)
- {
- int *data = (int *)(pkt->list[i] + DATA_HEADER_SIZE);
- if (*data == PLINK_EXIT_CODE)
- {
- ret |= 0x80000000; // set bit 31 to 1 to indicate 'exit'
- }
- else if (*data >= 0)
- ret++;
- }
- }
- return ret;
- }
- void retreiveSentBuffers(PlinkHandle plink, PlinkChannel *channel)
- {
- PlinkStatus sts = PLINK_STATUS_OK;
- while (channel->available_bufs < NUM_OF_BUFFERS)
- {
- do
- {
- sts = PLINK_recv(plink, channel->id, &channel->pkt);
- int count = getBufferCount(&channel->pkt);
- if (count > 0)
- {
- channel->available_bufs += count;
- }
- } while (sts == PLINK_STATUS_MORE_DATA);
- }
- }
- void AllocateBuffers(FeatureBuffer featurebuffers[NUM_OF_BUFFERS], unsigned int size, int fd_mem) {
- unsigned int bus_address = BASE_MEMORY;
- unsigned int buffer_size = (size + 0xFFF) & ~0xFFF;
- for (int i = 0; i < NUM_OF_BUFFERS; i++) {
- featurebuffers[i].virtual_address = mmap(0, buffer_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd_mem,
- bus_address);
- printf("mmap %p from %x with size %d\n", featurebuffers[i].virtual_address, bus_address, size);
- featurebuffers[i].bus_address = bus_address;
- featurebuffers[i].size = buffer_size;
- bus_address += buffer_size;
- }
- }
- void FreeBuffers(FeatureBuffer featurebuffers[NUM_OF_BUFFERS], unsigned int size, int fd_mem) {
- for (int i = 0; i < NUM_OF_BUFFERS; i++) {
- munmap(featurebuffers[i].virtual_address, featurebuffers[i].size);
- }
- }
- static void print_tensor_info(struct csinn_tensor *t) {
- printf("\n=== tensor info ===\n");
- printf("shape: ");
- for (int j = 0; j < t->dim_count; j++) {
- printf("%d ", t->dim[j]);
- }
- printf("\n");
- if (t->dtype == CSINN_DTYPE_UINT8) {
- printf("scale: %f\n", t->qinfo->scale);
- printf("zero point: %d\n", t->qinfo->zero_point);
- }
- printf("data pointer: %p\n", t->data);
- }
- /*
- * Postprocess function
- */
- static void postprocess(void *sess, const char *filename_prefix, BBoxOut *out, int *num) {
- int output_num, input_num;
- struct csinn_tensor *input = csinn_alloc_tensor(NULL);
- struct csinn_tensor *output = csinn_alloc_tensor(NULL);
- //input_num = csinn_get_input_number(sess);
- //for (int i = 0; i < input_num; i++) {
- // input->data = NULL;
- // csinn_get_input(i, input, sess);
- // //print_tensor_info(input);
-
- // struct csi_tensor *finput = shl_ref_tensor_transform_f32(input);
- // char filename[FILE_LENGTH] = {0};
- // char shape[SHAPE_LENGHT] = {0};
- // shape2string(input->dim, input->dim_count, shape, SHAPE_LENGHT);
- // snprintf(filename, FILE_LENGTH, "%s_input%u_%s.txt", filename_prefix, i, shape);
- // int input_size = csi_tensor_size(input);
- //printf("input_size: %d\n", input_size);
- //save_data_to_file(filename, (float*)finput->data, input_size);
- //}
- float *location = (float*)malloc(OUT_SIZE1*sizeof(float));
- float *confidence = (float*)malloc(OUT_SIZE2*sizeof(float));
- output_num = csinn_get_output_number(sess);
- for (int i = 0; i < output_num; i++) {
- output->data = NULL;
- csinn_get_output(i, output, sess);
- //print_tensor_info(output);
- struct csinn_tensor *foutput = shl_ref_tensor_transform_f32(output);
- //shl_show_top5(foutput, sess);
- //char filename[FILE_LENGTH] = {0};
- //char shape[SHAPE_LENGHT] = {0};
- //shape2string(output->dim, output->dim_count, shape, SHAPE_LENGHT);
- //snprintf(filename, FILE_LENGTH, "%s_output%u_%s.txt", filename_prefix, i, shape);
- //int output_size = csinn_tensor_size(foutput);
- //save_data_to_file(filename, (float*)foutput->data, output_size);
- if (i == 0)
- memcpy(location, (float *)foutput->data, OUT_SIZE1*sizeof(float));
- if (i == 1)
- memcpy(confidence, (float *)foutput->data, OUT_SIZE2*sizeof(float));
- shl_ref_tensor_transform_free_f32(foutput);
- }
- //BBoxOut out[100];
- BBox gbboxes[num_prior];
- *num = ssdforward(location, confidence, priorbox, gbboxes, out);
- free(location);
- free(confidence);
- printf("%d\n", *num);
- for (int i = 0; i < *num; i++) {
- fprintf(stderr, "%d, label=%s, score=%f, x1=%f, y1=%f, x2=%f, y2=%f\n", out[i].label, class_name[out[i].label],
- out[i].score, out[i].xmin, out[i].ymin, out[i].xmax, out[i].ymax);
- }
- csinn_free_tensor(input);
- csinn_free_tensor(output);
- }
- void *create_graph(char *params_path) {
- void *ret;
- int binary_size;
- char *params = get_binary_from_file(params_path, &binary_size);
- if (params == NULL) {
- return NULL;
- }
- char *suffix = params_path + (strlen(params_path) - 7);
- if (strcmp(suffix, ".params") == 0) {
- // create general graph
- ret = csinn_(params);
- free(params);
- return ret;
- }
- suffix = params_path + (strlen(params_path) - 3);
- if (strcmp(suffix, ".bm") == 0) {
- struct shl_bm_sections *section = (struct shl_bm_sections *)(params + 4128);
- if (section->graph_offset) {
- ret = csinn_import_binary_model(params);
- free(params);
- return ret;
- } else {
- ret = csinn_(params + section->params_offset * 4096);
- free(params);
- return ret;
- }
- } else {
- free(params);
- return NULL;
- }
- }
- bool is_looping = true;
- int main(int argc, char **argv) {
- char **data_path = NULL;
- char *params_path = NULL;
- int input_num = 1;
- int output_num = 3;
- int input_group_num = 1;
- int index = 0;
- int export_index = 0;
- PlinkStatus sts = PLINK_STATUS_OK;
- PlinkPacket sendpkt, recvpkt;
- PlinkMsg msg;
- PlinkHandle plink_npu_sink = NULL;
- PlinkHandle plink_npu_src = NULL;
- ServerParams params;
- VmemParams vmem_params;
- void *vmem = NULL;
- PlinkChannel channel[2];
- PlinkObjectInfo feat_map;
- FILE *fp = NULL;
- int exitcode = 0;
- int i;
- if (argc < (2 + input_num)) {
- printf("Please set valide args: ./model.elf model.params "
- "[tensor1/image1 ...] [tensor2/image2 ...]\n");
- return -1;
- } else {
- if (argc == 3 && get_file_type(argv[2]) == FILE_TXT) {
- data_path = read_string_from_file(argv[2], &input_group_num);
- input_group_num /= input_num;
- } else {
- data_path = argv + 2;
- input_group_num = (argc - 2) / input_num;
- }
- }
- parseParams(argc, argv, ¶ms);
- if (checkParams(¶ms) != 0)
- {
- printUsage(argv[0]);
- return 0;
- }
- void *sess = create_graph(argv[1]);
- uint8_t *input[input_num];
- float *finput[input_num];
- char filename_prefix[FILE_LENGTH] = {0};
- void *input_aligned[input_num];
- for (i = 0; i < input_num; i++) {
- input_aligned[i] = shl_mem_alloc_aligned(input_size[i], 0);
- }
- uint64_t start_time, end_time;
- uint64_t _start_time, _end_time;
-
- //int frames = argc > 1 ? atoi(argv[1]) : 1000;
- int frames = 1000;
- //char *dumpname = argc > 2 ? argv[2] : NULL;
- char *dumpname = NULL;
- if (dumpname != NULL)
- {
- fp = fopen(dumpname, "wb");
- if (fp == NULL)
- errExit("fopen");
- }
- if (VMEM_create(&vmem) != VMEM_STATUS_OK)
- errExit("Failed to create VMEM.");
- int fd_mem = open("/dev/mem", O_RDWR | O_SYNC);
- if (fd_mem == -1) {
- printf("ERROR: failed to open: %s\n", "/dev/mem");
- return -1;
- }
- int fd_src_mem = open("/dev/mem", O_RDWR | O_SYNC);
- if (fd_src_mem < 0) {
- printf("%s: failed to open /dev/mem", MODULE_NAME);
- return -1;
- }
- BBoxOut out[100];
- int out_num = 0;
- FeatureBuffer featurebuffers[NUM_OF_BUFFERS];
- AllocateBuffers(featurebuffers, 100 * sizeof(struct _FeatureBuffer), fd_mem);
- printf("PLINK begin to create & connect /tmp/plink_npu_rgb.test\n");
- if (PLINK_create(&plink_npu_sink, "/tmp/plink_npu_rgb.test", PLINK_MODE_CLIENT) != PLINK_STATUS_OK)
- errExit("Failed to create PLINK.");
- if (PLINK_connect(plink_npu_sink, NULL) != PLINK_STATUS_OK)
- errExit("Failed to connect to server.");
- printf("PLINK begin to create & connect %s\n", params.plinkname);
- sts = PLINK_create(&plink_npu_src, params.plinkname, PLINK_MODE_SERVER);
- memset(&channel[0], 0, sizeof(channel[0]));
- channel[0].available_bufs = NUM_OF_BUFFERS;
- sts = PLINK_connect(plink_npu_src, &channel[0].id);
-
- printf("begin to loops\n");
- int frmcnt = 0;
- // while loop to receive shm picture
- do {
- sts = PLINK_recv(plink_npu_sink, 0, &recvpkt);
- memset(&vmem_params, 0, sizeof(vmem_params));
- if (recvpkt.fd != PLINK_INVALID_FD) { // dmabuf fd
- vmem_params.fd = recvpkt.fd;
- if (VMEM_import(vmem, &vmem_params) != VMEM_STATUS_OK)
- errExit("Failed to import fd.");
- printf("%s: recvpkt.fd<%d> phy<0x%lx>\n", MODULE_NAME, vmem_params.fd, vmem_params.phy_address);
- }
- for (i = 0; i < recvpkt.num; i++) {
- PlinkDescHdr *hdr = (PlinkDescHdr *)(recvpkt.list[i]);
- if (hdr->type == PLINK_TYPE_2D_RGB) {
- uint8_t *vaddr = 0;
- PlinkRGBInfo *pic = (PlinkRGBInfo *)(recvpkt.list[i]);
- printf("[CLIENT] Received frame %d 0x%010llx: %dx%d, stride = %d\n",
- pic->header.id, pic->bus_address_b,
- pic->img_width, pic->img_height,
- pic->stride_b);
- int size_stride = 3 * pic->stride_b * pic->stride_b;
- if (recvpkt.fd == PLINK_INVALID_FD) { // physical address
- vaddr = (uint8_t *) mmap(0, size_stride, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd_mem, pic->bus_address_b);
- }
- // return the buffer to source
- msg.header.type = PLINK_TYPE_MESSAGE;
- msg.header.size = DATA_SIZE(PlinkMsg);
- msg.msg = hdr->id;
- sendpkt.list[0] = &msg;
- sendpkt.num = 1;
- sendpkt.fd = PLINK_INVALID_FD;
- if (PLINK_send(plink_npu_sink, 0, &sendpkt) == PLINK_STATUS_ERROR)
- errExit("Failed to send data.");
- _start_time = shl_get_timespec();
- if (recvpkt.fd == PLINK_INVALID_FD) { // physical address
- csinn_run(vaddr, sess);
- } else {
- csinn_run(&vmem_params.fd, sess);
- }
- _end_time = shl_get_timespec();
- printf("Run graph execution time: %.5fms, FPS=%.2f\n", ((float)(_end_time-_start_time))/1000000,
- 1000000000.0/((float)(_end_time-_start_time)));
- //snprintf(filename_prefix, FILE_LENGTH, "%s", basename(data_path[i * input_num]));
- _start_time = shl_get_timespec();
- postprocess(sess, filename_prefix, out, &out_num);
- _end_time = shl_get_timespec();
- printf("postProcess execution time: %.5fms\n", ((float)(_end_time-_start_time))/1000000);
- if (recvpkt.fd == PLINK_INVALID_FD) // physical address
- munmap(vaddr, size_stride);
- int sendid = channel[0].sendid;
- int face_cnt = 0;
- float *ptr = (float *)featurebuffers[sendid].virtual_address;
- for (int i = 0; i < out_num; i++) {
- if (strcmp(class_name[out[i].label], "person") == 0) {
- // ignore rects too low or too fat
- //if ((out[i].ymin > 0.3) || ((out[i].ymax - out[i].ymin) < (out[i].xmax - out[i].xmin)))
- // continue;
- face_cnt++;
- *ptr++ = out[i].score;
- *ptr++ = out[i].xmin;
- *ptr++ = out[i].ymin;
- *ptr++ = out[i].xmax;
- *ptr++ = out[i].ymax;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- *ptr++ = -1;
- }
- }
- if (face_cnt > 0) {
- constructFeatureInfo(&feat_map, ¶ms, featurebuffers[sendid].bus_address, face_cnt, sendid);
- printf("[FeatureMap SERVER] Processed frame %d 0x%08x: %d\n",
- sendid, feat_map.bus_address, face_cnt);
- channel[0].pkt.list[0] = &feat_map;
- channel[0].pkt.num = 1;
- //channel[0].pkt.fd = picbuffers[sendid].fd;
- channel[0].pkt.fd = PLINK_INVALID_FD; // physical address
- sts = PLINK_send(plink_npu_src, channel[0].id, &channel[0].pkt);
- channel[0].sendid = (channel[0].sendid + 1) % NUM_OF_BUFFERS;
- channel[0].available_bufs -= 1;
- // Notify npu one picture is ready for inference
- int timeout = 0;
- if (channel[0].available_bufs == 0)
- timeout = 60000; // wait up to 60 seconds if buffers are used up
- if (PLINK_wait(plink_npu_src, channel[0].id, timeout) == PLINK_STATUS_OK)
- {
- do
- {
- sts = PLINK_recv(plink_npu_src, channel[0].id, &channel[0].pkt);
- int count = getBufferCount(&channel[0].pkt);
- if (count < 0)
- channel[0].exit = 1;
- channel[0].available_bufs += count;
- } while (sts == PLINK_STATUS_MORE_DATA);
- }
- }
- }
- else if (hdr->type == PLINK_TYPE_MESSAGE)
- {
- PlinkMsg *msg = (PlinkMsg *)(recvpkt.list[i]);
- if (msg->msg == PLINK_EXIT_CODE)
- {
- exitcode = 1;
- printf("Exit\n");
- break;
- }
- }
- }
- if (recvpkt.fd != PLINK_INVALID_FD) { // dmabuf fd
- if (VMEM_release(vmem, &vmem_params) != VMEM_STATUS_OK)
- errExit("Failed to release buffer.");
- close(recvpkt.fd);
- }
- frmcnt++;
- #if 0
- if (frmcnt >= frames)
- {
- msg.header.type = PLINK_TYPE_MESSAGE;
- msg.header.size = DATA_SIZE(PlinkMsg);
- msg.msg = PLINK_EXIT_CODE;
- sendpkt.list[0] = &msg;
- sendpkt.num = 1;
- sendpkt.fd = PLINK_INVALID_FD;
- if (PLINK_send(plink_npu_sink, 0, &sendpkt) == PLINK_STATUS_ERROR)
- errExit("Failed to send data.");
- break;
- }
- #endif
- } while (exitcode == 0);
- retreiveSentBuffers(plink_npu_src, &channel[0]);
- cleanup:
- sleep(1); // Sleep one second to make sure server is ready for exit
- PLINK_close(plink_npu_sink, 0);
- if (fp != NULL)
- fclose(fp);
-
- for (i = 0; i < input_num; i++) {
- shl_mem_free(input_aligned[i]);
- }
- csinn_session_deinit(sess);
- csinn_free_session(sess);
- return 0;
- }
|