TIOVX User Guide
vx_tutorial_tidl.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2019 Texas Instruments Incorporated
4  *
5  * All rights reserved not granted herein.
6  *
7  * Limited License.
8  *
9  * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
10  * license under copyrights and patents it now or hereafter owns or controls to make,
11  * have made, use, import, offer to sell and sell ("Utilize") this software subject to the
12  * terms herein. With respect to the foregoing patent license, such license is granted
13  * solely to the extent that any such patent is necessary to Utilize the software alone.
14  * The patent license shall not apply to any combinations which include this software,
15  * other than combinations with devices manufactured by or for TI ("TI Devices").
16  * No hardware patent is licensed hereunder.
17  *
18  * Redistributions must preserve existing copyright notices and reproduce this license
19  * (including the above copyright notice and the disclaimer and (if applicable) source
20  * code license limitations below) in the documentation and/or other materials provided
21  * with the distribution
22  *
23  * Redistribution and use in binary form, without modification, are permitted provided
24  * that the following conditions are met:
25  *
26  * * No reverse engineering, decompilation, or disassembly of this software is
27  * permitted with respect to any software provided in binary form.
28  *
29  * * any redistribution and use are licensed by TI for use only with TI Devices.
30  *
31  * * Nothing shall obligate TI to provide you with source code for the software
32  * licensed and provided to you in object code.
33  *
34  * If software source code is provided to you, modification and redistribution of the
35  * source code are permitted provided that the following conditions are met:
36  *
37  * * any redistribution and use of the source code, including any resulting derivative
38  * works, are licensed by TI for use only with TI Devices.
39  *
40  * * any redistribution and use of any object code compiled from the source code
41  * and any resulting derivative works, are licensed by TI for use only with TI Devices.
42  *
43  * Neither the name of Texas Instruments Incorporated nor the names of its suppliers
44  *
45  * may be used to endorse or promote products derived from this software without
46  * specific prior written permission.
47  *
48  * DISCLAIMER.
49  *
50  * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS
51  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
53  * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
55  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
56  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
57  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
58  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59  * OF THE POSSIBILITY OF SUCH DAMAGE.
60  *
61  */
62 
63 
64 
109 #include <TI/tivx.h>
110 #include <tivx_utils_file_rd_wr.h>
111 
112 #include <stdio.h>
113 #include <stdint.h>
114 #include <stdlib.h>
115 #include <assert.h>
116 #include <float.h>
117 #include <math.h>
118 
119 #include "../../../common/xdais_types.h" /* In TIDL_PATH directory */
120 #include "sTIDL_IOBufDesc.h"
121 #include "tivx_tidl_utils.h"
122 
123 #include "itidl_ti.h"
124 #include "vx_tutorial_tidl.h"
125 #include "test_engine/test_utils.h"
126 
127 #define MAX(_a,_b) (((_a) > (_b)) ? (_a) : (_b))
128 
129 #define CFG_FILE_NAME "tivx/tidl/tidl_infer.cfg"
130 
131 #define NUM_EVE_CPU (obj->num_eve_cores)
132 #define NUM_DSP_CPU 2
133 #define MAX_NUM_THREADS 4
134 
135 typedef struct {
136  char tidl_params_file_path[VX_TUTORIAL_MAX_FILE_PATH];
137  char tidl_network_file_path[VX_TUTORIAL_MAX_FILE_PATH];
138  char input_file_path[VX_TUTORIAL_MAX_FILE_PATH];
139  char output_file_path[VX_TUTORIAL_MAX_FILE_PATH];
140  uint32_t operation_mode;
141  uint32_t processing_core_mode;
142  uint32_t num_eve_cores;
143 } VxTutorialTidl_CfgObj;
144 
145 VxTutorialTidl_CfgObj gCfgObj;
146 
147 static vx_status parse_cfg_file(VxTutorialTidl_CfgObj *obj, char *cfg_file_name);
148 static vx_status createInputTensors(vx_context context, vx_user_data_object config, vx_tensor *input_tensors);
149 static vx_status createOutputTensor(vx_context context, vx_user_data_object config, vx_tensor *output_tensors);
150 static vx_status readInput(vx_context context, vx_user_data_object config, vx_tensor *input_tensors, char *input_file, uint32_t operation_mode);
151 static void displayOutput(void *bmp_context, vx_df_image df_image, void *data_ptr, vx_uint32 img_width, vx_uint32 img_height, vx_uint32 img_stride, vx_user_data_object config, vx_tensor *output_tensors, char *output_file, uint32_t operation_mode);
152 
153 #ifdef HOST_EMULATION
154 /* This is a workaround to support spanning graphs on different EVE and DSP cores in PC host emulation environment
155  * Plan to remove this workaround in the future ...
156  *
157  * */
158 tivx_cpu_id_e gTidlNodeCpuId[2*MAX_NUM_THREADS];
159 #endif
160 
161 void vx_tutorial_tidl()
162 {
163 
164  vx_context context;
165  vx_user_data_object config1, config2, realConfig;
166  vx_user_data_object network;
167  vx_user_data_object createParams1[MAX_NUM_THREADS];
168  vx_user_data_object inArgs1[MAX_NUM_THREADS];
169  vx_user_data_object outArgs1[MAX_NUM_THREADS];
170  vx_user_data_object createParams2[MAX_NUM_THREADS];
171  vx_user_data_object inArgs2[MAX_NUM_THREADS];
172  vx_user_data_object outArgs2[MAX_NUM_THREADS];
173  vx_reference params[5];
174  vx_tensor input_tensors[MAX_NUM_THREADS][VX_TUTORIAL_MAX_TENSORS];
175  vx_tensor output_tensors1[MAX_NUM_THREADS][VX_TUTORIAL_MAX_TENSORS];
176  vx_tensor output_tensors2[MAX_NUM_THREADS][VX_TUTORIAL_MAX_TENSORS];
177  vx_tensor *real_output_tensors;
178  vx_perf_t perf_graph, perf_node1, perf_node2;
179  int32_t i, threadIdx;
180  int32_t quantHistoryBoot, quantHistory, quantMargin;
181  uint64_t exe_time=0;
182 
183  size_t sizeFilePath;
184  char filePath[MAXPATHLENGTH];
185  const char *targetCore1[MAX_NUM_THREADS];
186  const char *targetCore2[MAX_NUM_THREADS];
187  vx_enum targetCpuId1[MAX_NUM_THREADS];
188  vx_enum targetCpuId2[MAX_NUM_THREADS];
189 
190  vx_status status = (vx_status)VX_SUCCESS;
191 
192  VxTutorialTidl_CfgObj *obj = &gCfgObj;
193 
194  vx_graph graph[MAX_NUM_THREADS] = {0};
195  vx_node node1[MAX_NUM_THREADS] = {0};
196  vx_node node2[MAX_NUM_THREADS] = {0};
197  vx_kernel kernel1 = 0;
198  vx_kernel kernel2 = 0;
199 
200  uint32_t num_input_tensors = 0;
201  uint32_t num_output_tensors1 = 0;
202  uint32_t num_output_tensors2 = 0;
203 
204  uint32_t maxNumThreads= 1;
205 
206  printf(" vx_tutorial_tidl: Tutorial Started !!! \n");
207 
208  context = vxCreateContext();
209  VX_TUTORIAL_ASSERT_VALID_REF(context);
210 
212 
213  sizeFilePath = snprintf(filePath, MAXPATHLENGTH, "%s/%s", ct_get_test_file_path(), CFG_FILE_NAME);
214 
215  if (sizeFilePath > MAXPATHLENGTH) {
216  printf("Error: path of config gile too long to fit in string\n");
217  goto exit;
218  }
219 
220  printf(" Reading config file %s ...\n", filePath);
221 
222  status= parse_cfg_file(obj, filePath);
223  if (status!=(vx_status)VX_SUCCESS) {
224  goto exit;
225  }
226 
227 
228  printf(" Reading network file %s ...\n", obj->tidl_network_file_path);
229 
230  network = vx_tidl_utils_readNetwork(context, &obj->tidl_network_file_path[0]);
231  VX_TUTORIAL_ASSERT_VALID_REF(network)
232 
233  /*
234  * Processing_core_mode: Specify how the network will be processed if multiple processing cores exist in the system.
235  * 0 (default): all cores can be utilized according to each layer's groupID. If a layer's group ID is 1 then it will run on EVE1. If it is 2, it will run on DSP1.
236  * 1: The entire network will run on EVE1, even the layers which have group ID 2 (DSP layers).
237  * 2: The entire network will run on DSP1, even the layers which have group ID 1 (EVE layers).
238  *
239  */
240 #ifdef HOST_EMULATION
241  /* In host emulation on PC, it is not possible to test for processing_core_mode=2
242  * but we can test test processing_core_mode=1, which gives a high confidence that
243  * processing_core_mode=2 works as well.
244  * For a definitive testing of processing_core_mode=2, test on target.
245  */
246  if (obj->processing_core_mode== 2) {
247  obj->processing_core_mode= 1;
248  }
249 #endif
250 
251  if (obj->processing_core_mode== 0){
252 
253  /*
254  * In case the network has only one group of layer, assign the first core and disable the second core
255  * In case there are 2 groups of layers. 1st group is always assigned to EVE and second group always assigned to DSP
256  * */
257  int32_t layersGroupCount[(vx_enum)TIVX_CPU_ID_MAX];
258  int32_t numLayersGroup= vx_tidl_utils_countLayersGroup(network, layersGroupCount);
259 
260  if (numLayersGroup== 1) {
261  if (layersGroupCount[1]!=0) {
262  /* If the entire network runs on EVE, spun the processing into as many threads as there are EVEs to demonstrate parallelism between EVEs */
263  maxNumThreads= NUM_EVE_CPU;
264  targetCore1[0]= TIVX_TARGET_EVE1;targetCore1[1]= TIVX_TARGET_EVE2;targetCore1[2]= TIVX_TARGET_EVE3;targetCore1[3]= TIVX_TARGET_EVE4;
265  targetCpuId1[0]= (vx_enum)TIVX_CPU_ID_EVE1;targetCpuId1[1]= (vx_enum)TIVX_CPU_ID_EVE2;targetCpuId1[2]= (vx_enum)TIVX_CPU_ID_EVE3;targetCpuId1[3]= (vx_enum)TIVX_CPU_ID_EVE4;
266  }
267  else if (layersGroupCount[2]!=0) {
268  /* If the entire network runs on DSP, spun the processing into as many threads as there are DSPs to demonstrate parallelism between DSPs */
269  maxNumThreads= NUM_DSP_CPU;
270  targetCore1[0]= TIVX_TARGET_DSP1;targetCore1[1]= TIVX_TARGET_DSP2;
271  targetCpuId1[0]= (vx_enum)TIVX_CPU_ID_DSP1;targetCpuId1[1]= (vx_enum)TIVX_CPU_ID_DSP2;
272  }
273  else {
274  printf(" Invalid layer group ID detected, exiting ...\n");
275  goto exit;
276  }
277  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
278  targetCore2[threadIdx]= NULL;
279  targetCpuId2[threadIdx]= (vx_enum)TIVX_CPU_ID_INVALID;
280  }
281  }/* In case the network has 2 groups, it will run on two cores */
282  else if (numLayersGroup== 2) {
283  maxNumThreads= NUM_EVE_CPU;
284  targetCore1[0]= TIVX_TARGET_EVE1;targetCore1[1]= TIVX_TARGET_EVE2;targetCore1[2]= TIVX_TARGET_EVE3;targetCore1[3]= TIVX_TARGET_EVE4;
285  targetCpuId1[0]= (vx_enum)TIVX_CPU_ID_EVE1;targetCpuId1[1]= (vx_enum)TIVX_CPU_ID_EVE2;targetCpuId1[2]= (vx_enum)TIVX_CPU_ID_EVE3;targetCpuId1[3]= (vx_enum)TIVX_CPU_ID_EVE4;
286  targetCore2[0]= TIVX_TARGET_DSP1;targetCore2[1]= TIVX_TARGET_DSP1;targetCore2[2]= TIVX_TARGET_DSP1;targetCore2[3]= TIVX_TARGET_DSP1;
287  targetCpuId2[0]= (vx_enum)TIVX_CPU_ID_DSP1;targetCpuId2[1]= (vx_enum)TIVX_CPU_ID_DSP1;targetCpuId2[2]= (vx_enum)TIVX_CPU_ID_DSP1;targetCpuId2[3]= (vx_enum)TIVX_CPU_ID_DSP1;
288  }
289  else {
290  printf(" Invalid number of groups of layers, exiting ...\n");
291  goto exit;
292  }
293 
294  }
295  else if (obj->processing_core_mode== 1) {
296  maxNumThreads= NUM_EVE_CPU;
297  targetCore1[0]= TIVX_TARGET_EVE1;targetCore1[1]= TIVX_TARGET_EVE2;targetCore1[2]= TIVX_TARGET_EVE3;targetCore1[3]= TIVX_TARGET_EVE4;
298  targetCpuId1[0]= (vx_enum)TIVX_CPU_ID_EVE1;targetCpuId1[1]= (vx_enum)TIVX_CPU_ID_EVE2;targetCpuId1[2]= (vx_enum)TIVX_CPU_ID_EVE3;targetCpuId1[3]= (vx_enum)TIVX_CPU_ID_EVE4;
299  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
300  targetCore2[threadIdx]= NULL;
301  targetCpuId2[threadIdx]= (vx_enum)TIVX_CPU_ID_INVALID;
302  }
303  }
304  else if (obj->processing_core_mode== 2) {
305  maxNumThreads= NUM_DSP_CPU;
306  targetCore1[0]= TIVX_TARGET_DSP1;targetCore1[1]= TIVX_TARGET_DSP2;
307  targetCpuId1[0]= (vx_enum)TIVX_CPU_ID_DSP1;targetCpuId1[1]= (vx_enum)TIVX_CPU_ID_DSP2;
308  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
309  targetCore2[threadIdx]= NULL;
310  targetCpuId2[threadIdx]= (vx_enum)TIVX_CPU_ID_INVALID;
311  }
312  }
313  else {
314  printf("Invalid processing core mode, exiting ...\n");
315  goto exit;
316  }
317 
318  /* If processing_core_mode is not 0, update each layer's group ID so that the entire network runs either on EVE or DSP*/
319  if (obj->processing_core_mode!= 0) {
320  vx_tidl_utils_updateLayersGroup(network, targetCpuId1[0]);
321  }
322 
323  config1 = vx_tidl_utils_getConfig(context, network, &num_input_tensors, &num_output_tensors1, targetCpuId1[0]);
324 
325  /* In case the network runs on one CPU, set num_output_tensors2 to 0 */
326  if (targetCpuId2[0]== (vx_enum)TIVX_CPU_ID_INVALID) {
327  num_output_tensors2= 0;
328  config2= 0;
329  }
330  else {
331  int32_t num_interm_tensors= num_output_tensors1;
332 
333  config2 = vx_tidl_utils_getConfig(context, network, &num_output_tensors1, &num_output_tensors2, targetCpuId2[0]);
334 
335  if (num_interm_tensors != num_output_tensors1) {
336  printf("Number of output tensors from first group of layers not equal to the number of input tensors from second group of layers. Exiting ...\n");
337  goto exit;
338  }
339  }
340 
341  printf(" Reading network params file %s ...\n", obj->tidl_params_file_path);
342 
343  status= vx_tidl_utils_readParams(network, &obj->tidl_params_file_path[0]);
344  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
345 
346  kernel1 = tivxAddKernelTIDL(context, num_input_tensors, num_output_tensors1);
347  VX_TUTORIAL_ASSERT_VALID_REF(kernel1)
348 
349  if (targetCpuId2[0]!= (vx_enum)TIVX_CPU_ID_INVALID) {
350  kernel2 = tivxAddKernelTIDL(context, num_output_tensors1, num_output_tensors2);
351  VX_TUTORIAL_ASSERT_VALID_REF(kernel2)
352  }
353 
354 
355  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
356 
357  printf("\nThread #%d: Create graph ... \n", threadIdx+1);
358 
359  /* Create OpenVx Graph */
360  graph[threadIdx] = vxCreateGraph(context);
361  VX_TUTORIAL_ASSERT_VALID_REF(graph[threadIdx])
362 
363  printf("Thread #%d: Create input and output tensors for node 1 ... \n", threadIdx+1);
364  /* Create array of input tensors for the first node */
365 
366  status= createInputTensors(context, config1, &input_tensors[threadIdx][0]);
367  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
368 
369  /* Create array of output tensors for the first node, which is also the input tensors for the second node */
370  status= createOutputTensor(context, config1, &output_tensors1[threadIdx][0]);
371  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
372 
373  /*
374  * TIDL maintains range statistics for previously processed frames. It quantizes the current inference activations using range statistics from history for processes (weighted average range).
375  * Below is the parameters controls quantization.
376  * quantMargin is margin added to the average in percentage.
377  * quantHistoryBoot weights used for previously processed inference during application boot time for initial few frames
378  * quantHistory weights used for previously processed inference during application execution (After initial few frames)
379  *
380  * Below settings are adequate for running on videos sequences.
381  * For still images, set all settings to 0.
382  */
383  quantHistoryBoot= 20;
384  quantHistory= 5;
385  quantMargin= 0;
386 
387  printf("Thread #%d: Create node 1 ... \n", threadIdx+1);
388 
389  createParams1[threadIdx]= vx_tidl_utils_setCreateParams(context, quantHistoryBoot, quantHistory, quantMargin);
390  inArgs1[threadIdx]= vx_tidl_utils_setInArgs(context);
391  outArgs1[threadIdx]= vx_tidl_utils_setOutArgs(context);
392 
393  params[0]= (vx_reference)config1;
394  params[1]= (vx_reference)network;
395  params[2]= (vx_reference)createParams1[threadIdx];
396  params[3]= (vx_reference)inArgs1[threadIdx];
397  params[4]= (vx_reference)outArgs1[threadIdx];
398 
399  node1[threadIdx] = tivxTIDLNode(graph[threadIdx], kernel1,
400  params,
401  &input_tensors[threadIdx][0],
402  &output_tensors1[threadIdx][0]
403  );
404  VX_TUTORIAL_ASSERT_VALID_REF(node1[threadIdx])
405 
406  /* Set target node to targetCore1 (EVEn or DSP1)*/
407  vxSetNodeTarget(node1[threadIdx], (vx_enum)VX_TARGET_STRING, targetCore1[threadIdx]);
408 #ifdef HOST_EMULATION
409  /* This is a workaround to support spanning graphs on different EVE and DSP cores in PC host emulation environment
410  * */
411  gTidlNodeCpuId[2*threadIdx]= targetCpuId1[threadIdx];
412 #endif
413 
414  if ((targetCpuId2[threadIdx]== (vx_enum)TIVX_CPU_ID_DSP1) || (targetCpuId2[threadIdx]== (vx_enum)TIVX_CPU_ID_DSP2)) {
415  printf("Thread #%d: Create output tensors for node 2 ... \n", threadIdx+1);
416 
417  /* Create array of output tensors for the second node */
418  status= createOutputTensor(context, config2, &output_tensors2[threadIdx][0]);
419  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
420 
421  printf("Thread #%d: Create node 2 ... \n", threadIdx+1);
422 
423  createParams2[threadIdx]= vx_tidl_utils_setCreateParams(context, quantHistoryBoot, quantHistory, quantMargin);
424  inArgs2[threadIdx]= vx_tidl_utils_setInArgs(context);
425  outArgs2[threadIdx]= vx_tidl_utils_setOutArgs(context);
426 
427  params[0]= (vx_reference)config2;
428  params[1]= (vx_reference)network;
429  params[2]= (vx_reference)createParams2[threadIdx];
430  params[3]= (vx_reference)inArgs2[threadIdx];
431  params[4]= (vx_reference)outArgs2[threadIdx];
432 
433  node2[threadIdx] = tivxTIDLNode(graph[threadIdx], kernel2,
434  params,
435  &output_tensors1[threadIdx][0],
436  &output_tensors2[threadIdx][0]
437  );
438  VX_TUTORIAL_ASSERT_VALID_REF(node2[threadIdx])
439 
440  /* Set target node to targetCore2 (EVEn or DSP1)*/
441  vxSetNodeTarget(node2[threadIdx], (vx_enum)VX_TARGET_STRING, targetCore2[threadIdx]);
442 #ifdef HOST_EMULATION
443  /* This is a workaround to support spanning graphs on different EVE and DSP cores in PC host emulation environment
444  * */
445  gTidlNodeCpuId[2*threadIdx+1]= targetCpuId2[threadIdx];
446 #endif
447 
448  }
449  }
450 
451  printf("\n");
452 
453  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
454  printf("Thread #%d: Verify graph ... \n", threadIdx+1);
455  /* Verify the TIDL Graph
456  * When executed in host emulation on PC, the version of TI-DL library linked displays information about each layer of the network.
457  * In target execution, such display is disabled in the library.
458  * */
459  status = vxVerifyGraph(graph[threadIdx]);
460  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
461  }
462 
463  if((vx_status)VX_SUCCESS == status) {
464 
465  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
466 
467  /* Read input from file and populate the input tensor #0, we assume here that only one input tensor is used */
468  status= readInput(context, config1, &input_tensors[threadIdx][0], &obj->input_file_path[0], obj->operation_mode);
469  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
470 
471  if (status!=(vx_status)VX_SUCCESS) {
472  goto exit;
473  }
474 
475  }
476 
477  exe_time= tivxPlatformGetTimeInUsecs();
478 
479  printf("\n");
480 
481 #ifdef SEQUENTIAL_SCHEDULE
482  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
483  printf("Thread #%d: Execute graph ... \n",threadIdx + 1);
484  /* Execute the network */
485  status = vxProcessGraph(graph[threadIdx]);
486  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
487  }
488 #else
489  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
490  printf("Thread #%d: Start graph ... \n",threadIdx + 1);
491  /* Execute the network */
492  status = vxScheduleGraph(graph[threadIdx]);
493  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
494  }
495 
496  /* You can do other useful things here, while the graphs execute asynchronously using resources available on other cores */
497  printf("\n");
498 
499  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
500  printf("Thread #%d: Wait for graph ... \n",threadIdx + 1);
501  /* Execute the network */
502  status = vxWaitGraph(graph[threadIdx]);
503  VX_TUTORIAL_ASSERT(status==(vx_status)VX_SUCCESS);
504  }
505 #endif
506 
507  exe_time= tivxPlatformGetTimeInUsecs() - exe_time;
508 
509  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
510 
511  printf("\nThread #%d: Results\n", threadIdx+1);
512  printf("---------------------\n");
513 
514  /* Display the output_tensors1 if graph runs 1 cores */
515  if (targetCpuId2[threadIdx]== (vx_enum)TIVX_CPU_ID_INVALID) {
516  real_output_tensors= &output_tensors1[threadIdx][0];
517  realConfig= config1;
518  }
519  else { /* Display the output_tensors2 if graph runs 2 cores */
520  real_output_tensors= &output_tensors2[threadIdx][0];
521  realConfig= config2;
522  }
523 
524  displayOutput(NULL, (vx_df_image)NULL, NULL, 0, 0, 0, realConfig, real_output_tensors, &obj->output_file_path[0], obj->operation_mode);
525 
526  }
527  }
528 
529  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
530  vxQueryNode(node1[threadIdx], (vx_enum)VX_NODE_PERFORMANCE, &perf_node1, sizeof(perf_node1));
531  printf("\n---- Thread #%d: Node 1 (%s) Execution time: %4.6f ms\n", threadIdx+1, targetCore1[threadIdx], perf_node1.min/1000000.0);
532 
533  if(node2[threadIdx] != 0) {
534  vxQueryNode(node2[threadIdx], (vx_enum)VX_NODE_PERFORMANCE, &perf_node2, sizeof(perf_node2));
535  printf("---- Thread #%d: Node 2 (%s) Execution time: %4.6f ms\n", threadIdx+1, targetCore2[threadIdx], perf_node2.min/1000000.0);
536  }
537 
538  vxQueryGraph(graph[threadIdx], (vx_enum)VX_GRAPH_PERFORMANCE, &perf_graph, sizeof(perf_graph));
539  printf("---- Thread #%d: Total Graph Execution time: %4.6f ms\n", threadIdx + 1, perf_graph.min/1000000.0);
540  }
541 
542 #ifdef SEQUENTIAL_SCHEDULE
543  printf("\nExecution time of all the threads running sequentially: %4.6f ms\n", exe_time/1000.0);
544 #else
545  printf("\nExecution time of all the threads running in parallel: %4.6f ms\n", exe_time/1000.0);
546 #endif
547 
548  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
549  if (vxGetStatus((vx_reference)node1[threadIdx]) == (vx_status)VX_SUCCESS) {
550  vxReleaseNode(&node1[threadIdx]);
551  }
552  if (vxGetStatus((vx_reference)createParams1[threadIdx]) == (vx_status)VX_SUCCESS) {
553  vxReleaseUserDataObject(&createParams1[threadIdx]);
554  }
555  if (vxGetStatus((vx_reference)inArgs1[threadIdx]) == (vx_status)VX_SUCCESS) {
556  vxReleaseUserDataObject(&inArgs1[threadIdx]);
557  }
558  if (vxGetStatus((vx_reference)outArgs1[threadIdx]) == (vx_status)VX_SUCCESS) {
559  vxReleaseUserDataObject(&outArgs1[threadIdx]);
560  }
561  if (node2[threadIdx] !=0 ){
562  if (vxGetStatus((vx_reference)node2[threadIdx]) == (vx_status)VX_SUCCESS) {
563  vxReleaseNode(&node2[threadIdx]);
564  }
565  if (vxGetStatus((vx_reference)createParams2[threadIdx]) == (vx_status)VX_SUCCESS) {
566  vxReleaseUserDataObject(&createParams2[threadIdx]);
567  }
568  if (vxGetStatus((vx_reference)inArgs2[threadIdx]) == (vx_status)VX_SUCCESS) {
569  vxReleaseUserDataObject(&inArgs2[threadIdx]);
570  }
571  if (vxGetStatus((vx_reference)outArgs2[threadIdx]) == (vx_status)VX_SUCCESS) {
572  vxReleaseUserDataObject(&outArgs2[threadIdx]);
573  }
574  }
575  }
576 
577  if (config2 !=0 ){
578  if (vxGetStatus((vx_reference)config2) == (vx_status)VX_SUCCESS) {
579  vxReleaseUserDataObject(&config2);
580  }
581  }
582 
583  if (vxGetStatus((vx_reference)config1) == (vx_status)VX_SUCCESS) {
584  vxReleaseUserDataObject(&config1);
585  }
586 
587  if (vxGetStatus((vx_reference)network) == (vx_status)VX_SUCCESS) {
588  vxReleaseUserDataObject(&network);
589  }
590 
591  for (threadIdx= 0; threadIdx < maxNumThreads; threadIdx++) {
592 
593  if (vxGetStatus((vx_reference)graph[threadIdx]) == (vx_status)VX_SUCCESS) {
594  vxReleaseGraph(&graph[threadIdx]);
595  }
596 
597  for (i= 0; i < num_input_tensors; i++) {
598  if (vxGetStatus((vx_reference)input_tensors[threadIdx][i]) == (vx_status)VX_SUCCESS) {
599  vxReleaseTensor(&input_tensors[threadIdx][i]);
600  }
601  }
602 
603  for (i= 0; i < num_output_tensors1; i++) {
604  if (vxGetStatus((vx_reference)output_tensors1[threadIdx][i]) == (vx_status)VX_SUCCESS) {
605  vxReleaseTensor(&output_tensors1[threadIdx][i]);
606  }
607  }
608 
609  for (i= 0; i < num_output_tensors2; i++) {
610  if (vxGetStatus((vx_reference)output_tensors2[threadIdx][i]) == (vx_status)VX_SUCCESS) {
611  vxReleaseTensor(&output_tensors2[threadIdx][i]);
612  }
613  }
614 
615  }
616 
617  if (vxGetStatus((vx_reference)kernel1) == (vx_status)VX_SUCCESS) {
618  vxRemoveKernel(kernel1);
619  }
620  if (kernel2!=0){
621  if (vxGetStatus((vx_reference)kernel2) == (vx_status)VX_SUCCESS) {
622  vxRemoveKernel(kernel2);
623  }
624  }
625 
626  exit:
627  printf("\n vx_tutorial_tidl: Tutorial Done !!! \n");
628  printf(" \n");
629 
630  if (vxGetStatus((vx_reference)context) == (vx_status)VX_SUCCESS) {
631  vxReleaseContext(&context);
632  }
633 
634 }
635 
636 static vx_status parse_cfg_file(VxTutorialTidl_CfgObj *obj, char *cfg_file_name)
637 {
638  FILE *fp = fopen(cfg_file_name, "r");
639  char line_str[1024];
640  char *token;
641  size_t sizeFilePath;
642  char filePath[MAXPATHLENGTH];
643  vx_status status = (vx_status)VX_SUCCESS;
644 
645  /* Set processing_core_mode to 0, which means network can be partitioned accross all cores */
646  obj->processing_core_mode= 0;
647  obj->num_eve_cores= 1;
648 
649  if(fp==NULL)
650  {
651  printf("# ERROR: Unable to open config file [%s]\n", cfg_file_name);
652 #ifdef HOST_EMULATION
653  printf("# ERROR: Please make sure that the environment variable VX_TEST_DATA_PATH is set to .../conformance_tests/test_data\n");
654 #endif
655  status= (vx_status)VX_FAILURE;
656  goto exit;
657  }
658 
659  while(fgets(line_str, sizeof(line_str), fp)!=NULL)
660  {
661  char s[]=" \t";
662 
663  if (strchr(line_str, '#'))
664  {
665  continue;
666  }
667 
668  /* get the first token */
669  token = strtok(line_str, s);
670 
671  if(strcmp(token, "tidl_params_file_path")==0)
672  {
673  token = strtok(NULL, s);
674  token[strlen(token)-1]=0;
675  sizeFilePath = snprintf(filePath, MAXPATHLENGTH, "%s/%s", ct_get_test_file_path(), token);
676  if (sizeFilePath > MAXPATHLENGTH) {
677  printf("Error in parse_cfg_file, path too long to fit in string\n");
678  }
679  else {
680  strcpy(obj->tidl_params_file_path, filePath);
681  }
682  }
683  else
684  if(strcmp(token, "tidl_network_file_path")==0)
685  {
686  token = strtok(NULL, s);
687  token[strlen(token)-1]=0;
688  sizeFilePath = snprintf(filePath, MAXPATHLENGTH, "%s/%s", ct_get_test_file_path(), token);
689  if (sizeFilePath > MAXPATHLENGTH) {
690  printf("Error in parse_cfg_file, path too long to fit in string\n");
691  }
692  else {
693  strcpy(obj->tidl_network_file_path, filePath);
694  }
695  }
696  else
697  if(strcmp(token, "input_file_path")==0)
698  {
699  token = strtok(NULL, s);
700  token[strlen(token)-1]=0;
701  sizeFilePath = snprintf(filePath, MAXPATHLENGTH, "%s/%s", ct_get_test_file_path(), token);
702  if (sizeFilePath > MAXPATHLENGTH) {
703  printf("Error in parse_cfg_file, path too long to fit in string\n");
704  }
705  else {
706  strcpy(obj->input_file_path, filePath);
707  }
708  }
709  else
710  if(strcmp(token, "output_file_path")==0)
711  {
712  token = strtok(NULL, s);
713  token[strlen(token)-1]=0;
714  sizeFilePath = snprintf(filePath, MAXPATHLENGTH, "%s/%s", ct_get_test_file_path(), token);
715  if (sizeFilePath > MAXPATHLENGTH) {
716  printf("Error in parse_cfg_file, path too long to fit in string\n");
717  }
718  else {
719  strcpy(obj->output_file_path, filePath);
720  }
721  }
722  else
723  if(strcmp(token, "operation_mode")==0)
724  {
725  token = strtok(NULL, s);
726  obj->operation_mode = atoi(token);
727  }
728  else
729  if(strcmp(token, "processing_core_mode")==0)
730  {
731  token = strtok(NULL, s);
732  obj->processing_core_mode = atoi(token);
733  }
734  else
735  if(strcmp(token, "num_eve_cores")==0)
736  {
737  token = strtok(NULL, s);
738  obj->num_eve_cores = atoi(token);
739  }
740  }
741 
742  fclose(fp);
743 
744  exit:
745  return status;
746 }
747 
748 static vx_status createInputTensors(vx_context context, vx_user_data_object config, vx_tensor *input_tensors)
749 {
750  vx_size input_sizes[VX_TUTORIAL_MAX_TENSOR_DIMS];
751  vx_map_id map_id_config;
752  sTIDL_IOBufDesc_t *ioBufDesc;
753  uint32_t id;
754  vx_status status = (vx_status)VX_SUCCESS;
755 
756  vxMapUserDataObject(config, 0, sizeof(sTIDL_IOBufDesc_t), &map_id_config,
757  (void **)&ioBufDesc, (vx_enum)VX_READ_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST, 0);
758 
759  if (ioBufDesc->numInputBuf < VX_TUTORIAL_MAX_TENSORS) {
760 
761  for(id = 0; id < ioBufDesc->numInputBuf; id++) {
762  input_sizes[0] = ioBufDesc->inWidth[id] + ioBufDesc->inPadL[id] + ioBufDesc->inPadR[id];
763  input_sizes[1] = ioBufDesc->inHeight[id] + ioBufDesc->inPadT[id] + ioBufDesc->inPadB[id];
764  input_sizes[2] = ioBufDesc->inNumChannels[id];
765 
766  input_tensors[id] = vxCreateTensor(context, 3, input_sizes, (vx_enum)VX_TYPE_UINT8, 0);
767  }
768 
769  }
770  else {
771  status= (vx_status)VX_FAILURE;
772  }
773 
774  vxUnmapUserDataObject(config, map_id_config);
775 
776  return status;
777 }
778 
779 static vx_status createOutputTensor(vx_context context, vx_user_data_object config, vx_tensor *output_tensors)
780 {
781  vx_size output_sizes[VX_TUTORIAL_MAX_TENSOR_DIMS];
782  vx_map_id map_id_config;
783  uint32_t id;
784  sTIDL_IOBufDesc_t *ioBufDesc;
785  vx_status status = (vx_status)VX_SUCCESS;
786 
787  vxMapUserDataObject(config, 0, sizeof(sTIDL_IOBufDesc_t), &map_id_config,
788  (void **)&ioBufDesc, (vx_enum)VX_READ_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST, 0);
789 
790  if (ioBufDesc->numOutputBuf < VX_TUTORIAL_MAX_TENSORS) {
791 
792  for(id = 0; id < ioBufDesc->numOutputBuf; id++) {
793  output_sizes[0] = ioBufDesc->outWidth[id] + ioBufDesc->outPadL[id] + ioBufDesc->outPadR[id];
794  output_sizes[1] = ioBufDesc->outHeight[id] + ioBufDesc->outPadT[id] + ioBufDesc->outPadB[id];
795  output_sizes[2] = ioBufDesc->outNumChannels[id];
796 
797  output_tensors[id] = vxCreateTensor(context, 3, output_sizes, (vx_enum)VX_TYPE_FLOAT32, 0);
798  }
799 
800  }
801  else {
802  status= (vx_status)VX_FAILURE;
803  }
804 
805  vxUnmapUserDataObject(config, map_id_config);
806 
807  return status;
808 }
809 
810 static vx_status readDataS8(FILE *fp, int8_t *ptr, int32_t n,
811  int32_t width, int32_t height, int32_t pitch,
812  int32_t chOffset)
813 {
814  int32_t i0, i1;
815  uint32_t readSize;
816  vx_status status = (vx_status)VX_SUCCESS;
817 
818  for(i0 = 0; i0 < n; i0++)
819  {
820  for(i1 = 0; i1 < height; i1++)
821  {
822  readSize= fread(&ptr[i0*chOffset + i1*pitch], 1, width, fp);
823  if (readSize != width) {
824  status= (vx_status)VX_FAILURE;
825  goto exit;
826  }
827  }
828  }
829 
830  exit:
831  return status;
832 
833 }
834 
835 
836 static vx_status readInput(vx_context context, vx_user_data_object config, vx_tensor *input_tensors, char *input_file, uint32_t operation_mode)
837 {
838  vx_status status = (vx_status)VX_SUCCESS;
839 
840  int8_t *input_buffer = NULL;
841  uint32_t id;
842 
843  vx_map_id map_id_config;
844  vx_map_id map_id_input;
845 
846  vx_size start[VX_TUTORIAL_MAX_TENSOR_DIMS];
847  vx_size input_strides[VX_TUTORIAL_MAX_TENSOR_DIMS];
848  vx_size input_sizes[VX_TUTORIAL_MAX_TENSOR_DIMS];
849 
850  sTIDL_IOBufDesc_t *ioBufDesc;
851 
852  FILE *fp;
853 
854  fp= fopen(input_file, "rb");
855 
856  if(fp==NULL)
857  {
858  printf("# ERROR: Unable to open input file [%s]\n", input_file);
859  return((vx_status)VX_FAILURE);
860  }
861 
862  vxMapUserDataObject(config, 0, sizeof(sTIDL_IOBufDesc_t), &map_id_config,
863  (void **)&ioBufDesc, (vx_enum)VX_READ_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST, 0);
864 
865  for(id = 0; id < ioBufDesc->numInputBuf; id++)
866  {
867  input_sizes[0] = ioBufDesc->inWidth[id] + ioBufDesc->inPadL[id] + ioBufDesc->inPadR[id];
868  input_sizes[1] = ioBufDesc->inHeight[id] + ioBufDesc->inPadT[id] + ioBufDesc->inPadB[id];
869  input_sizes[2] = ioBufDesc->inNumChannels[id];
870 
871  start[0] = start[1] = start[2] = 0;
872 
873  input_strides[0] = 1;
874  input_strides[1] = input_sizes[0];
875  input_strides[2] = input_sizes[1] * input_strides[1];
876 
877  status = tivxMapTensorPatch(input_tensors[id], 3, start, input_sizes, &map_id_input, input_strides, (void **)&input_buffer, (vx_enum)VX_WRITE_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST);
878 
879  if ((vx_status)VX_SUCCESS == status)
880  {
881  status= readDataS8(
882  fp,
883  &input_buffer[(ioBufDesc->inPadT[id] * input_strides[1]) + ioBufDesc->inPadL[id]],
884  ioBufDesc->inNumChannels[id],
885  ioBufDesc->inWidth[id],
886  ioBufDesc->inHeight[id],
887  input_strides[1],
888  input_strides[2]);
889 
890  tivxUnmapTensorPatch(input_tensors[id], map_id_input);
891 
892  if (status== (vx_status)VX_FAILURE) {
893  goto exit;
894  }
895  }
896  }
897 
898  exit:
899  vxUnmapUserDataObject(config, map_id_config);
900 
901  fclose(fp);
902 
903  return status;
904 }
905 
906 static void displayOutput(void *bmp_context, vx_df_image df_image, void *data_ptr, vx_uint32 img_width, vx_uint32 img_height, vx_uint32 img_stride, vx_user_data_object config, vx_tensor *output_tensors, char *output_file, uint32_t operation_mode)
907 {
908  vx_status status = (vx_status)VX_SUCCESS;
909 
910  vx_size output_sizes[VX_TUTORIAL_MAX_TENSOR_DIMS];
911 
912  vx_map_id map_id_config;
913 
914  int32_t id, i, j;
915 
916  sTIDL_IOBufDesc_t *ioBufDesc;
917 
918  vxMapUserDataObject(config, 0, sizeof(sTIDL_IOBufDesc_t), &map_id_config,
919  (void **)&ioBufDesc, (vx_enum)VX_READ_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST, 0);
920 
921  for(id = 0; id < 1; id++)
922  {
923  output_sizes[0] = ioBufDesc->outWidth[id] + ioBufDesc->outPadL[id] + ioBufDesc->outPadR[id];
924  output_sizes[1] = ioBufDesc->outHeight[id] + ioBufDesc->outPadT[id] + ioBufDesc->outPadB[id];
925  output_sizes[2] = ioBufDesc->outNumChannels[id];
926 
927  status = vxGetStatus((vx_reference)output_tensors[id]);
928 
929  if ((vx_status)VX_SUCCESS == status)
930  {
931  void *output_buffer;
932 
933  vx_map_id map_id_output;
934 
935  vx_size output_strides[VX_TUTORIAL_MAX_TENSOR_DIMS];
936  vx_size start[VX_TUTORIAL_MAX_TENSOR_DIMS];
937 
938  start[0] = start[1] = start[2] = start[3] = 0;
939 
940  output_strides[0] = 1;
941  output_strides[1] = output_sizes[0];
942  output_strides[2] = output_sizes[1] * output_strides[1];
943 
944  tivxMapTensorPatch(output_tensors[id], 3, start, output_sizes, &map_id_output, output_strides, &output_buffer, (vx_enum)VX_READ_ONLY, (vx_enum)VX_MEMORY_TYPE_HOST);
945 
946  if (operation_mode == 0)
947  {
948  uint8_t *pOut;
949  uint8_t score[5];
950  vx_uint32 classid[5];
951 
952  pOut = (uint8_t *)output_buffer + (ioBufDesc->outPadT[id] * output_sizes[0]) + ioBufDesc->outPadL[id];
953 
954  for(i = 0; i < 5; i++)
955  {
956  score[i] = 0;
957  classid[i] = 0xFFFFFFFF;
958 
959  for(j = 0; j < output_sizes[0]; j++)
960  {
961  if(pOut[j] > score[i])
962  {
963  score[i] = pOut[j];
964  classid[i] = j;
965  }
966  }
967 
968  pOut[classid[i]] = 0;
969  }
970 
971  printf("\nImage classification Top-5 results: \n");
972 
973  for(i = 0; i < 5; i++)
974  {
975  printf(" %s, class-id: %d, score: %u\n", (char *)&imgnet_labels[classid[i]], classid[i], score[i]);
976  }
977  }
978  else
979  if (operation_mode== 1)
980  {
981  typedef struct {
982  float objId;
983  float label;
984  float score;
985  float xmin;
986  float ymin;
987  float xmax;
988  float ymax;
989  } ODLayerObjInfo;
990 
991  /* Display of coordinates of detected objects */
992  uint8_t *pOut;
993  ODLayerObjInfo *pObjInfo;
994  uint32_t numObjs;
995 
996  numObjs= 20;
997 
998  pOut = (uint8_t *)output_buffer + (ioBufDesc->outPadT[id] * output_sizes[0]) + ioBufDesc->outPadL[id];
999 
1000  pObjInfo = (ODLayerObjInfo *)pOut;
1001 
1002  printf("\nObjId|label|score| xmin| ymin| xmax| ymax|\n");
1003  printf("------------------------------------------\n");
1004  for(i = 0; i < numObjs; i++)
1005  {
1006  ODLayerObjInfo * pObj = pObjInfo + i;
1007  if ((int32_t)(pObj->objId)!=-1) {
1008  printf("%5d|%5d|%5.2f|%5.2f|%5.2f|%5.2f|%5.2f|\n", (int32_t)pObj->objId, (uint32_t)pObj->label, pObj->score, pObj->xmin, pObj->ymin, pObj->xmax, pObj->ymax);
1009  }
1010  else {
1011  break;
1012  }
1013  /*
1014  if(pPSpots->score >= 0.5f)
1015  {
1016  drawBox(obj, pObj);
1017  }
1018  */
1019  }
1020  printf("\nNumber of detected objects: %d\n\n", i);
1021  }
1022  tivxUnmapTensorPatch(output_tensors[id], map_id_output);
1023  }
1024  }
1025 
1026  vxUnmapUserDataObject(config, map_id_config);
1027 }
vx_kernel tivxAddKernelTIDL(vx_context context, uint32_t num_input_tensors, uint32_t num_output_tensors)
Used for the Application to create the tidl kernel from the context.
VX_DIRECTIVE_ENABLE_PERFORMANCE
Max value of CPU ID.
Definition: tivx.h:246
Invalid CPU ID.
Definition: tivx.h:249
VX_API_ENTRY vx_node VX_API_CALL tivxTIDLNode(vx_graph graph, vx_kernel kernel, vx_reference appParams[], vx_tensor input_tensors[], vx_tensor output_tensors[])
[Graph] Creates a TIDL Node.
VX_MEMORY_TYPE_HOST
Interface to TI extension APIs.
size_t vx_size
VX_API_ENTRY vx_status VX_API_CALL vxReleaseTensor(vx_tensor *tensor)
Releases a reference to a tensor data object. The object may not be garbage collected until its total...
int32_t vx_enum
VX_SUCCESS
vx_status VX_API_CALL vxQueryGraph(vx_graph graph, vx_enum attribute, void *ptr, vx_size size)
CPU ID for DSP2.
Definition: tivx.h:216
vx_status VX_API_CALL vxProcessGraph(vx_graph graph)
VX_GRAPH_PERFORMANCE
vx_status VX_API_CALL vxReleaseContext(vx_context *context)
VX_TYPE_FLOAT32
vx_enum vx_status
VX_NODE_PERFORMANCE
vx_status VX_API_CALL vxRemoveKernel(vx_kernel kernel)
struct _vx_context * vx_context
vx_status VX_API_CALL vxSetNodeTarget(vx_node node, vx_enum target_enum, const char *target_string)
struct _vx_reference * vx_reference
CPU ID for DSP1.
Definition: tivx.h:213
#define TIVX_TARGET_DSP2
Name for DSP target class, instance 2.
Definition: tivx.h:97
VX_TARGET_STRING
uint32_t vx_df_image
VX_WRITE_ONLY
vx_uint64 min
VX_READ_ONLY
CPU ID for EVE3.
Definition: tivx.h:225
CPU ID for EVE1.
Definition: tivx.h:219
vx_status VX_API_CALL vxWaitGraph(vx_graph graph)
#define TIVX_TARGET_DSP1
Name for DSP target class, instance 1.
Definition: tivx.h:92
struct _vx_user_data_object * vx_user_data_object
The User Data Object. User Data Object is a strongly-typed container for other data structures.
vx_status VX_API_CALL vxReleaseGraph(vx_graph *graph)
struct _vx_kernel * vx_kernel
vx_status VX_API_CALL vxQueryNode(vx_node node, vx_enum attribute, void *ptr, vx_size size)
VX_FAILURE
VX_API_ENTRY vx_status VX_API_CALL vxMapUserDataObject(vx_user_data_object user_data_object, vx_size offset, vx_size size, vx_map_id *map_id, void **ptr, vx_enum usage, vx_enum mem_type, vx_uint32 flags)
Allows the application to get direct access to a subset of the user data object.
uint32_t vx_uint32
vx_graph VX_API_CALL vxCreateGraph(vx_context context)
VX_API_ENTRY vx_status VX_API_CALL vxUnmapUserDataObject(vx_user_data_object user_data_object, vx_map_id map_id)
Unmap and commit potential changes to a user data object subset that was previously mapped....
CPU ID for EVE4.
Definition: tivx.h:228
VX_API_ENTRY vx_status VX_API_CALL vxReleaseUserDataObject(vx_user_data_object *user_data_object)
Releases a reference of a User data object. The object may not be garbage collected until its total r...
VX_API_ENTRY vx_status VX_API_CALL tivxUnmapTensorPatch(vx_tensor tensor, vx_map_id map_id)
Unmap and commit potential changes to a tensor object patch that were previously mapped....
vx_status VX_API_CALL vxDirective(vx_reference reference, vx_enum directive)
uint64_t tivxPlatformGetTimeInUsecs(void)
Get the time in micro seconds.
vx_status VX_API_CALL vxVerifyGraph(vx_graph graph)
vx_status VX_API_CALL vxScheduleGraph(vx_graph graph)
vx_context VX_API_CALL vxCreateContext()
VX_API_ENTRY vx_tensor VX_API_CALL vxCreateTensor(vx_context context, vx_size number_of_dims, const vx_size *dims, vx_enum data_type, vx_int8 fixed_point_position)
Creates an opaque reference to a tensor data buffer.
struct _vx_graph * vx_graph
vx_status VX_API_CALL vxReleaseNode(vx_node *node)
VX_API_ENTRY vx_status VX_API_CALL tivxMapTensorPatch(vx_tensor tensor, vx_size number_of_dims, const vx_size *view_start, const vx_size *view_end, vx_map_id *map_id, vx_size *stride, void **ptr, vx_enum usage, vx_enum mem_type)
Allows the application to get direct access to a patch of tensor object.
struct _vx_node * vx_node
uintptr_t vx_map_id
struct _vx_tensor * vx_tensor
The multidimensional data object (Tensor).
Definition: tivx_tensor.h:83
CPU ID for EVE2.
Definition: tivx.h:222
vx_status VX_API_CALL vxGetStatus(vx_reference reference)
VX_TYPE_UINT8
tivx_cpu_id_e
CPU ID for supported CPUs.
Definition: tivx.h:210