TIOVX User Guide
PyTIOVX User Guide

Overview

The PyTIOVX Tool allows users to generate an OpenVX extension kernel wrapper by specifying parameters of the kernel and setting relationships between these parameters.

'tiovx' is the python module that is used to specify OpenVX graph in a compact manner using predefined classes and objects. After specification of OpenVX graph using PyTIOVX APIs, it can be exported in various formats including C code, JPG image

Installation

  • Install Python 3.5.2 or later (https://www.python.org/)
    • To confirm "python" and "pip" are in your install path, type below
      python3 --version
      pip3 --version
  • Install 'dot' tool provided as part of 'graphviz' (http://www.graphviz.org/)
    'dot' is required to generated .JPG file for a OpenVX graph specification
    • To confirm "dot" tool is in your install path, type
      dot -V
  • Install 'tiovx' python module by executing below command at folder "<tiovx install path>/tools/PyTIOVX"
    sudo pip3 install -e .
    Expected output,
    Obtaining file:///<tiovx install path>/tiovx/tools/PyTIOVX
    Installing collected packages: tiovx
    Running setup.py develop for tiovx
    Successfully installed tiovx-0.1
  • Now tiovx python module can be imported and used in your python script by doing below,
    from tiovx import *

Usage

  • Describe your application graph or kernel wrapper using PyTIOVX APIs in a .py file. Execute the .py file by invoking python
    python my_kernel_wrapper.py
    Note: if the following error is observed, please run using the command "python3.5 my_use_case.py"
    Traceback (most recent call last):
    File "kernel_generate_example.py", line 6, in <module>
    from tiovx import *
    File "tiovx/__init__.py", line 63, in <module>
    from .enums import *
    File "tiovx/tools/PyTIOVX/tiovx/enums.py", line 62, in <module>
    from enum import Enum
    ImportError: No module named enum
  • See also examples in TIOVX tutorial [HTML] for making OpenVX usecases using PyTIOVX tool
  • See also sample python scripts (*.py) @ "<tiovx install path>/tools/sample_use_cases" for additional examples

Kernel Generation

Example Kernel Generation Python Script
  • Below is an example of a Python script used for generating a custom Channel Extract kernel:
    from tiovx import *
    code = KernelExportCode(Module.IMAGING, Core.C66, "CUSTOM_APPLICATION_PATH")
    code.setCoreDirectory("c66")
    kernel = Kernel("channel_extract")
    kernel.setParameter(Type.IMAGE, Direction.INPUT, ParamState.REQUIRED, "IN", ['VX_DF_IMAGE_U8'])
    kernel.setParameter(Type.ENUM, Direction.INPUT, ParamState.REQUIRED, "CHANNEL")
    kernel.setParameter(Type.IMAGE, Direction.OUTPUT, ParamState.REQUIRED, "OUT", ['VX_DF_IMAGE_U8'])
    kernel.setParameterRelationship(["IN", "OUT"], [Attribute.Image.WIDTH, Attribute.Image.HEIGHT])
    kernel.allocateLocalMemory("img_scratch_mem", ["width*height"], "IN")
    kernel.setTarget(Target.DSP1)
    kernel.setTarget(Target.DSP2)
    code.export(kernel)
  • The constructor for the KernelExportCode API contains arguments that serve as the directory paths of the generated code.
    • The first argument, Module.IMAGING, is the intended module of the kernel. A full list of modules are contained with the module.py file of PyTIOVX. If the name of the module needed is not listed, either the module can be added to the module.py file or the module name can be passed as a string to the constructor.
    • The second argument, Core.C66 is the specific core that this kernel will run on. Similar to the module name, a list of core values are listed in core.py. If the name of the core needed is not listed, either the core can be added to the core.py file or the core name can be passed as a string to the constructor.
    • The third argument "CUSTOM_APPLICATION_PATH" is the path where the output files will be exported to.
      • Note: this path must be set as an environment variable by using "export" or else an error will be thrown.
    • The constructor has two optional arguments, include_subpath and include_filename.
      • The include_subpath should be set to the string value of the company name of the developer and defaults to "TI".
      • The include_filename contains the path name to the include file. By default, this value is set an empty string which results in the filepath being set to "<lowercase(include_subpath)>vx_<module>". However, the filepath can be overwritten by filling in this optional parameter.
  • Several dedicated API's are provided in the case that certain parameters of KernelExportCode must be changed during execution of the script. This example shows one such API, setCoreDirectory. This method can change the intended core by passing in a particular core as its only argument.
  • The constructor for the Kernel class contains as its only argument the name of the kernel to be created.
  • Parameters of a kernel are set via the setParameter API as in the example above. In this example, 3 parameters are set, an input image, an input scalar enum and an output image.
  • The following are arguments of the setParameter method:
    • The first argument is the OpenVX data type of the parameter. Allowed values can be found in enums.py.
    • The second argument is the direction of the parameter. Allowed values are Direction.INPUT or Direction.OUTPUT.
    • The third argument determines whether the parameter is required or optional. Allowed values are ParamState.REQUIRED or ParamState.OPTIONAL.
    • The fourth argument allows you to provide a name for the new parameter. This argument accepts a string value as the input. For instance, if this object is an input image, you may want to give it the argument "IN_IMAGE".
    • The fifth argument is optional and defines a set of allowed data types of the parameter. These are given as OpenVX data types as defined in the OpenVX 1.1 specification and are given as a comma separated list.
    • For further information, please refer to the API guide here PyTIOVX APIs.
  • After setting all parameters via the setParameter method, relationships among these parameters can be set via the setParameterRelationship method. This method is designed to ouput code in the validation callback to verify equality between certain attributes of parameters of the kernel. This validation of parameters is important in order no run-time errors of the kernel.
  • In this case, a relationship is set between the width and height of the "IN" and "OUT" parameters. This will produce code in the kernel validate callback that first queries the "IN" and "OUT" parameters for the width and height then checks for equality between the width of the "IN" parameter against the width of the "OUT" parameter in addition to checking for the equality between the height of the "IN" parameter against the height of the "OUT" parameter.
  • The allocateLocalMemory method is used to generate OpenVX code for allocating and free-ing local memory based on characteristics of existing data objects or on constant values. In this example, the allocateLocalMemory method is used to create a buffer with the name "img_scratch_mem" and is equal to the size of the width * height of the image, "IN". For further information, please refer to the API guide.
  • The list of targets for the kernel to run on can be set via the setTarget API. All possible targets that the kernel could run on should be given as arguments to this API. In this example, the target kernel is can be run on either DSP1 or DSP2 and therefore the setTarget API is called twice with each argument given. Allowed target values are given in enums.py.
  • After setting up all parameters and targets of the kernel, the kernel wrappers can be generated by running the export method.
  • Further documentation of the API's used for kernel code generation can be found here
Generated Kernel Code Overview
  • This section describes the generated files based on the example given above.
  • Based on whether the code generation path is set to CUSTOM_APPLICATION_PATH or VISION_APPS_PATH, the kernel files are generated in different locations.
  • The files that are generated the first time only are noted.
    custom_application_path.png
    <CUSTOM_APPLICATION_PATH>/DEVELOPER_TODO.txt (generated first time only)
    <CUSTOM_APPLICATION_PATH>/concerto_inc.mak
    <CUSTOM_APPLICATION_PATH>/custom_tools_path.mak
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/include/TI/tivx_imaging.h (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/include/TI/tivx_imaging_kernels.h (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/include/TI/tivx_imaging_nodes.h (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/c66/concerto.mak (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/c66/vx_channel_extract_target.c
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/c66/vx_kernels_imaging_target.c (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/host/concerto.mak (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/tivx_imaging_node_api.c (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/host/vx_channel_extract_host.c
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/host/vx_kernels_imaging_host.c (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/include/tivx_imaging_kernels.h (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/include/tivx_kernel_channel_extract.h
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/test/concerto.mak (generated first time only)
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/test/test_main.h (generated first time only)
  • If the final argument was changed to VISION_APPS_PATH, the following files are produced:
    vision_apps_path.png
    <VISION_APPS_PATH>/kernels/DEVELOPER_TODO.txt (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/include/TI/tivx_imaging.h (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/include/TI/tivx_imaging_kernels.h (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/include/TI/tivx_imaging_nodes.h (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/c66/concerto.mak (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/c66/vx_channel_extract_target.c
    <VISION_APPS_PATH>/kernels/imaging/c66/vx_kernels_imaging_target.c (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/host/concerto.mak (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/tivx_imaging_node_api.c (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/host/vx_channel_extract_host.c
    <VISION_APPS_PATH>/kernels/imaging/host/vx_kernels_imaging_host.c (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/include/tivx_imaging_kernels.h (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/include/tivx_kernel_channel_extract.h
    <VISION_APPS_PATH>/kernels/imaging/test/concerto.mak (generated first time only)
    <VISION_APPS_PATH>/kernels/imaging/test/test_main.h (generated first time only)
  • As noted, the majority of the generated files are only generated once per kernel module. These files contain boilerplate code needed for registering/unregistering the new kernels and node creation.
  • In the case that the module already exists, code will simply be appended to the existing files rather than duplicating any previously generated files.
Overview of Necessary Kernel Code Modifications
  • In addition to the code generated by the python script, a text file called "DEVELOPER_TODO.txt" is generated that provides information regarding the changes to be made to the generated files.
  • The two files wherein most modifications will occur are the host and target kernel files. The files for the given example are listed below:
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/c66/vx_channel_extract_target.c
    <CUSTOM_APPLICATION_PATH>/kernels/imaging/host/vx_channel_extract_host.c
  • The host kernel file must be modified in the following ways:
    • Validate callback: Additional custom parameter checking may need to be added to the validate callback. The script will generate parameter checking for attributes of parameters that are equal. Additional checking beyond the scope of the script must be entered in manually by the user. For example, in the case of a kernel with a scaled output, the validate callback should verify that the output is dimensions are scaled properly from the input. This type of check will most likely first require querying a given kernel parameter as specified by the OpenVX API designated for querying the given parameter. At this point the value can be verified against a known quantity. This step of proper validation catches errors during the verification stage and is important within the context of OpenVX to ensure no errors during execution of the graph.
    • Initialize callback: Appropriate valid region padding values must be added to the initialize callback to support the UNDEFINED border mode in the case that the data type in question is an image. These values will be determined by whether or not the generated kernel contains a region-based operation. For example, in the case that the kernel in question is a 3x3 filter, the padding for the top, bottom, left and right will all be a value of '1'. In the case that no region-based operations are performed, these values can be set to '0'.
  • The target kernel file must be modified in the following ways:
    • Create callback: The create callback is run once upon verification of the graph and should include allocation of any required local memory buffers as well as any one time initialization required for the kernel.
    • Delete callback: The delete callback is run upon release of the graph and should include the freeing of local memory buffers that were allocated within the create callback as well as any deinitialization of parameters that were initialized in the create callback.
    • Process callback: The process callback is run upon each execution of the graph and should include a call to the kernel process function. For example, in the case of OpenVX core kernels, the process callback contains a call to the optimized VXLIB function that performs the operation of the kernel.
    • Control callback: The control callback is run upon a user command to the kernel at run-time. It should include the processing of this user command and the operation necessary to modify the operation of the kernel.
  • Within the generated test folder, the test_main.h and concerto allows for simple integration into the TIOVX test framework. However, the test case itself must be developed. For test case references, please refer to tiovx/conformance_tests/