Some questions about condition of using OpenVX

Hi,

For my understanding, OpenVX is an library can support hardware acceleration.
Just like OpenGL and GPU for 3D rendering.
But how can I choose DSP for computer vision computation?
If I develop an algorithm of computer vision by openCV. Is openVX supporting for porting on DSP?
If it’s true. I need to execute an application by openVX for hardware acceleration by DSP?
Above denote the condition about how to use for my understanding. Please teach me for correct concept.
Thanks,

Great Question!

First, your vendor must provide an implementation that supports the hardware.

Second, the implementation will likely choose the best hardware for you at the time of execution. It may think one core is better than another due to some internal heuristic (power, load balancing, etc). However, you can override this. Choosing any target (CPU/DSP/GPU/Accelerator, etc) is done on a per-Node basis in the Graph. If you want to assign all your Nodes, it would handy to keep all the node handles in an array. Assignment is done with the “vxAssignNode” function, which takes the node reference and target reference. To get those, you need to create a node first and find the target you want.

The helper library has a function to find a target by name, but it’s really just finding all targets and doing a string compare against their names, which the users could do too.

Here’s a complete example:


vx_context context = vxCreateContext();
vx_image images[] = {vxCreateImage(context, 640, 480, FOURCC_U8), 
    vxCreateImage(context, 640,480,FOURCC_S16),
    vxCreateImage(context, 640,480,FOURCC_S16),
};
vx_uint32 num_images = sizeof(images)/sizeof(images[0]);
vx_graph graph = vxCreateGraph(context);
vx_node nodes[] = {
    vxSobel3x3Node(graph, images[0], images[1], images[2]),
    /* add more nodes here */
};
vx_uint32 num_nodes = sizeof(nodes)/sizeof(nodes[0]);

/* from the vx_helper library (with made up name) */
vx_target target = vxFindTarget(context, "vendor.dsp.xxxx");

/* fail if the target doesn't exist */

vx_status status = VX_FAILURE;
for (vx_uint32 i = 0u;  i < num_nodes && status == VX_SUCCESS; i++) {
    status = vxAssignNode(nodes[i], target); /* now that node will execute on the DSP. */
    /* check status to see if the assigned target supports the node */
}

status = vxVerifyGraph(graph);
/* check status */
status = vxProcessGraph(graph); /* code will execute in here on DSP */

/* teardown */
for (vx_uint32 i = 0u; i < num_nodes; i++)
    vxReleaseNode(&nodes[i]);
for (vx_uint32 i = 0u; i < num_images; i++)
    vxReleaseImage(&images[i]);
vxReleaseGraph(&graph);
vxReleaseTarget(&target);
vxReleaseContext(&context);

Hi, Emrainey

Thanks for your answer.
I think I have more concept about OpenVX by your explanation.

So finally, I need to find a DSP of vendor(like TI provide), and TI’s DSP may support simple computation of computer vision(like OpenCV function).
When I develop my algorithm of computer vision, OpenVX will transfer the simple computation of computer vision to DSP.(this step include memory hierarchy arrangement for hardware computation)

The other work will still process by CPU. This aspect, which OS should we choose for using OpenVX?

And how can I know the computations are transfer to DSP for hardware acceleration successful? (like the target detection. If I detect the target exist, but this target may not support some computation.)

Thanks.

1.) OS Choice is up to the vendor and the customer. I can’t announce any specific OS support at this time on behalf of TI, though we are working on some.

2.) To know how a node executed successfully on any target, just check the return value of the calls.


status = vxAssignNode(node, target);
/* if not VX_SUCCESS, didn't assign */
status = vxProcessGraph(graph);
/* if not VX_SUCCESS, some error happened */

3.) To find all kernels that a target supports, you just open each target, find all the kernel it supports and it will print them out. The code to do something like this is here:


vx_context context = vxCreateContext();
vx_uint32 targets = 0u, kernels = 0u;
vxQueryContext(context, VX_CONTEXT_ATTRIBUTE_NUMTARGETS, &targets, sizeof(targets));
for (vx_uint32 t = 0u; i < targets; i++)
{
    vx_char targetname[VX_MAX_TARGET_NAME];
    vx_target target = vxGetTargetByIndex(context, t);
    vx_target_kernel_t *table = NULL;
    vxQueryTarget(target, VX_TARGET_ATTRIBUTE_NAME, targetname, sizeof(targetname));
    vxQueryTarget(target, VX_TARGET_ATTRIBUTE_NUMKERNELS, &kernels, sizeof(kernels));
    table = calloc(kernels, sizeof(*table));
    vxQueryTarget(target, VX_TARGET_ATTRIBUTE_KERNELTABLE, table, sizeof(*table)*kernels);
    for (vx_uint32 k = 0; k < kernels && table != NULL; k++)
    {
        vx_kernel kernel = vxGetKernelByName(context, table[k].name);
        if (kernel) {
            /* print or do whatever with the kernel info */
            vxReleaseKernel(&kernel);
        }
    }
    if (table) free(table);
    vxReleaseTarget(&target);
}
vxReleaseContext(&context);

The sample implementation will come with an example tool, “vx_query” which will do exactly this.