3 * Copyright (C) 2020 Samsung Electronics
4 * Copyright (C) 2020 Dongju Chae <dongju.chae@samsung.com>
7 * @file tvn_triv2_dmabuf.cc
9 * @brief AppTest to test dmabuf-sharing capability in TRIV2 device
10 * @author Dongju Chae <dongju.chae@samsung.com>
11 * @bug No known bugs except for NYI items
14 #include <libnpuhost.h>
15 #include <ne_test_utils.h>
21 /** ./include/typedef.h */
22 #define TRIV2_TYPE NPUCOND_TRIV2_CONN_SOCIP
24 #define NPU_MODEL_NAME "model.tvn"
26 /** @brief c++ class to describe how to use npu-engine library */
29 TesterTRIV2 () : dev_ (nullptr), dev_tmp_ (nullptr), meta_ (nullptr), model_id_ (0) {
30 memset (&input_, '\x00', sizeof (input_buffers));
31 memset (&input_tmp_, '\x00', sizeof (input_buffers));
35 /** release resources */
36 if (dev_ != nullptr) {
38 unregisterNPUmodel (dev_, model_id_);
46 if (dev_tmp_ != nullptr) {
47 for (uint32_t idx = 0; idx < input_tmp_.num_buffers; idx++) {
48 cleanNPU_inputBuffer (dev_tmp_, &input_tmp_.bufs[idx]);
51 putNPUdevice (dev_tmp_);
55 /** @brief initilize the device handle */
56 int init (const std::string dir) {
58 /* use /dev/triv2-0 */
59 return getNPUdeviceByType (&dev_, TRIV2_TYPE, 0);
62 /** @brief run the inference (with dummy data) */
64 int status = prepare_model ();
68 status = prepare_input ();
72 status = set_data_info ();
76 output_buffers output;
77 status = runNPU_sync (dev_, model_id_, &input_, &output);
81 return compare_result (output);
85 int prepare_model () {
87 std::string model_path;
90 model_path = dir_ + "/" + NPU_MODEL_NAME;
92 meta_ = getNPUmodel_metadata (model_path.c_str (), false);
96 if (NPUBIN_VERSION (meta_->magiccode) != 3)
99 for (i = 0; i < meta_->segment_num; ++i) {
100 if (meta_->input_seg_off[i] != 0)
101 return test_ret::test_ret_skipped_not_compatible;
104 model.type = BUFFER_FILE;
105 model.size = meta_->size;
106 model.filepath = model_path.c_str ();
108 int status = allocNPU_modelBuffer (dev_, &model);
112 status = registerNPUmodel (dev_, &model, &model_id_);
113 cleanNPU_modelBuffer (dev_, &model);
118 int prepare_input () {
119 /* use /dev/triv2-1 for external dmabuf */
120 int status = getNPUdeviceByType (&dev_tmp_, TRIV2_TYPE, 1);
124 input_.num_buffers = meta_->input_seg_num;
125 input_tmp_.num_buffers = meta_->input_seg_num;
126 for (uint32_t idx = 0; idx < meta_->input_seg_num; idx++) {
127 uint32_t input_seg_idx = meta_->input_seg_idx[idx];
128 uint32_t input_seg_size = meta_->segment_size[input_seg_idx];
129 off_t input_seg_off = meta_->input_seg_off[idx];
131 std::string input_path;
132 input_path = dir_ + "/input_fmap_" + std::to_string (idx) + ".bin";
134 input_tmp_.bufs[idx].type = BUFFER_MAPPED;
135 input_tmp_.bufs[idx].size = input_seg_size;
136 status = allocNPU_inputBuffer (dev_tmp_, &input_tmp_.bufs[idx]);
140 std::ifstream ifs (input_path, std::ios::binary);
144 ifs.seekg (0, std::ios::end);
145 size_t size = ifs.tellg ();
148 ifs.read (static_cast<char *> (input_tmp_.bufs[idx].addr) + input_seg_off, size);
151 input_.bufs[idx].type = BUFFER_DMABUF;
152 input_.bufs[idx].size = size;
153 input_.bufs[idx].dmabuf = input_tmp_.bufs[idx].dmabuf;
154 input_.bufs[idx].offset = input_seg_off;
160 int set_data_info () {
161 tensors_data_info info_in;
162 tensors_data_info info_out;
164 /* No data manipulation & quantization in this test */
166 info_in.num_info = meta_->input_seg_num;
167 for (uint32_t idx = 0; idx < info_in.num_info; idx++) {
168 info_in.info[idx].layout = DATA_LAYOUT_TRIV2;
169 info_in.info[idx].type = DATA_TYPE_QASYMM8;
172 info_out.num_info = meta_->output_seg_num;
173 for (uint32_t idx = 0; idx < info_out.num_info; idx++) {
174 info_out.info[idx].layout = DATA_LAYOUT_TRIV2;
175 info_out.info[idx].type = DATA_TYPE_QASYMM8;
178 return setNPU_dataInfo (dev_, model_id_, &info_in, &info_out);
181 int compare_result (output_buffers &output) {
184 for (uint32_t idx = 0; idx < output.num_buffers; idx++) {
185 char *output_data = static_cast<char *> (output.bufs[idx].addr);
186 off_t output_size = output.bufs[idx].size;
187 std::string golden_path;
189 golden_path = dir_ + "/output_fmap_" + std::to_string (idx) + ".bin";
191 err = compare_data (golden_path.c_str (), output_data, output_size);
193 assert (output.bufs[idx].type == BUFFER_MAPPED);
210 input_buffers input_;
211 input_buffers input_tmp_;
214 /** @brief apptest main */
216 main (int argc, char **argv) {
221 status = test_ret::test_ret_skipped_wrong_num_args;
225 /** initialize triv2 device */
226 status = tester.init (argv[1]);
227 if (status < test_ret::test_ret_success)
230 /** run the inference with the device */
231 status = tester.run ();
232 if (status < test_ret::test_ret_success)
234 else if (status > test_ret::test_ret_skipped)
237 std::cerr << "[APPTEST] " << argv[0] << ": PASSED\n";
241 std::cerr << "[APPTEST] " << argv[0] << ": FAILED (" << status << ")\n";
245 std::cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n";
246 std::cerr << "\t" << msg_skipped_reason[status] << std::endl;