From bb472db1c6a6f550e4196939f9977b7972660427 Mon Sep 17 00:00:00 2001 From: Brock Carey Date: Wed, 21 Aug 2024 11:50:13 -0500 Subject: [PATCH] [TIOVX-1501] Implementing node/graph level debug options --- .../test_kernels/arm/vx_test_target_target.c | 8 +- conformance_tests/test_tiovx/test_debug.c | 106 +++++++++++++++++- .../test_tiovx/test_graph_pipeline.c | 73 ++++++------ include/TI/tivx_debug.h | 59 ++++++++-- include/TI/tivx_obj_desc.h | 7 ++ include/TI/tivx_target_kernel.h | 14 +++ .../content_pages/20_usage.h | 24 +++- kernels/include/tivx_kernels_host_utils.h | 1 + kernels/include/tivx_kernels_target_utils.h | 5 + source/framework/vx_debug.c | 64 +++++++---- source/framework/vx_graph.c | 47 +++++++- source/framework/vx_graph_verify.c | 46 ++++---- source/framework/vx_node.c | 58 +++++++++- source/framework/vx_target.c | 35 ++++-- source/framework/vx_target_kernel_instance.c | 4 + source/include/tivx_debug.h | 82 ++++++++++++++ source/include/vx_graph.h | 3 + source/include/vx_internal.h | 1 + source/include/vx_node.h | 4 +- source/platform/pc/common/tivx_init.c | 3 + 20 files changed, 528 insertions(+), 116 deletions(-) create mode 100644 source/include/tivx_debug.h diff --git a/conformance_tests/kernels/test_kernels/arm/vx_test_target_target.c b/conformance_tests/kernels/test_kernels/arm/vx_test_target_target.c index 1dfde511e..0ab957e19 100644 --- a/conformance_tests/kernels/test_kernels/arm/vx_test_target_target.c +++ b/conformance_tests/kernels/test_kernels/arm/vx_test_target_target.c @@ -283,22 +283,22 @@ static vx_status tivxTestTargetDebugZone(uint8_t id) vx_status status = (vx_status)VX_SUCCESS; vx_enum zone = VX_ZONE_INFO; - if(vx_true_e != tivx_get_debug_zone(zone)) + if(vx_true_e != tivx_is_zone_enabled(zone)) { VX_PRINT(VX_ZONE_ERROR,"Invalid result:VX_ZONE_INFO is cleared\n"); status = (vx_status)VX_FAILURE; } - if(vx_false_e != tivx_get_debug_zone(VX_ZONE_TARGET)) + if(vx_false_e != tivx_is_zone_enabled(VX_ZONE_TARGET)) { VX_PRINT(VX_ZONE_ERROR,"Invalid result:VX_ZONE_TARGET is enabled\n"); status = (vx_status)VX_FAILURE; } - if(vx_false_e != tivx_get_debug_zone(-1)) + if(vx_false_e != tivx_is_zone_enabled(-1)) { VX_PRINT(VX_ZONE_ERROR,"Invalid result returned for the ARG:-1\n"); status = (vx_status)VX_FAILURE; } - if(vx_false_e != tivx_get_debug_zone(VX_ZONE_MAX)) + if(vx_false_e != tivx_is_zone_enabled(VX_ZONE_MAX)) { VX_PRINT(VX_ZONE_ERROR,"Invalid result returned for the ARG:'VX_ZONE_MAX'\n"); status = (vx_status)VX_FAILURE; diff --git a/conformance_tests/test_tiovx/test_debug.c b/conformance_tests/test_tiovx/test_debug.c index e4d6d29f7..2457a5658 100644 --- a/conformance_tests/test_tiovx/test_debug.c +++ b/conformance_tests/test_tiovx/test_debug.c @@ -19,7 +19,7 @@ */ #include -#include +#include #include "test_engine/test.h" @@ -51,16 +51,110 @@ TEST(tivxDebug, negativeTestGetDebugZone) vx_enum zone = -1; - ASSERT(vx_false_e == tivx_get_debug_zone(zone)); - ASSERT(vx_false_e == tivx_get_debug_zone(VX_ZONE_MAX)); - ASSERT(vx_false_e == tivx_get_debug_zone(0)); - ASSERT(vx_true_e == tivx_get_debug_zone(1)); + ASSERT(vx_false_e == tivx_is_zone_enabled(zone)); + ASSERT(vx_false_e == tivx_is_zone_enabled(VX_ZONE_MAX)); + ASSERT(vx_false_e == tivx_is_zone_enabled(0)); + ASSERT(vx_true_e == tivx_is_zone_enabled(1)); +} + +TEST(tivxDebug, testSetNodeDebugZone) +{ + vx_context context = context_->vx_context_; + vx_graph graph = 0; + vx_kernel kernel = 0; + vx_node node = 0; + vx_uint32 set_zone = (vx_enum)VX_ZONE_INFO; + + ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH); + ASSERT_VX_OBJECT(kernel = vxGetKernelByEnum(context, VX_KERNEL_BOX_3x3), VX_TYPE_KERNEL); + ASSERT_VX_OBJECT(node = vxCreateGenericNode(graph, kernel), VX_TYPE_NODE); + + set_zone = (vx_enum)VX_ZONE_INFO; + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxNodeSetDebugZone(node, set_zone, vx_true_e)); + + set_zone = (vx_enum)VX_ZONE_ERROR; + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxNodeSetDebugZone(node, set_zone, vx_false_e)); + + VX_CALL(vxReleaseNode(&node)); + VX_CALL(vxReleaseKernel(&kernel)); + VX_CALL(vxReleaseGraph(&graph)); +} + +TEST(tivxDebug, testSetGraphDebugZone) +{ + vx_context context = context_->vx_context_; + vx_graph graph = 0; + vx_kernel kernel = 0; + vx_uint32 set_gZone = (vx_enum)VX_ZONE_INFO, set_nZone = (vx_enum)VX_ZONE_WARNING, num_nodes = 10, i; + vx_node node[num_nodes]; + + ASSERT_VX_OBJECT(kernel = vxGetKernelByEnum(context, VX_KERNEL_BOX_3x3), VX_TYPE_KERNEL); + ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH); + + for (i = 0; i < num_nodes; i++) + { + ASSERT_VX_OBJECT(node[i] = vxCreateGenericNode(graph, kernel), VX_TYPE_NODE); + + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxNodeSetDebugZone(node[i], set_nZone, vx_true_e)); + } + + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxGraphSetDebugZone(graph, set_gZone, vx_true_e)); + + set_gZone = (vx_enum)VX_ZONE_WARNING; + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxGraphSetDebugZone(graph, set_gZone, vx_false_e)); + + for (i = 0; i < num_nodes; i++) + { + VX_CALL(vxReleaseNode(&node[i])); + } + VX_CALL(vxReleaseKernel(&kernel)); + VX_CALL(vxReleaseGraph(&graph)); +} + +TEST(tivxDebug, negativetestSetNodeDebugZone) +{ + vx_context context = context_->vx_context_; + vx_graph graph = 0; + vx_kernel kernel = 0; + vx_node node = 0; + vx_uint32 level; + vx_size size = 0; + + ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH); + ASSERT_VX_OBJECT(kernel = vxGetKernelByEnum(context, VX_KERNEL_BOX_3x3), VX_TYPE_KERNEL); + ASSERT_VX_OBJECT(node = vxCreateGenericNode(graph, kernel), VX_TYPE_NODE); + + level = VX_ZONE_MAX+1; + ASSERT_EQ_VX_STATUS(VX_ERROR_INVALID_PARAMETERS, tivxNodeSetDebugZone(node, level, vx_true_e)); + + VX_CALL(vxReleaseNode(&node)); + VX_CALL(vxReleaseKernel(&kernel)); + VX_CALL(vxReleaseGraph(&graph)); +} + +TEST(tivxDebug, negativeTestSetGraphDebugZone) +{ + vx_context context = context_->vx_context_; + vx_graph graph = 0; + vx_uint32 level; + vx_size size = 0; + + ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH); + + level = VX_ZONE_MAX+1; + ASSERT_EQ_VX_STATUS(VX_ERROR_INVALID_PARAMETERS, tivxGraphSetDebugZone(graph, level, vx_true_e)); + + VX_CALL(vxReleaseGraph(&graph)); } TESTCASE_TESTS( tivxDebug, negativeTestSetDebugZone, negativeTestClrDebugZone, - negativeTestGetDebugZone + negativeTestGetDebugZone, + testSetNodeDebugZone, + testSetGraphDebugZone, + negativetestSetNodeDebugZone, + negativeTestSetGraphDebugZone ) diff --git a/conformance_tests/test_tiovx/test_graph_pipeline.c b/conformance_tests/test_tiovx/test_graph_pipeline.c index 5d1290ca7..11f2bbf7e 100644 --- a/conformance_tests/test_tiovx/test_graph_pipeline.c +++ b/conformance_tests/test_tiovx/test_graph_pipeline.c @@ -1616,14 +1616,16 @@ TEST_WITH_ARG(tivxGraphPipeline, testTwoNodes, Arg, PARAMETERS) * - Same input going to multiple nodes * - Outputs from multiple nodes going to a single node * - Node taking input from another node as well as from user + * - Graph / node level debugging options at each level of the pipeline * */ TEST_WITH_ARG(tivxGraphPipeline, testFourNodes, Arg, PARAMETERS) { vx_context context = context_->vx_context_; vx_graph graph; - vx_image d0[MAX_NUM_BUF] = {NULL}, d1, d2, d3, d4[MAX_NUM_BUF] = {NULL}, d5[MAX_NUM_BUF] = {NULL}; - vx_node n0, n1, n2, n3; + vx_uint32 gLevel = (vx_enum)VX_ZONE_INFO, nLevel = (vx_enum)VX_ZONE_WARNING, new_level = 0, num_nodes=4, num_images=3, i; + vx_image d0[MAX_NUM_BUF] = {NULL}, virtImg[num_images], d4[MAX_NUM_BUF] = {NULL}, d5[MAX_NUM_BUF] = {NULL}; + vx_node node[num_nodes]; vx_graph_parameter_queue_params_t graph_parameters_queue_params_list[3]; CT_Image ref_src[MAX_NUM_BUF] = {NULL}, vxdst; @@ -1660,33 +1662,37 @@ TEST_WITH_ARG(tivxGraphPipeline, testFourNodes, Arg, PARAMETERS) ASSERT_VX_OBJECT(d4[buf_id] = vxCreateImage(context, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); ASSERT_VX_OBJECT(d5[buf_id] = vxCreateImage(context, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); } - ASSERT_VX_OBJECT(d1 = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); - ASSERT_VX_OBJECT(d2 = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); - ASSERT_VX_OBJECT(d3 = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); - ASSERT_VX_OBJECT(n0 = vxNotNode(graph, d0[0], d1), VX_TYPE_NODE); - ASSERT_VX_OBJECT(n1 = vxNotNode(graph, d1, d2), VX_TYPE_NODE); - ASSERT_VX_OBJECT(n2 = vxOrNode(graph, d1, d2, d3), VX_TYPE_NODE); - ASSERT_VX_OBJECT(n3 = vxAndNode(graph, d3, d4[0], d5[0]), VX_TYPE_NODE); + for (i = 0; i < num_images; i++) + { + ASSERT_VX_OBJECT(virtImg[i] = vxCreateVirtualImage(graph, width, height, VX_DF_IMAGE_U8), VX_TYPE_IMAGE); + } + + ASSERT_VX_OBJECT(node[0] = vxNotNode(graph, d0[0], virtImg[0]), VX_TYPE_NODE); + ASSERT_VX_OBJECT(node[1] = vxNotNode(graph, virtImg[0], virtImg[1]), VX_TYPE_NODE); + ASSERT_VX_OBJECT(node[2] = vxOrNode(graph, virtImg[0], virtImg[1], virtImg[2]), VX_TYPE_NODE); + ASSERT_VX_OBJECT(node[3] = vxAndNode(graph, virtImg[2], d4[0], d5[0]), VX_TYPE_NODE); + + ASSERT_EQ_VX_STATUS(VX_SUCCESS, tivxGraphSetDebugZone(graph, gLevel, vx_true_e)); #if defined(SOC_AM62A) - VX_CALL(vxSetNodeTarget(n0, VX_TARGET_STRING, TIVX_TARGET_DSP1)); - VX_CALL(vxSetNodeTarget(n1, VX_TARGET_STRING, TIVX_TARGET_DSP1)); - VX_CALL(vxSetNodeTarget(n2, VX_TARGET_STRING, TIVX_TARGET_DSP1)); - VX_CALL(vxSetNodeTarget(n3, VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[0], VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[1], VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[2], VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[3], VX_TARGET_STRING, TIVX_TARGET_DSP1)); #else - VX_CALL(vxSetNodeTarget(n0, VX_TARGET_STRING, TIVX_TARGET_DSP1)); - VX_CALL(vxSetNodeTarget(n1, VX_TARGET_STRING, TIVX_TARGET_DSP1)); - VX_CALL(vxSetNodeTarget(n2, VX_TARGET_STRING, TIVX_TARGET_DSP2)); - VX_CALL(vxSetNodeTarget(n3, VX_TARGET_STRING, TIVX_TARGET_DSP2)); + VX_CALL(vxSetNodeTarget(node[0], VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[1], VX_TARGET_STRING, TIVX_TARGET_DSP1)); + VX_CALL(vxSetNodeTarget(node[2], VX_TARGET_STRING, TIVX_TARGET_DSP2)); + VX_CALL(vxSetNodeTarget(node[3], VX_TARGET_STRING, TIVX_TARGET_DSP2)); #endif /* input @ n0 index 0, becomes graph parameter 0 */ - add_graph_parameter_by_node_index(graph, n0, 0); + add_graph_parameter_by_node_index(graph, node[0], 0); /* input @ n3 index 1, becomes graph parameter 1 */ - add_graph_parameter_by_node_index(graph, n3, 1); + add_graph_parameter_by_node_index(graph, node[3], 1); /* output @ n3 index 2, becomes graph parameter 2 */ - add_graph_parameter_by_node_index(graph, n3, 2); + add_graph_parameter_by_node_index(graph, node[3], 2); /* set graph schedule config such that graph parameter @ index 0, 1, 2 are enqueuable */ graph_parameters_queue_params_list[0].graph_parameter_index = 0; @@ -1725,24 +1731,24 @@ TEST_WITH_ARG(tivxGraphPipeline, testFourNodes, Arg, PARAMETERS) } /* Validating tivxGetNodeParameterNumBufByIndex API */ - VX_CALL(tivxGetNodeParameterNumBufByIndex(n0, 1, &get_num_buf)); + VX_CALL(tivxGetNodeParameterNumBufByIndex(node[0], 1, &get_num_buf)); ASSERT(get_num_buf==0); - VX_CALL(set_num_buf_by_node_index(n0, 1, tmp_num_buf)); + VX_CALL(set_num_buf_by_node_index(node[0], 1, tmp_num_buf)); /* Validating tivxGetNodeParameterNumBufByIndex API */ - VX_CALL(tivxGetNodeParameterNumBufByIndex(n0, 1, &get_num_buf)); + VX_CALL(tivxGetNodeParameterNumBufByIndex(node[0], 1, &get_num_buf)); ASSERT(get_num_buf==tmp_num_buf); /* n1 and n2 run on different targets hence set output of n1 to have multiple buffers so * that n1 and n2 can run in a pipeline */ - VX_CALL(set_num_buf_by_node_index(n1, 1, num_buf)); + VX_CALL(set_num_buf_by_node_index(node[1], 1, num_buf)); tmp_num_buf = 1; - VX_CALL(set_num_buf_by_node_index(n2, 2, tmp_num_buf)); + VX_CALL(set_num_buf_by_node_index(node[2], 2, tmp_num_buf)); VX_CALL(vxVerifyGraph(graph)); @@ -1826,25 +1832,26 @@ TEST_WITH_ARG(tivxGraphPipeline, testFourNodes, Arg, PARAMETERS) if(arg_->measure_perf==1) { - vx_node nodes[] = { n0, n1, n2, n3 }; + vx_node nodes[] = { node[0], node[1], node[2], node[3] }; printGraphPipelinePerformance(graph, nodes, 4, exe_time, loop_cnt+num_buf, arg_->width*arg_->height); } #endif - VX_CALL(vxReleaseNode(&n0)); - VX_CALL(vxReleaseNode(&n1)); - VX_CALL(vxReleaseNode(&n2)); - VX_CALL(vxReleaseNode(&n3)); + for (i = 0; i < num_nodes; i++) + { + VX_CALL(vxReleaseNode(&node[i])); + } for(buf_id=0; buf_id +#include + /*! \brief Macros for build time check * \ingroup group_tivx_platform */ @@ -74,6 +76,8 @@ #define BUILD_ASSERT(e) \ enum { ASSERT_CONCAT(assert_line_, __LINE__) = (1U/(e)) } +#define ZONE_BIT(zone) ((vx_uint32)1U << (zone)) + /*! * \file * \brief The Internal Debugging API @@ -110,28 +114,39 @@ enum tivx_debug_zone_e { VX_ZONE_OPTIMIZATION = 19, /*!< Used to provide optimization tips */ - VX_ZONE_MAX = 32 + VX_ZONE_MAX = 32 /*!< Maximum value a debug zone can be mapped to */ }; -#define VX_PRINT(zone, message, ...) do { tivx_print(((vx_enum)zone), "[%s:%u] " message, __FUNCTION__, __LINE__, ## __VA_ARGS__); } while (1 == 0) - /*! \def VX_PRINT - * \brief The OpenVX Debugging Facility. + * \brief Utility macro to print debug information if specified zone is globally set * \ingroup group_vx_debug */ +#define VX_PRINT(zone, message, ...) do { tivx_print_global(((vx_enum)zone), "[%s:%u] " message, __FUNCTION__, __LINE__, ## __VA_ARGS__); } while (1 == 0) +#define VX_PRINT_LOCAL(zone, debug_zonemask, message, ...) do { tivx_print_object(((vx_enum)zone), debug_zonemask, "[%s:%u] " message, __FUNCTION__, __LINE__, ## __VA_ARGS__); } while (1 == 0) #ifdef __cplusplus extern "C" { #endif -/*! \brief Internal Printing Function. - * \param [in] zone The debug zone from \ref tivx_debug_zone_e. +vx_char *tivx_find_zone_name(vx_enum zone); + +/*! \brief Internal printing function for the global debug zone bitmask + * \param [in] zone The debug zone from \ref tivx_debug_zone_e required to print the given message. + * \param [in] format The format string to print. + * \param [in] ... The variable list of arguments. + * \ingroup group_vx_debug + */ +void tivx_print_global(vx_enum zone, const char *format, ...); + +/*! \brief Internal printing function for a framework object with a set debug zone bitmask + * \param [in] zone The debug zone from \ref tivx_debug_zone_e required to print the given message. + * \param [in] set_zone The debug zone bitmask of a framework object * \param [in] format The format string to print. * \param [in] ... The variable list of arguments. * \ingroup group_vx_debug */ -void tivx_print(vx_enum zone, const char *format, ...); +void tivx_print_object(vx_enum zone, vx_uint32 debug_zonemask, const char *format, ...); /*! \brief Sets a zone bit in the debug mask * \param [in] zone The debug zone from \ref tivx_debug_zone_e. @@ -149,7 +164,35 @@ void tivx_clr_debug_zone(vx_enum zone); * \param [in] zone The debug zone from \ref tivx_debug_zone_e. * \ingroup group_vx_debug */ -vx_bool tivx_get_debug_zone(vx_enum zone); +vx_bool tivx_is_zone_enabled(vx_enum zone); + +/*! \brief Returns the global debug zone bitmask + * \param [out] vx_uint32 The global debug zone bitmask + * \ingroup group_vx_debug + */ +vx_uint32 tivx_get_global_zonemask(void); + +/*! + * \brief Sets or clears a given debug zone for a graph + * + * \param [in] graph Graph reference + * \param [in] debug_zone Given debug zone enumeration + * \param [in] enable Flag to indicate if zone should be enabled or disabled + * + * \ingroup group_vx_graph + */ +vx_status tivxGraphSetDebugZone(vx_graph graph, vx_uint32 debug_zone, vx_bool enable); + +/*! + * \brief Sets or clears a given debug zone for a node + * + * \param [in] node Node reference + * \param [in] debug_zone Given debug zone enumeration + * \param [in] enable Flag to indicate if zone should be enabled or disabled + * + * \ingroup group_vx_node + */ +vx_status tivxNodeSetDebugZone(vx_node node, vx_uint32 debug_zone, vx_bool enable); #ifdef __cplusplus } diff --git a/include/TI/tivx_obj_desc.h b/include/TI/tivx_obj_desc.h index feeffdfbf..dbbe806cd 100755 --- a/include/TI/tivx_obj_desc.h +++ b/include/TI/tivx_obj_desc.h @@ -68,6 +68,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -339,7 +340,9 @@ typedef struct _tivx_obj_desc_t { * \brief Node object descriptor * * Fields with name target_* are only accessed by target CPU + * * Fields with name host_* are only accessed by host CPU + * * Other fields are accessed by both target and host * * \ingroup group_tivx_obj_desc @@ -494,6 +497,10 @@ typedef struct _tivx_obj_desc_node */ volatile uint32_t block_height; + /*! \brief Debug zonemask of a given object descriptor node. + */ + vx_uint32 debug_zonemask; + } tivx_obj_desc_node_t; /*! diff --git a/include/TI/tivx_target_kernel.h b/include/TI/tivx_target_kernel.h index 424766e75..4f536b0e0 100755 --- a/include/TI/tivx_target_kernel.h +++ b/include/TI/tivx_target_kernel.h @@ -259,6 +259,20 @@ VX_API_ENTRY vx_bool tivxIsTargetKernelInstanceReplicated(tivx_target_kernel_ins */ tivx_target_kernel tivxTargetKernelInstanceGetKernel(tivx_target_kernel_instance target_kernel_instance); +/*! + * \brief Get debug zonemask for a given target kernel instance + * + * \ingroup group_tivx_target_kernel_instance + */ +vx_uint32 tivxGetTargetKernelInstanceDebugZonemask(tivx_target_kernel_instance kernel); + +/*! + * \brief Get debug zonemask for a given hoste node + * + * \ingroup group_tivx_target_kernel_instance + */ +vx_uint32 tivxGetHostKernelDebugZonemask(vx_node node); + static inline vx_bool tivxFlagIsBitSet(uint32_t flag_var, uint32_t flag_val); static inline void tivxFlagBitSet(volatile uint32_t *flag_var, uint32_t flag_val); static inline void tivxFlagBitClear(volatile uint32_t *flag_var, uint32_t flag_val); diff --git a/internal_docs/doxy_cfg_user_guide/content_pages/20_usage.h b/internal_docs/doxy_cfg_user_guide/content_pages/20_usage.h index 3c7f96541..a1d3629c3 100755 --- a/internal_docs/doxy_cfg_user_guide/content_pages/20_usage.h +++ b/internal_docs/doxy_cfg_user_guide/content_pages/20_usage.h @@ -477,11 +477,31 @@ This page itemizes the various debug utilities and methods recommended for TIOVX application development + - \subpage GRAPH_NODE_DEBUG - How to set graph/node specific debug levels - \subpage DEBUG_PRINT - How to enable debug print statements. - \subpage JPEG_TOOL - How to use the graph JPEG generation tool - \subpage DEBUG_LOG_RT - How to enable run-time event start/stop logging and offline visualization */ + /*! + \page GRAPH_NODE_DEBUG Setting Graph and Node Debug Levels + + Explicitly setting logging levels creates flexibility for debugging specific graphs and nodes within an application. + Debug levels can be set for specific graphs and nodes using the TIVX_GRAPH_DEBUG_LEVEL and TIVX_NODE_DEBUG_LEVEL attributes of the + \ref vxSetGraphAttribute and \ref vxSetNodeAttribute APIs respectively. Valid logging levels for nodes and graphs are VX_ZONE_ERROR, + VX_ZONE_WARNING, and VX_ZONE_INFO, increasing from error to info. When setting the logging level for a graph, all nodes that have lower + logging levels will be updated. Nodes with debug levels that are already set to a higher level will remain at their original debug levels. + When a graph or node are created, the default and lowest logging level is VX_ZONE_ERROR. + + When creating a custom user kernel, a change must be made to the \ref VX_PRINT statement. Rather than passing just the VX_ZONE_* parameter, + the VX_DEBUG_ENCODE macro must be called which accepts a VX_ZONE_* parameter as well as the \ref debug_level of the current node or graph. + A check is performed in the \ref tivx_print definition to ensure that the proper debug level is set, even during node processing when + tasks that contain different nodes might be switching preemptively. + + More information on specific logging levels can be found in the documentation for \ref tivx_debug_zone_e. + + */ + /*! \page DEBUG_PRINT Debug Print Statements @@ -496,7 +516,7 @@ */ /*! - \page JPEG_TOOL JPEG visualization of graph + \page JPEG_TOOL JPEG Visualization of Graph The \ref tivxExportGraphToDot API provides the ability to generate a JPEG diagramming the nodes in a graph. Below are a few notes on how to use this tool. @@ -524,7 +544,7 @@ */ /*! - \page DEBUG_LOG_RT Run-time event logging and visualization + \page DEBUG_LOG_RT Run-time Event Logging and Visualization \tableofcontents diff --git a/kernels/include/tivx_kernels_host_utils.h b/kernels/include/tivx_kernels_host_utils.h index 67a59bb3d..ac8d4c215 100644 --- a/kernels/include/tivx_kernels_host_utils.h +++ b/kernels/include/tivx_kernels_host_utils.h @@ -66,6 +66,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/kernels/include/tivx_kernels_target_utils.h b/kernels/include/tivx_kernels_target_utils.h index 3603570c3..cf3b17eb3 100644 --- a/kernels/include/tivx_kernels_target_utils.h +++ b/kernels/include/tivx_kernels_target_utils.h @@ -66,11 +66,16 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif +#undef VX_PRINT +#define VX_PRINT(zone, message, ...) VX_PRINT_LOCAL(zone, tivxGetTargetKernelInstanceDebugZonemask(kernel), message, ## __VA_ARGS__) + #define MAX2(a, b) (((a) > (b)) ? (a) : (b)) #define MAX3(a, b, c) (MAX2((MAX2((a), (b))), (c))) #define MAX4(a, b, c, d) (MAX2((MAX3((a), (b), (c))), (d))) diff --git a/source/framework/vx_debug.c b/source/framework/vx_debug.c index 2847d2901..6729d4fbc 100644 --- a/source/framework/vx_debug.c +++ b/source/framework/vx_debug.c @@ -17,16 +17,10 @@ #include -static vx_char *find_zone_name(vx_enum zone); +static void tivx_print(vx_enum zone, vx_uint32 debug_zonemask, const char *format, va_list ap); static vx_uint32 g_debug_zonemask = 0; -#ifdef ZONE_BIT -#undef ZONE_BIT -#endif - -#define ZONE_BIT(zone) ((vx_uint32)1U << (zone)) - #define STR2(x) {#x, (vx_enum)x} struct vx_string_and_enum_e { @@ -54,10 +48,11 @@ static struct vx_string_and_enum_e g_debug_enumnames[] = { STR2(VX_ZONE_TARGET), STR2(VX_ZONE_LOG), STR2(VX_ZONE_INIT), + STR2(VX_ZONE_OPTIMIZATION), {"UNKNOWN", -1} /* if the zone is not found, this will be returned. */ }; -static vx_char *find_zone_name(vx_enum zone) +vx_char *tivx_find_zone_name(vx_enum zone) { vx_uint32 i; @@ -74,23 +69,40 @@ static vx_char *find_zone_name(vx_enum zone) void tivx_set_debug_zone(vx_enum zone) { - if ( (0 <= zone) && (zone < (vx_enum)VX_ZONE_MAX) ) { + if ( (0 <= zone) && (zone < (vx_enum)VX_ZONE_MAX) ) + { + g_debug_zonemask |= ZONE_BIT((vx_uint32)zone); - tivx_print(zone, "Enabled\n"); + tivx_print_object(VX_ZONE_LOG, ~(0U), "Globally Enabled %s\n", tivx_find_zone_name(zone)); + } + else + { + VX_PRINT(VX_ZONE_ERROR,"Invalid debug zone specified\n"); } } void tivx_clr_debug_zone(vx_enum zone) { - if ( (0 <= zone) && (zone < (vx_enum)VX_ZONE_MAX) ) { - tivx_print(zone, "Disabled\n"); + if ( (0 <= zone) && (zone < (vx_enum)VX_ZONE_MAX) ) + { g_debug_zonemask &= ~(ZONE_BIT((vx_uint32)zone)); + tivx_print_object(VX_ZONE_LOG, ~(0U), "Globally Disabled %s\n", tivx_find_zone_name(zone)); + } + else + { + VX_PRINT(VX_ZONE_ERROR,"Invalid debug zone specified\n"); } } -vx_bool tivx_get_debug_zone(vx_enum zone) +vx_uint32 tivx_get_global_zonemask(void) +{ + return g_debug_zonemask; +} + +vx_bool tivx_is_zone_enabled(vx_enum zone) { vx_bool zone_enabled; + printf("Zone: %d\n", (uint32_t)g_debug_zonemask); if ( (0 <= zone) && (zone < (vx_enum)VX_ZONE_MAX) ) { @@ -103,21 +115,33 @@ vx_bool tivx_get_debug_zone(vx_enum zone) return zone_enabled; } -void tivx_print(vx_enum zone, const char *format, ...) +static void tivx_print(vx_enum zone, vx_uint32 debug_zonemask, const char *format, va_list ap) { - if ((g_debug_zonemask & ZONE_BIT((vx_uint32)zone)) != 0U) + if ((debug_zonemask & ZONE_BIT((vx_uint32)zone)) != 0U) { uint32_t size; char string[1024]; - va_list ap; - (void)memset(&ap, 0, sizeof(ap)); - (void)va_start(ap, format); - (void)snprintf(string, sizeof(string), " %s:", find_zone_name(zone)); + (void)snprintf(string, sizeof(string), " %s: ", tivx_find_zone_name(zone)); size = (uint32_t)strlen(string); + (void)vsnprintf(&string[size], sizeof(string)-size, format, ap); ownPlatformPrintf(string); - va_end(ap); } } +void tivx_print_global(vx_enum zone, const char *format, ...) +{ + va_list args; + va_start(args, format); + tivx_print(zone, g_debug_zonemask, format, args); + va_end(args); +} + +void tivx_print_object(vx_enum zone, vx_uint32 debug_zonemask, const char *format, ...) +{ + va_list args; + va_start(args, format); + tivx_print(zone, debug_zonemask, format, args); + va_end(args); +} diff --git a/source/framework/vx_graph.c b/source/framework/vx_graph.c index 856baedf4..8c2ef62dc 100644 --- a/source/framework/vx_graph.c +++ b/source/framework/vx_graph.c @@ -462,6 +462,7 @@ VX_API_ENTRY vx_graph VX_API_CALL vxCreateGraph(vx_context context) graph->num_delay_data_ref_q = 0; graph->num_supernodes = 0; graph->timeout_val = TIVX_DEFAULT_GRAPH_TIMEOUT; + graph->debug_zonemask = tivx_get_global_zonemask(); status = ownResetGraphPerf(graph); #ifdef LDRA_UNTESTABLE_CODE @@ -665,6 +666,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxQueryGraph(vx_graph graph, vx_enum attribut VX_API_ENTRY vx_status VX_API_CALL vxReleaseGraph(vx_graph *g) { + return ownReleaseReferenceInt(vxCastRefFromGraphP(g), (vx_enum)VX_TYPE_GRAPH, (vx_enum)VX_EXTERNAL, NULL); } @@ -945,12 +947,15 @@ vx_status ownGraphScheduleGraphWrapper(vx_graph graph) VX_API_ENTRY vx_status VX_API_CALL vxScheduleGraph(vx_graph graph) { vx_status status = (vx_status)VX_SUCCESS; + vx_uint32 graph_debug_zonemask; + + graph_debug_zonemask = graph->debug_zonemask; if(ownIsValidSpecificReference(vxCastRefFromGraph(graph), (vx_enum)VX_TYPE_GRAPH) != (vx_bool)vx_false_e) { if (graph->is_streaming_enabled != 0) { - VX_PRINT(VX_ZONE_ERROR, "graph is already streaming\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "graph is already streaming\n"); status = (vx_status)VX_ERROR_INVALID_REFERENCE; } else @@ -958,7 +963,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxScheduleGraph(vx_graph graph) if(graph->schedule_mode==(vx_enum)VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO) { status = (vx_status)VX_ERROR_NOT_SUPPORTED; - VX_PRINT(VX_ZONE_ERROR, "not supported for VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "not supported for VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO\n"); } else { @@ -968,7 +973,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxScheduleGraph(vx_graph graph) } else { - VX_PRINT(VX_ZONE_ERROR, "invalid graph reference\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "invalid graph reference\n"); status = (vx_status)VX_ERROR_INVALID_REFERENCE; } @@ -978,6 +983,9 @@ VX_API_ENTRY vx_status VX_API_CALL vxScheduleGraph(vx_graph graph) VX_API_ENTRY vx_status VX_API_CALL vxWaitGraph(vx_graph graph) { vx_status status = (vx_status)VX_SUCCESS; + vx_uint32 graph_debug_zonemask; + + graph_debug_zonemask = graph->debug_zonemask; if(ownIsValidSpecificReference(vxCastRefFromGraph(graph), (vx_enum)VX_TYPE_GRAPH) == (vx_bool)vx_true_e) @@ -999,18 +1007,18 @@ VX_API_ENTRY vx_status VX_API_CALL vxWaitGraph(vx_graph graph) } else { - VX_PRINT(VX_ZONE_ERROR, "tivxEventWait() failed.\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "tivxEventWait() failed.\n"); } } else { - VX_PRINT(VX_ZONE_ERROR, "graph not in expected state\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "graph not in expected state\n"); status = (vx_status)VX_ERROR_NOT_SUPPORTED; } } else { - VX_PRINT(VX_ZONE_ERROR, "invalid graph reference\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "invalid graph reference\n"); status = (vx_status)VX_ERROR_INVALID_REFERENCE; } @@ -1171,3 +1179,30 @@ vx_node tivxGraphGetNode(vx_graph graph, uint32_t idx) return node; } + +vx_status tivxGraphSetDebugZone(vx_graph graph, vx_uint32 debug_zone, vx_bool enable) +{ + vx_status status; + + if (debug_zone > (vx_enum)VX_ZONE_MAX) + { + VX_PRINT(VX_ZONE_ERROR, + "Invalid debug level specified (value greater than VX_ZONE_MAX): %d\n", + debug_zone); + status = (vx_status)VX_ERROR_INVALID_PARAMETERS; + } + else + { + uint32_t i; + + graph->debug_zonemask |= ZONE_BIT(debug_zone); + VX_PRINT_LOCAL(VX_ZONE_INFO, debug_zone, "Enabled %s for Graph\n", tivx_find_zone_name(debug_zone)); + for (i = 0; i < graph->num_nodes; i++) + { + tivxNodeSetDebugZone(graph->nodes[i], debug_zone, enable); + } + status = VX_SUCCESS; + } + + return status; +} diff --git a/source/framework/vx_graph_verify.c b/source/framework/vx_graph_verify.c index 65f906037..2fe616de2 100644 --- a/source/framework/vx_graph_verify.c +++ b/source/framework/vx_graph_verify.c @@ -2197,6 +2197,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) vx_status status = (vx_status)VX_SUCCESS; vx_meta_format meta[TIVX_KERNEL_MAX_PARAMS] = {NULL}; vx_bool first_time_verify = (vx_bool)vx_true_e; + vx_uint32 graph_debug_zonemask = 0; if (NULL != graph) { @@ -2205,7 +2206,8 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) } else { - VX_PRINT(VX_ZONE_ERROR,"Invalid graph reference\n"); + graph_debug_zonemask = graph->debug_zonemask; + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Invalid graph reference\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } @@ -2216,7 +2218,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* This should not fail at all */ if (vxGetStatus(vxCastRefFromMetaFormat(meta[i])) != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Unable to create meta format object\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Unable to create meta format object\n"); status = (vx_status)VX_ERROR_NO_RESOURCES; } } @@ -2233,7 +2235,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphNodeKernelDeinit(graph); if((vx_status)VX_SUCCESS != status) { - VX_PRINT(VX_ZONE_ERROR,"Graph Node kernel de-init failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Graph Node kernel de-init failed\n"); } } if(status == (vx_status)VX_SUCCESS) @@ -2244,7 +2246,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphCalcInAndOutNodes(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Unable to calculate out nodes and in nodes for each node\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Unable to calculate out nodes and in nodes for each node\n"); } else { @@ -2272,7 +2274,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) if(has_cycle != 0) { - VX_PRINT(VX_ZONE_ERROR,"Topological sort failed, due to cycles in graph\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Topological sort failed, due to cycles in graph\n"); status = (vx_status)VX_FAILURE; } } @@ -2294,7 +2296,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Node kernel Validate failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Node kernel Validate failed\n"); } } @@ -2316,7 +2318,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphValidatePipelineParameters(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Error in pipelining parameters\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Error in pipelining parameters\n"); } } @@ -2340,7 +2342,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphCalcHeadAndLeafNodes(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Find head nodes and leaf nodes failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Find head nodes and leaf nodes failed\n"); } } @@ -2352,7 +2354,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Find and add data references failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Find and add data references failed\n"); } #endif } @@ -2373,7 +2375,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphAllocateDataObjects(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Memory alloc for data objects failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Memory alloc for data objects failed\n"); } } @@ -2385,7 +2387,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* TIOVX-1808- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT020 */ if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Node pipelining failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Node pipelining failed\n"); } /* END: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT020 */ /*LDRA_ANALYSIS*/ @@ -2401,7 +2403,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphCreateNodeCallbackCommands(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Create node callback commands failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Create node callback commands failed\n"); } } @@ -2419,7 +2421,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* TIOVX-1808- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT021 */ if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Create data ref queues failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Create data ref queues failed\n"); } /* END: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT021 */ /*LDRA_ANALYSIS*/ @@ -2436,7 +2438,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphNodeKernelInit(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Node kernel init failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Node kernel init failed\n"); } } @@ -2448,7 +2450,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* TIOVX-1676- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UM030 */ if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Unable to update data ref queue refs for graph\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Unable to update data ref queue refs for graph\n"); } #endif } @@ -2461,7 +2463,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* TIOVX-1808- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT022 */ if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Unable to alloc obj desc for graph\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Unable to alloc obj desc for graph\n"); } /* END: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT022 */ /*LDRA_ANALYSIS*/ @@ -2473,7 +2475,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) status = ownGraphAllocForStreaming(graph); if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Unable to alloc streaming objects for graph\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Unable to alloc streaming objects for graph\n"); } } @@ -2485,7 +2487,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) /* TIOVX-1808- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT023 */ if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"If streaming is enabled, schedule mode must be normal\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "If streaming is enabled, schedule mode must be normal\n"); } /* END: TIOVX_CODE_COVERAGE_GRAPH_VERIFY_UTJT023 */ /*LDRA_ANALYSIS*/ @@ -2501,11 +2503,11 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) if(status != (vx_status)VX_SUCCESS) { - VX_PRINT(VX_ZONE_ERROR,"Graph verify failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Graph verify failed\n"); /* deinit kernel to recover resources */ if((vx_status)VX_SUCCESS != ownGraphNodeKernelDeinit(graph)) { - VX_PRINT(VX_ZONE_ERROR,"Grade node kernel de-init failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Grade node kernel de-init failed\n"); } } @@ -2516,7 +2518,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) } else { - VX_PRINT(VX_ZONE_ERROR,"Invalid graph reference\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Invalid graph reference\n"); status = (vx_status)VX_ERROR_INVALID_REFERENCE; } @@ -2526,7 +2528,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxVerifyGraph(vx_graph graph) { if((vx_status)VX_SUCCESS != ownReleaseMetaFormat(&meta[i])) { - VX_PRINT(VX_ZONE_ERROR,"Failed to release met-format object\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, graph_debug_zonemask, "Failed to release met-format object\n"); } } } diff --git a/source/framework/vx_node.c b/source/framework/vx_node.c index 87b753177..c398e0559 100644 --- a/source/framework/vx_node.c +++ b/source/framework/vx_node.c @@ -1544,6 +1544,7 @@ VX_API_ENTRY vx_node VX_API_CALL vxCreateGenericNode(vx_graph graph, vx_kernel k /* all condition successful for node creation, now set kernel, graph references */ node->kernel = kernel; node->graph = graph; + node->obj_desc[0]->debug_zonemask = node->graph->debug_zonemask; /* show that there are potentially multiple nodes using this kernel. */ (void)ownIncrementReference(&kernel->base, (vx_enum)VX_INTERNAL); @@ -1773,7 +1774,7 @@ VX_API_ENTRY vx_status VX_API_CALL vxQueryNode(vx_node node, vx_enum attribute, } else { - VX_PRINT(VX_ZONE_ERROR,"Query TIVX_NODE_TIMEOUT failed\n"); + VX_PRINT(VX_ZONE_ERROR,"Query TIVX_NODE_IS_TIMED_OUT failed\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; @@ -2508,6 +2509,7 @@ vx_status ownNodeAllocObjDescForPipeline(vx_node node, uint32_t pipeline_depth) tivx_obj_desc_memcpy(&obj_desc->border_mode, &obj_desc_0->border_mode, (uint32_t)sizeof(vx_border_t)); obj_desc->is_prm_replicated = obj_desc_0->is_prm_replicated; obj_desc->num_of_replicas = obj_desc_0->num_of_replicas; + obj_desc->debug_zonemask = obj_desc_0->debug_zonemask; /* copying data_id[], out_node_id[], in_node_id[] * from 0th obj desc but these are overriden later @@ -2669,3 +2671,57 @@ vx_status VX_API_CALL tivxGetNodeParameterNumBufByIndex(vx_node node, vx_uint32 } return status; } + +vx_status tivxNodeSetDebugZone(vx_node node, vx_uint32 debug_zone, vx_bool enable) +{ + vx_status status; + + if (debug_zone > (vx_enum)VX_ZONE_MAX) + { + VX_PRINT(VX_ZONE_ERROR, + "Invalid debug level specified (value greater than VX_ZONE_MAX): %d\n", + debug_zone); + status = (vx_status)VX_ERROR_INVALID_PARAMETERS; + } + else + { + if (enable == (vx_bool)vx_true_e) + { + uint32_t i; + + for (i = 0; i < TIVX_GRAPH_MAX_PIPELINE_DEPTH; i++) + { + if (node->obj_desc[i] != NULL) + { + node->obj_desc[i]->debug_zonemask |= ZONE_BIT(debug_zone); + } + else + { + break; + } + } + VX_PRINT_LOCAL(VX_ZONE_INFO, debug_zone, "Enabled %s for Node\n", tivx_find_zone_name(debug_zone)); + } + else + { + uint32_t i; + + for (i = 0; i < TIVX_GRAPH_MAX_PIPELINE_DEPTH; i++) + { + if (node->obj_desc[i] != NULL) + { + node->obj_desc[i]->debug_zonemask &= ~(ZONE_BIT(debug_zone)); + } + else + { + break; + } + } + VX_PRINT_LOCAL(VX_ZONE_INFO, debug_zone, "Disabled %s for Node\n", tivx_find_zone_name(debug_zone)); + } + + status = VX_SUCCESS; + } + + return status; +} diff --git a/source/framework/vx_target.c b/source/framework/vx_target.c index 28cb0fd41..ae3c45272 100644 --- a/source/framework/vx_target.c +++ b/source/framework/vx_target.c @@ -608,6 +608,9 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ uint64_t beg_time, end_time; uint16_t blocked_node_id = (vx_enum)TIVX_OBJ_DESC_INVALID; uint16_t prm_obj_desc_id[TIVX_KERNEL_MAX_PARAMS]; + uint32_t node_debug_zonemask; + + node_debug_zonemask = node_obj_desc->debug_zonemask; /* if node is already executed do nothing */ if( tivxFlagIsBitSet(node_obj_desc->flags,TIVX_NODE_FLAG_IS_EXECUTED) == (vx_bool)vx_false_e ) /* TIOVX-1930- LDRA Uncovered Branch Id: TIOVX_BRANCH_COVERAGE_TIVX_TARGET_UBR021 */ @@ -624,7 +627,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ is_node_blocked = (vx_bool)vx_false_e; - VX_PRINT(VX_ZONE_INFO,"Node (node=%d, pipe=%d) acquiring parameters on target %08x\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Node (node=%d, pipe=%d) acquiring parameters on target %08x\n", node_obj_desc->base.obj_desc_id, node_obj_desc->pipeline_id, target->target_id @@ -679,7 +682,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ if(is_node_blocked==(vx_bool)vx_false_e) { - VX_PRINT(VX_ZONE_INFO,"Node (node=%d, pipe=%d) executing on target %08x\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Node (node=%d, pipe=%d) executing on target %08x\n", node_obj_desc->base.obj_desc_id, node_obj_desc->pipeline_id, target->target_id @@ -695,7 +698,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ ownLogRtTraceNodeExeEnd(end_time, node_obj_desc); - VX_PRINT(VX_ZONE_INFO,"Node (node=%d, pipe=%d) executing on target %08x ... DONE !!!\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Node (node=%d, pipe=%d) executing on target %08x ... DONE !!!\n", node_obj_desc->base.obj_desc_id, node_obj_desc->pipeline_id, target->target_id @@ -721,7 +724,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ if((vx_enum)blocked_node_id!=(vx_enum)TIVX_OBJ_DESC_INVALID) { /* this will be same node in next pipeline to trigger it last */ - VX_PRINT(VX_ZONE_INFO,"Re-triggering (node=%d)\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Re-triggering (node=%d)\n", blocked_node_id ); ownTargetTriggerNode(blocked_node_id); @@ -729,7 +732,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ } else { - VX_PRINT(VX_ZONE_INFO,"Node (node=%d, pipe=%d) ... BLOCKED for resources on target %08x\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Node (node=%d, pipe=%d) ... BLOCKED for resources on target %08x\n", node_obj_desc->base.obj_desc_id, node_obj_desc->pipeline_id, target->target_id @@ -738,7 +741,7 @@ static void ownTargetNodeDescNodeExecute(tivx_target target, tivx_obj_desc_node_ } else { - VX_PRINT(VX_ZONE_INFO,"Node (node=%d, pipe=%d) ... BLOCKED for previous pipe instance node (node=%d) to complete !!!\n", + VX_PRINT_LOCAL(VX_ZONE_INFO, node_debug_zonemask, "Node (node=%d, pipe=%d) ... BLOCKED for previous pipe instance node (node=%d) to complete !!!\n", node_obj_desc->base.obj_desc_id, node_obj_desc->pipeline_id, node_obj_desc->prev_pipe_node_id @@ -758,6 +761,7 @@ static vx_status ownTargetNodeDescNodeCreate(tivx_obj_desc_node_t *node_obj_desc tivx_obj_desc_t *prm_obj_desc; tivx_obj_desc_kernel_name_t *kernel_name_obj_desc; volatile char *kernel_name = NULL; + vx_uint32 node_debug_zonemask; if (tivxFlagIsBitSet(node_obj_desc->flags,TIVX_NODE_FLAG_IS_REPLICATED) == (vx_bool)vx_true_e) @@ -765,6 +769,7 @@ static vx_status ownTargetNodeDescNodeCreate(tivx_obj_desc_node_t *node_obj_desc loop_max = (uint16_t)node_obj_desc->num_of_replicas; } + node_debug_zonemask = node_obj_desc->debug_zonemask; kernel_name_obj_desc = (tivx_obj_desc_kernel_name_t*)ownObjDescGet((uint16_t)node_obj_desc->kernel_name_obj_desc_id); if(kernel_name_obj_desc!=NULL) /* TIOVX-1930- LDRA Uncovered Branch Id: TIOVX_BRANCH_COVERAGE_TIVX_TARGET_UBR023 */ { @@ -779,7 +784,7 @@ static vx_status ownTargetNodeDescNodeCreate(tivx_obj_desc_node_t *node_obj_desc /* TIOVX-1671- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_TARGET_UM011 */ if(target_kernel_instance == NULL) { - VX_PRINT(VX_ZONE_ERROR, "target_kernel_instance is NULL\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "target_kernel_instance is NULL\n"); status = (vx_status)VX_ERROR_NO_RESOURCES; } else @@ -927,6 +932,9 @@ static vx_status ownTargetNodeDescNodeDelete(const tivx_obj_desc_node_t *node_ob vx_status status = (vx_status)VX_SUCCESS; uint16_t i, cnt, loop_max = 1; tivx_obj_desc_t *params[TIVX_KERNEL_MAX_PARAMS]; + vx_uint32 node_debug_zonemask; + + node_debug_zonemask = node_obj_desc->debug_zonemask; if (tivxFlagIsBitSet(node_obj_desc->flags,TIVX_NODE_FLAG_IS_REPLICATED) == (vx_bool)vx_true_e) @@ -943,7 +951,7 @@ static vx_status ownTargetNodeDescNodeDelete(const tivx_obj_desc_node_t *node_ob /* TIOVX-1671- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_TARGET_UM014 */ if(target_kernel_instance == NULL) { - VX_PRINT(VX_ZONE_ERROR, "target_kernel_instance is NULL\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "target_kernel_instance is NULL\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } else @@ -1022,6 +1030,9 @@ static vx_status ownTargetNodeDescNodeControl( { vx_status status = (vx_status)VX_SUCCESS; uint16_t cnt, loop_max = 1; + vx_uint32 node_debug_zonemask; + + node_debug_zonemask = node_obj_desc->debug_zonemask; if (tivxFlagIsBitSet(node_obj_desc->flags,TIVX_NODE_FLAG_IS_REPLICATED) == (vx_bool)vx_true_e) @@ -1039,7 +1050,7 @@ static vx_status ownTargetNodeDescNodeControl( /* TIOVX-1671- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_TARGET_UM017 */ if ((vx_status)VX_SUCCESS != status) { - VX_PRINT(VX_ZONE_ERROR, "SendCommand Failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "SendCommand Failed\n"); break; } #endif @@ -1057,12 +1068,12 @@ static vx_status ownTargetNodeDescNodeControl( node_obj_desc); if ((vx_status)VX_SUCCESS != status) { - VX_PRINT(VX_ZONE_ERROR, "SendCommand Failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "SendCommand Failed\n"); } } else { - VX_PRINT(VX_ZONE_ERROR, "Incorrect node id\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "Incorrect node id\n"); status = (vx_status)VX_FAILURE; } } @@ -1076,7 +1087,7 @@ static vx_status ownTargetNodeDescNodeControl( /* TIOVX-1671- LDRA Uncovered Id: TIOVX_CODE_COVERAGE_TARGET_UM018 */ if ((vx_status)VX_SUCCESS != status) { - VX_PRINT(VX_ZONE_ERROR, "SendCommand Failed\n"); + VX_PRINT_LOCAL(VX_ZONE_ERROR, node_debug_zonemask, "SendCommand Failed\n"); } #endif } diff --git a/source/framework/vx_target_kernel_instance.c b/source/framework/vx_target_kernel_instance.c index 2ce09b6e2..9a03ee2bd 100644 --- a/source/framework/vx_target_kernel_instance.c +++ b/source/framework/vx_target_kernel_instance.c @@ -253,6 +253,10 @@ tivx_target_kernel_instance ownTargetKernelInstanceGet(uint16_t target_kernel_in return target_kernel_instance; } +vx_uint32 tivxGetTargetKernelInstanceDebugZonemask(tivx_target_kernel_instance kernel) +{ + return kernel->node_obj_desc->debug_zonemask; +} VX_API_ENTRY vx_status VX_API_CALL tivxSetTargetKernelInstanceContext( tivx_target_kernel_instance target_kernel_instance, diff --git a/source/include/tivx_debug.h b/source/include/tivx_debug.h new file mode 100644 index 000000000..c73688bbc --- /dev/null +++ b/source/include/tivx_debug.h @@ -0,0 +1,82 @@ +/* +* +* Copyright (c) 2024 Texas Instruments Incorporated +* +* All rights reserved not granted herein. +* +* Limited License. +* +* Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive +* license under copyrights and patents it now or hereafter owns or controls to make, +* have made, use, import, offer to sell and sell ("Utilize") this software subject to the +* terms herein. With respect to the foregoing patent license, such license is granted +* solely to the extent that any such patent is necessary to Utilize the software alone. +* The patent license shall not apply to any combinations which include this software, +* other than combinations with devices manufactured by or for TI ("TI Devices"). +* No hardware patent is licensed hereunder. +* +* Redistributions must preserve existing copyright notices and reproduce this license +* (including the above copyright notice and the disclaimer and (if applicable) source +* code license limitations below) in the documentation and/or other materials provided +* with the distribution +* +* Redistribution and use in binary form, without modification, are permitted provided +* that the following conditions are met: +* +* * No reverse engineering, decompilation, or disassembly of this software is +* permitted with respect to any software provided in binary form. +* +* * any redistribution and use are licensed by TI for use only with TI Devices. +* +* * Nothing shall obligate TI to provide you with source code for the software +* licensed and provided to you in object code. +* +* If software source code is provided to you, modification and redistribution of the +* source code are permitted provided that the following conditions are met: +* +* * any redistribution and use of the source code, including any resulting derivative +* works, are licensed by TI for use only with TI Devices. +* +* * any redistribution and use of any object code compiled from the source code +* and any resulting derivative works, are licensed by TI for use only with TI Devices. +* +* Neither the name of Texas Instruments Incorporated nor the names of its suppliers +* +* may be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* DISCLAIMER. +* +* THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS +* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +* OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +#ifndef TIVX_DEBUG_H_ +#define TIVX_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZONE_BIT(zone) ((vx_uint32)1U << (zone)) + +/*! \brief Internal function - returns the global debug zone bitmask + * \param [out] vx_uint32 The global debug zone bitmask + * \ingroup group_vx_debug + */ +vx_uint32 own_get_global_zonemask(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/include/vx_graph.h b/source/include/vx_graph.h index 77a44d714..4bf77b146 100755 --- a/source/include/vx_graph.h +++ b/source/include/vx_graph.h @@ -254,6 +254,9 @@ typedef struct _vx_graph { /*! \brief Control API processing Timeout value in milli-sec. */ vx_uint32 timeout_val; + /*! \brief Debug zonemask of a given graph. */ + vx_uint32 debug_zonemask; + } tivx_graph_t; diff --git a/source/include/vx_internal.h b/source/include/vx_internal.h index 9bf48afe3..c1eca5c87 100755 --- a/source/include/vx_internal.h +++ b/source/include/vx_internal.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/source/include/vx_node.h b/source/include/vx_node.h index 14d66ebf5..cdf595f03 100644 --- a/source/include/vx_node.h +++ b/source/include/vx_node.h @@ -121,10 +121,10 @@ typedef struct _vx_node { tivx_super_node super_node; /*! \brief Control API processing Timeout value in milli-sec. */ - vx_uint32 timeout_val; + vx_uint32 timeout_val; /*! \brief Depth of a given node. */ - vx_uint32 node_depth; + vx_uint32 node_depth; } tivx_node_t; diff --git a/source/platform/pc/common/tivx_init.c b/source/platform/pc/common/tivx_init.c index b91bb3f8f..998612005 100644 --- a/source/platform/pc/common/tivx_init.c +++ b/source/platform/pc/common/tivx_init.c @@ -194,6 +194,9 @@ void tivxInit(void) ownPlatformCreateTargets(); VX_PRINT(VX_ZONE_INIT, "Initialization Done !!!\n"); + + tivx_clr_debug_zone(VX_ZONE_INIT); + tivx_clr_debug_zone(VX_ZONE_WARNING); } g_init_status++;