+++ /dev/null
-/**
- * Proprietary
- * Copyright (C) 2020 Samsung Electronics
- * Copyright (C) 2020 Dongju Chae <dongju.chae@samsung.com>
- * Copyright (C) 2020 Wook Song <wook16.song@samsung.com>
-*/
-/**
- * @file tvn_triv2_bulk_gem.c
- * @date 05 Aug 2020
- * @brief AppTest to test example visa binaries with GEM (triv2/npubinfmt v3)
- * @author Dongju Chae <dongju.chae@samsung.com>
- * @author Wook Song <wook16.song@samsung.com>
- * @bug No known bugs except for NYI items
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <xf86drm.h>
-#include <unistd.h>
-
-#include <libnpuhost.h>
-#include <npubinfmt.h>
-#include <ne_test_utils.h>
-
-#define MAX_FILE_LEN 256
-#define NPU_MODEL_NAME "model.tvn"
-
-#ifndef DRM_RDWR
-#define DRM_RDWR O_RDWR
-#endif
-
-static int enable_output_dump = 1;
-
-/** @brief compare output buffers */
-static int
-compare_output_buffers (const npubin_meta *meta, const char *base_path,
- const char *target, output_buffers *output)
-{
- char golden_path[MAX_FILE_LEN];
- char *output_data;
- off_t output_size;
- int err = 0;
- uint32_t idx;
-
- for (idx = 0; idx < output->num_buffers; idx++) {
- output_data = output->bufs[idx].addr;
- output_size = output->bufs[idx].size;
-
- snprintf (golden_path, MAX_FILE_LEN, "%s/%s/output_fmap_%d.bin",
- base_path, target, idx);
-
- err = compare_data (golden_path, output_data, output_size);
-
- if (enable_output_dump == 1) {
- char output_path[MAX_FILE_LEN];
- FILE *f;
-
- snprintf (output_path, MAX_FILE_LEN, "%s/%s/obtained_fmap_%d.bin",
- base_path, target, idx);
- f = fopen (output_path, "wb");
- if (f != NULL) {
- fwrite (output_data, output_size, 1, f);
- fclose (f);
- }
- }
-
- assert (output->bufs[idx].type == BUFFER_MAPPED);
- free (output->bufs[idx].addr);
-
- if (err != 0)
- break;
- }
-
- return err;
-}
-
-/** @brief run inference for each target visa binary (on sync mode) */
-static int
-run_inference_each (npudev_h dev, const char *base_path, const char *target)
-{
- /** @todo Need a mechanism that automatically find the node of cgem */
- /** DRM-related variables */
- const char cgem_dev_node[] = "/dev/card0";
- struct drm_prime_handle *arg_handle;
- int drm_fd;
-
- generic_buffer model;
- input_buffers input;
- output_buffers output;
-
- char model_path[MAX_FILE_LEN];
- char input_path[MAX_TENSORS][MAX_FILE_LEN];
- off_t input_size;
-
- npuConstraint constraint;
- npubin_meta *meta;
- uint32_t model_id;
- uint32_t idx;
- int err = 0;
- int ret;
- int i;
-
- /** 1: setup model (not dmabuf) */
- memset (model_path, '\x00', MAX_FILE_LEN);
- snprintf (model_path, MAX_FILE_LEN, "%s/%s/%s",
- base_path, target, NPU_MODEL_NAME);
-
- meta = getNPUmodel_metadata (model_path, false);
- if (meta == NULL) {
- fprintf (stderr, "Fail to get the metadata of %s\n", model_path);
- return -EINVAL;
- }
-
- drm_fd = open (cgem_dev_node, O_RDWR);
- if (drm_fd < 0) {
- err = drm_fd;
- goto out_free_meta;
- }
-
- model.size = get_file_size (model_path);
- model.filepath = model_path;
- model.type = BUFFER_FILE;
-
- /** 2: setup input buffers */
- if (NPUBIN_VERSION (meta->magiccode) != 3) {
- fprintf (stderr, "Support only npubinfmt v3\n");
- err = -EINVAL;
- goto out_close_drmfd;
- }
-
- for (i = 0; i < meta->segment_num; ++i) {
- if (meta->input_seg_off[i] != 0) {
- err = test_ret_skipped_not_compatible;
- goto out_close_drmfd;
- }
- }
-
- if (meta->input_seg_num > MAX_TENSORS ||
- meta->output_seg_num > MAX_TENSORS) {
- fprintf (stderr, "Invalid metadata detected\n");
- err = -EINVAL;
- goto out_close_drmfd;
- }
-
- arg_handle = calloc (meta->input_seg_num, sizeof(*arg_handle));
- for (idx = 0; idx < meta->input_seg_num; idx++) {
- struct drm_mode_create_dumb arg_create;
- void *mapped;
- size_t n_read;
- FILE *f;
-
- memset (input_path[idx], '\x00', MAX_FILE_LEN);
- snprintf (input_path[idx], MAX_FILE_LEN, "%s/%s/input_fmap_%d.bin",
- base_path, target, idx);
- f = fopen (input_path[idx], "rb");
- if (f == NULL) {
- err = -errno;
- goto out_free_handle;
- }
-
- input_size = get_file_size (input_path[idx]);
- if (input_size <= 0) {
- fprintf (stderr, "Wrong metadata; need %d input tensors\n",
- meta->input_seg_num);
- err = -EINVAL;
- fclose (f);
- goto out_free_handle;
- }
-
- arg_create.width = input_size;
- arg_create.height = 1;
- arg_create.bpp = 8;
- arg_create.flags = 0;
-
- err = drmIoctl (drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg_create);
- if (err) {
- fclose (f);
- goto out_free_handle;
- }
-
- arg_handle[idx].handle = arg_create.handle;
- arg_handle[idx].flags = DRM_CLOEXEC | DRM_RDWR;
- arg_handle[idx].fd = -1;
- err = drmIoctl (drm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg_handle[idx]);
- if (err) {
- fclose (f);
- goto out_destroy_drm_dumb;
- }
-
- mapped = mmap (NULL, input_size, PROT_READ | PROT_WRITE, MAP_SHARED,
- arg_handle[idx].fd, 0);
- if (mapped == MAP_FAILED) {
- err = errno;
- fclose (f);
- goto out_destroy_drm_dumb;
- }
-
- n_read = fread (mapped, 1, input_size, f);
- if (n_read != input_size)
- err = ferror (f);
-
- munmap (mapped, input_size);
- fclose(f);
-
- if (err)
- goto out_destroy_drm_dumb;
-
- input.bufs[idx].size = input_size;
- input.bufs[idx].type = BUFFER_DMABUF;
- input.bufs[idx].dmabuf = arg_handle[idx].fd;
- input.bufs[idx].offset = 0;
- }
-
- input.num_buffers = meta->input_seg_num;
- /** 3: register the model to NPU Engine */
- if ((err = registerNPUmodel (dev, &model, &model_id)) != 0) {
- fprintf (stderr, "Fail to registerNPU model (errno %d)\n", err);
- goto out_destroy_drm_dumb;
- }
-
- /** 4-1: provide additional information to NPU Engine */
- {
- tensors_data_info info_in;
- tensors_data_info info_out;
-
- /* No data manipulation & quantization in this test */
- info_in.num_info = meta->input_seg_num;
- for (idx = 0; idx < info_in.num_info; idx++) {
- info_in.info[idx].layout = DATA_LAYOUT_TRIV2;
- info_in.info[idx].type = DATA_TYPE_QASYMM8;
- }
-
- info_out.num_info = meta->output_seg_num;
- for (idx = 0; idx < info_out.num_info; idx++) {
- info_out.info[idx].layout = DATA_LAYOUT_TRIV2;
- info_out.info[idx].type = DATA_TYPE_QASYMM8;
- }
-
- if ((err = setNPU_dataInfo (dev, model_id, &info_in, &info_out)) != 0) {
- fprintf (stderr, "Failed to set the information for NPU data\n");
- goto out_unregister;
- }
- }
-
- /** 4-2: set constraints */
- constraint.timeout_ms = 100;
- constraint.priority = NPU_PRIORITY_MID;
- if ((err = setNPU_constraint (dev, model_id, constraint)) != 0)
- goto out_unregister;
-
- /** 5: run NPU inference (sync) */
- if ((err = runNPU_sync (dev, model_id, &input, &output)) != 0)
- goto out_unregister;
-
- /** 6: compare output buffers */
- err = compare_output_buffers (meta, base_path, target, &output);
-
-out_unregister:
- unregisterNPUmodel (dev, model_id);
-out_destroy_drm_dumb:
- for (idx = 0; idx < meta->input_seg_num; ++idx) {
- struct drm_mode_destroy_dumb dreq;
-
- if (arg_handle[idx].handle == 0)
- continue;
-
- memset(&dreq, 0, sizeof(dreq));
-
- dreq.handle = arg_handle[idx].handle;
- ret = drmIoctl (drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
- if (ret)
- fprintf (stderr, "Failed to destory the handle of CGEM_DUMB: %u\n",
- dreq.handle);
- }
-out_free_handle:
- free (arg_handle);
-out_close_drmfd:
- close (drm_fd);
-out_free_meta:
- free (meta);
-
- /** ensure that all memory (allocated by libnpuhost APIs) are successfully freed */
- if (err == 0)
- check_memory_leak (dev);
-
- return err;
-}
-
-/** @brief apptest main */
-int
-main (int argc, char **argv)
-{
- int ret = 0;
- dev_type type = NPUCOND_TRIV2_CONN_SOCIP;
- npudev_h dev;
-
- if (argc < 2) {
- ret = test_ret_skipped_wrong_num_args;
- goto skipped;
- }
-
- if (argc == 3)
- enable_output_dump = atoi(argv[2]);
-
- if (getNPUdeviceByTypeAny (&dev, type, default_tops) != 0) {
- fprintf(stderr, "No available TRIV2 device\n");
- return -1;
- }
-
- return run_apptest (dev, argv, &run_inference_each);
-
-skipped:
- fprintf(stderr, "[APPTEST] %s: SKIPPED\n", argv[0]);
- fprintf(stderr, "\t%s\n", msg_skipped_reason[ret]);
-
- return 0;
-}
}
/**
- * @brief check impl methods, HWmemExternal with cgem
- */
-TEST (ne_core_hwmem_test, hwmem_external_cgem)
-{
- /** @todo Need a mechanism that automatically find the node of cgem */
- const char cgem_dev_node[] = "/dev/card0";
- const size_t size = 0x1000;
- HWmem *external = new HWmem (new HWmemExternal);
- struct drm_mode_create_dumb arg_create;
- struct drm_prime_handle arg_handle;
- int ret = 0;
- int fd;
-
- if (is_enabled_emulation) {
- delete external;
- return;
- }
-
- INIT_TEST_DRIVER_API();
-
- fd = open (cgem_dev_node, O_RDWR);
- ASSERT_GE (fd, 0);
-
- arg_create.width = size;
- arg_create.height = 1;
- arg_create.bpp = 8;
- arg_create.flags = 0;
-
- ret = drmIoctl (fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg_create);
- if (ret) {
- EXPECT_EQ (ret, 0);
- goto clean_up;
- }
-
- arg_handle.handle = arg_create.handle;
- arg_handle.flags = DRM_CLOEXEC | DRM_RDWR;
- arg_handle.fd = -1;
- ret = drmIoctl (fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg_handle);
- if (ret) {
- EXPECT_EQ (ret, 0);
- goto clean_up;
- }
-
- external->setDriverAPI(api.get());
- external->setDmabuf (arg_handle.fd);
- external->setSize (size);
- external->setOffset (0);
-
- EXPECT_NE (external->getData (), nullptr);
-
-clean_up:
- delete external;
- close (fd);
-}
-
-/**
- * @brief a negative test case of HWmemExternal impl methods with cgem
- */
-TEST (ne_core_hwmem_test, hwmem_external_cgem_n)
-{
- /** @todo Need a mechanism that automatically find the node of cgem */
- const char cgem_dev_node[] = "/dev/card0";
- const size_t size = 0x1000;
- HWmem *external = new HWmem (new HWmemExternal);
- struct drm_mode_create_dumb arg_create;
- struct drm_prime_handle arg_handle;
- int ret = 0;
- int fd;
-
- if (is_enabled_emulation) {
- delete external;
- return;
- }
-
- INIT_TEST_DRIVER_API();
-
- fd = open (cgem_dev_node, O_RDWR);
- ASSERT_GE (fd, 0);
-
- arg_create.width = size;
- arg_create.height = 1;
- arg_create.bpp = 8;
- arg_create.flags = 0;
-
- ret = drmIoctl (fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg_create);
- if (ret) {
- EXPECT_EQ (ret, 0);
- goto clean_up;
- }
-
- arg_handle.handle = arg_create.handle;
- arg_handle.flags = DRM_CLOEXEC | DRM_RDWR;
- arg_handle.fd = -1;
-
- external->setDriverAPI(api.get());
- external->setDmabuf (arg_handle.fd);
- external->setSize (size);
- external->setOffset (0);
-
- /** dmabuf_fd is -1 */
- EXPECT_EQ (external->getData (), nullptr);
-
-clean_up:
- delete external;
- close (fd);
-}
-
-
-/**
* @brief main function for unit test
*/
int