The OpenVX Specification  a73e458
Design Overview

# Software Landscape

OpenVX is intended to be used either directly by applications or as the acceleration layer for higher-level vision frameworks, engines or platform APIs.

OpenVX Usage Overview

# Design Objectives

OpenVX is designed as a framework of standardized computer vision functions able to run on a wide variety of platforms and potentially to be accelerated by a vendor's implementation on that platform. OpenVX can improve the performance and efficiency of vision applications by providing an abstraction for commonly-used vision functions and an abstraction for aggregations of functions (a “graph”), thereby providing the implementer the opportunity to minimize the run-time overhead.

The functions in OpenVX are intended to cover common functionality required by many vision applications.

## Hardware Optimizations

This specification makes no statements as to which acceleration methodology or techniques may be used in its implementation. Vendors may choose any number of implementation methods such as parallelism and/or specialized hardware offload techniques.

This specification also makes no statement or requirements on a “level of performance” as this may vary significantly across platforms and use cases.

## Hardware Limitations

The OpenVX focuses on vision functions that can be significantly accelerated by diverse hardware. Future versions of this specification may adopt additional vision functions into the core standard when hardware acceleration for those functions becomes practical.

# Assumptions

## Portability

OpenVX has been designed to maximize functional and performance portability wherever possible, while recognizing that the API is intended to be used on a wide diversity of devices with specific constraints and properties. Tradeoffs are made for portability where possible: for example, portable Graphs constructed using this API should work on any OpenVX implementation and return similar results within the precision bounds defined by the OpenVX conformance tests.

## Opaqueness

OpenVX is intended to address a very broad range of devices and platforms, from deeply embedded systems to desktop machines and distributed computing architectures. The OpenVX API addresses this range of possible implementations without forcing hardware-specific requirements onto any particular implementation via the use of opaque objects for most program data.

All data, except client-facing structures, are opaque and hidden behind a reference that may be as thin or thick as an implementation needs. Each implementation provides the standardized interfaces for accessing data that takes care of specialized hardware, platform, or allocation requirements. Memory that is imported or shared from other APIs is not subsumed by OpenVX and is still maintained and accessible by the originator.

OpenVX does not dictate any requirements on memory allocation methods or the layout of opaque memory objects and it does not dictate byte packing or alignment for structures on architectures.

# Object-Oriented Behaviors

OpenVX objects are both strongly typed at compile-time for safety critical applications and are strongly typed at run-time for dynamic applications. Each object has its typedef'd type and its associated enumerated value in the The VX_TYPE Constants list. Any object may be down-cast to a vx_reference safely to be used in functions that require this, specifically vxQueryReference, which can be used to get the The VX_TYPE Constants value using an vx_enum.

# OpenVX Framework Objects

This specification defines the following OpenVX framework objects.

• Object: Context - The OpenVX context is the object domain for all OpenVX objects. All data objects live in the context as well as all framework objects. The OpenVX context keeps reference counts on all objects and must do garbage collection during its deconstruction to free lost references. While multiple clients may connect to the OpenVX context, all data are private in that the references that refer to data objects are given only to the creating party. The results of calling an OpenVX function on data objects created in different contexts are undefined.
• Object: Kernel - A Kernel in OpenVX is the abstract representation of a computer vision function, such as a “Sobel Gradient” or “Lucas Kanade Feature Tracking”. A vision function may implement many similar or identical features from other functions, but it is still considered a single, unique kernel as long as it is named by the same string and enumeration and conforms to the results specified by OpenVX. Kernels are similar to function signatures in this regard.
• Object: Parameter - An abstract input, output, or bidirectional data object passed to a computer vision function. This object contains the signature of that parameter's usage from the kernel description. This information includes:
• Signature Index - The numbered index of the parameter in the signature.
• Object Type - e.g. VX_TYPE_IMAGE, or VX_TYPE_ARRAY, or some other object type from The VX_TYPE Constants.
• Usage Model - e.g. VX_INPUT, VX_OUTPUT, or VX_BIDIRECTIONAL.
• Presence State - e.g. VX_PARAMETER_STATE_REQUIRED, or VX_PARAMETER_STATE_OPTIONAL.
• Object: Node - A node is an instance of a kernel that will be paired with a specific set of references (the parameters). Nodes are created from and associated with a single graph only. When a vx_parameter is extracted from a Node, an additional attribute can be accessed:
• Reference - The vx_reference assigned to this parameter index from the Node creation function (e.g., vxSobel3x3Node).
• Object: Graph - A set of nodes connected in a directed (only goes one-way) acyclic (does not loop back) fashion. A Graph may have sets of Nodes that are unconnected to other sets of Nodes within the same Graph. See Graph Formalisms.

# OpenVX Data Objects

Data objects are object that are processed by graphs in nodes.

• Object: Array An opaque array object that could be an array of primitive data types or an array of structures.
• Object: Convolution An opaque object that contains $$MxN$$ matrix of vx_int16 values. Also contains a scaling factor for normalization. Used specifically with vxConvolveNode.
• Object: Delay An opaque object that contains a manually controlled, temporally-delayed list of objects.
• Object: Distribution An opaque object that contains a frequency distribution (e.g., a histogram).
• Object: Image An opaque image object that may be some format in Image Type Constants.
• Object: LUT An opaque lookup table object used with vxTableLookupNode.
• Object: Matrix An opaque object that contains $$MxN$$ matrix of some scalar values.
• Object: Pyramid An opaque object that contains multiple levels of scaled vx_image objects.
• Object: Remap An opaque object that contains the map of source points to destination points used to transform images.
• Object: Scalar An opaque object that contains a single primitive data type.
• Object: Threshold An opaque object that contains the thresholding configuration.
• Object: ObjectArray An opaque array object that could be an array of any data-object (not data-type) of OpenVX except Delay and ObjectArray objects.

# Error Objects

Error objects are specialized objects that may be returned from other object creator functions when serious platform issue occur (i.e., out of memory or out of handles). These can be checked at the time of creation of these objects, but checking also may be put-off until usage in other APIs or verification time, in which case, the implementation must return appropriate errors to indicate that an invalid object type was used.

vx_<object> obj = vxCreate<Object>(context, ...);
if (status == VX_SUCCESS) {
// object is good
}

# Graphs Concepts

The graph is the central computation concept of OpenVX. The purpose of using graphs to express the Computer Vision problem is to allow for the possibility of any implementation to maximize its optimization potential because all the operations of the graph and its dependencies are known ahead of time, before the graph is processed.

Graphs are composed of one or more nodes that are added to the graph through node creation functions. Graphs in OpenVX must be created ahead of processing time and verified by the implementation, after which they can be processed as many times as needed.

Graph Nodes are linked together via data dependencies with no explicitly-stated ordering. The same reference may be linked to other nodes. Linking has a limitation, however, in that only one node in a graph may output to any specific data object reference. That is, only a single writer of an object may exist in a given graph. This prevents indeterminate ordering from data dependencies. All writers in a graph shall produce output data before any reader of that data accesses it.

## Virtual Data Objects

Graphs in OpenVX depend on data objects to link together nodes. When clients of OpenVX know that they do not need access to these intermediate data objects, they may be created as virtual. Virtual data objects can be used in the same manner as non-virtual data objects to link nodes of a graph together; however, virtual data objects are different in the following respects.

• Inaccessible - No calls to an Map/Unmap or Copy APIs shall succeed given a reference to an object created through a virtual create function from a Graph external perspective. Calls to Map/Unmap or Copy APIs from within client-defined node that belongs to the same graph as the virtual object will succeed as they are Graph internal.
• Scoped - Virtual data objects are scoped within the Graph in which they are created; they cannot be shared outside their scope. The live range of the data content of a virtual data object is limited to a single graph execution. In other word, data content of a virtual object is undefined before graph execution and no data of a virtual object should be expected to be preserved across successive graph executions by the application.
• Intermediates - Virtual data objects should be used only for intermediate operations within Graphs, because they are fundamentally inaccessible to clients of the API.
• Dimensionless or Formatless - Virtual data objects may have dimensions and formats partially or fully undefined at creation time. For instance, a virtual image can be created with undefined or partially defined dimensions (0x0, Nx0 or 0xN where N is not null) and/or without defined format (VX_DF_IMAGE_VIRT). The undefined property of the virtual object at creation time is undefined with regard to the graph and mutable at graph verification time; it will be automatically adjusted at each graph verification, deduced from the node that outputs the virtual object. Dimensions and format properties that are well defined at virtual object creation time are immutable and can't be adjusted automatically at graph verification time. The Dimensionless or Formatless aspect of virtual data is a commodity that allows creating graphs generic with regard to dimensions or format, but there are restrictions:
1. Nodes may require the dimensions and/or the format to be defined for a virtual output object when it can't be deduced from its other parameters. For example, a Scale node requires well defined dimensions for the output image, while ColorConvert and ChannelCombine nodes require a well defined format for the output image.
2. An image created from ROI must always be well defined (vx_rectangle_t parameter) and can't be created from a dimensionless virtual image.
3. A ROI of a formatless virtual image shouldn't be a node output.
4. Levels of a dimensionless or formatless virtual pyramid shouldn't be a node output.
• Inheritance - A sub-object inherits from the virtual property of its parent. A sub-object also inherits from the Dimensionless or Formatless property of its parent with restrictions:
1. it is adjusted automatically at graph verification when the parent properties are adjusted (the parent is the output of a node)
2. it can't be adjusted at graph verification when the sub-object is itself the output of a node.
• Optimizations - Virtual data objects do not have to be created during Graph validation and execution and therefore may be of zero size.

These restrictions enable vendors the ability to optimize some aspects of the data object or its usage. Some vendors may not allocate such objects, some may create intermediate sub-objects of the object, and some may allocate the object on remote, inaccessible memories. OpenVX does not proscribe which optimization the vendor does, merely that it may happen.

## Node Parameters

Parameters to node creation functions are defined as either atomic types, such as vx_int32, vx_enum, or as objects, such as vx_scalar, vx_image. The atomic variables of the Node creation functions shall be converted by the framework into vx_scalar references for use by the Nodes. A node parameter of type vx_scalar can be changed during the graph execution; whereas, a node parameter of an atomic type (vx_int32 etc.) require at least a graph revalidation if changed. All node parameter objects may be modified by retrieving the reference to the vx_parameter via vxGetParameterByIndex, and then passing that to vxQueryParameter to retrieve the reference to the object.

vxQueryParameter(param, VX_PARAMETER_REF, &ref, sizeof(ref));

If the type of the parameter is unknown, it may be retrieved with the same function.

vx_enum type;
vxQueryParameter(param, VX_PARAMETER_TYPE, &type, sizeof(type));
/* cast the ref to the correct vx_<type>. Atomics are now vx_scalar */

## Graph Parameters

Parameters may exist on Graphs, as well. These parameters are defined by the author of the Graph and each Graph parameter is defined as a specific parameter from a Node within the Graph using vxAddParameterToGraph. Graph parameters communicate to the implementation that there are specific Node parameters that may be modified by the client between Graph executions. Additionally, they are parameters that the client may set without the reference to the Node but with the reference to the Graph using vxSetGraphParameterByIndex. This allows for the Graph authors to construct Graph Factories. How these factories work falls outside the scope of this document.

Framework: Graph Parameters

## Execution Model

Graphs must execute in both:

• Synchronous blocking mode (in that vxProcessGraph will block until the graph has completed), and in
• Asynchronous single-issue-per-reference mode (via vxScheduleGraph and vxWaitGraph).

### Asynchronous Mode

In asynchronous mode, Graphs must be single-issue-per-reference. This means that given a constructed graph reference $$G$$, it may be scheduled multiple times but only executes sequentially with respect to itself. Multiple graphs references given to the asynchronous graph interface do not have a defined behavior and may execute in parallel or in series based on the behavior or the vendor's implementation.

## Graph Formalisms

To use graphs several rules must be put in place to allow deterministic execution of Graphs. The behavior of a processGraph( $$G$$) call is determined by the structure of the Processing Graph $$G$$. The Processing Graph is a bipartite graph consisting of a set of Nodes $$N_1 \ldots N_n$$ and a set of data objects $$d_1 \ldots d_i$$. Each edge ( $$N_x$$, $$D_y$$) in the graph represents a data object $$D_y$$ that is written by Node $$N_x$$ and each edge ( $$D_x$$, $$N_y$$) represents a data object $$D_x$$ that is read by Node $$N_y$$. Each edge $$e$$ has a name Name( $$e$$), which gives the parameter name of the node that references the corresponding data object. Each Node Parameter also has a type Type(node, name) in {INPUT, OUTPUT, INOUT}. Some data objects are Virtual, and some data objects are Delay. Delay data objects are just collections of data objects with indexing (like an image list) and known linking points in a graph. A node may be classified as a head node, which has no backward dependency. Alternatively, a node may be a dependent node, which has a backward dependency to the head node. In addition, the Processing Graph has several restrictions:

1. Output typing - Every output edge ( $$N_x$$, $$D_y$$) requires Type( $$N_x$$, Name( $$N_x$$, $$D_y$$)) in {OUTPUT, INOUT}
2. Input typing - Every input edge ( $$N_x$$, $$D_y$$) requires Type( $$N_y$$, Name( $$D_x$$, $$N_y$$)) in {INPUT} or {INOUT}
3. Single Writer - Every data object is the target of at most one output edge.
4. Broken Cycles - Every cycle in $$G$$ must contain at least input edge ( $$D_x$$, $$N_y$$) where $$D_x$$ is Delay.
5. Virtual images must have a source - If $$D_y$$ is Virtual, then there is at least one output edge that writes $$D_y$$ ( $$N_x$$, $$D_y$$)
6. Bidirectional data objects shall not be virtual - If Type( $$N_x$$, Name( $$N_x$$, $$D_y$$)) is INOUT implies $$D_y$$ is non-Virtual.
7. Delay data objects shall not be virtual - If $$D_x$$ is Delay then it shall not be Virtual.
8. A uniform image cannot be output or bidirectional.

The execution of each node in a graph consists of an atomic operation (sometimes referred to as firing) that consumes data representing each input data object, processes it, and produces data representing each output data object. A node may execute when all of its input edges are marked present. Before the graph executes, the following initial marking is used:

• All input edges ( $$D_x$$, $$N_y$$) from non-Virtual objects Dx are marked (parameters must be set).
• All input edges ( $$D_x$$, $$N_y$$) with an output edge ( $$N_z$$, $$D_x$$) are unmarked.
• All input edges ( $$D_x$$, $$N_y$$) where $$D_x$$ is a Delay data object are marked.

Processing a node results in unmarking all the corresponding input edges and marking all its output edges; marking an output edge ( $$N_x$$, $$D_y$$) where $$D_y$$ is not a Delay results in marking all of the input edges ( $$D_y$$, $$N_z$$). Following these rules, it is possible to statically schedule the nodes in a graph as follows: Construct a precedence graph $$P$$, including all the nodes $$N_1 \ldots N_x$$, and an edge ( $$N_x$$, $$N_z$$) for every pair of edges ( $$N_x$$, $$D_y$$) and ( $$D_y$$, $$N_z$$) where $$D_y$$ is not a Delay. Then unconditionally fire each node according to any topological sort of $$P$$.

The following assertions should be verified:

• $$P$$ is a Directed Acyclic Graph (DAG), implied by 4 and the way it is constructed.
• Every data object has a value when it is executed, implied by 5, 6, 7, and the marking.
• Execution is deterministic if the nodes are deterministic, implied by 3, 4, and the marking.
• Every node completes its execution exactly once.

The execution model described here just acts as a formalism. For example, independent processing is allowed across multiple depended and depending nodes and edges, provided that the result is invariant with the execution model described here.

### Contained & Overlapping Data Objects

There are cases in which two different data objects referenced by an output parameter of node $$N_1$$ and input parameter of node $$N_2$$ in a graph induce a dependency between these two nodes: For example, a pyramid and its level images, image and the sub-images created from it by vxCreateImageFromROI or vxCreateImageFromChannel, or overlapping sub-images of the same image. Following figure show examples of this dependency. To simplify subsequent definitions and requirements a limitation is imposed that if a sub-image I' has been created from image I and sub-image I'' has been created from I', then I'' is still considered a sub-image of I and not of I'. In these cases it is expected that although the two nodes reference two different data objects, any change to one data object might be reflected in the other one. Therefore it implies that $$N_1$$ comes before $$N_2$$ in the graph's topological order. To ensure that, following definitions are introduced.

1. Containment Set - C(d), the set of recursively contained data objects of d, named Containment Set, is defined as follows:
• $$C_0$$(d)={d}
• $$C_1$$(d) is the set of all data objects that are directly contained by d:
1. If d is an image, all images created from an ROI or channel of d are directly contained by d.
2. If d is a pyramid, all pyramid levels of d are directly contained by d.
3. If d is an object array, all elements of d are directly contained by d.
4. If d is a delay object, all slots of d are directly contained by d.
• For i>1, $$C_i$$(d) is the set of all data objects that are contained by d at the ith order

\begin{eqnarray} C_i(d)=\bigcup_{d'\in{C_{i-1}(d)}}C_1(d') \end{eqnarray}

• C(d) is the set that contains d itself, the data objects contained by d, the data objects that are contained by the data objects contained by d and so on. Formally:

\begin{eqnarray} C(d)=\bigcup_{i=0}^{\infty}C_i(d) \end{eqnarray}

2. I(d) is a predicate that equals true if and only if d is an image.
3. Overlapping Relationship - The overlapping relation $$R_{ov}$$ is a relation defined for images, such that if $$i_1$$ and $$i_2$$ in C(i), i being an image, then $$i_1$$ $$R_{ov}$$ $$i_2$$ is true if and only if $$i_1$$ and $$i_2$$ overlap, i.e there exists a point (x,y) of i that is contained in both $$i_1$$ and $$i_2$$ . Note that this relation is reflexive and symmetric, but not transitive: $$i_1$$ overlaps $$i_2$$ and $$i_2$$ overlaps $$i_3$$ does not necessarily imply that $$i_1$$ overlaps $$i_3$$, as illustrated in the following figure:
4. Dependency Relationship - The dependency relationship $$N_1$$ -> $$N_2$$, is a relation defined for nodes. $$N_1$$ -> $$N_2$$ means that $$N_2$$ depends on $$N_1$$ and then implies that $$N_2$$ must be executed after the completion of $$N_1$$.
5. $$N_1$$ -> $$N_2$$ if $$N_1$$ writes to a data object $$d_1$$ and $$N_2$$ reads from a data object $$d_2$$ and:

\begin{eqnarray} d_1\in{C(d_2)}\ or\ d_2\in{C(d_1)}\ or\ (I(d_1)\ and\ I(d_2)\ and\ d_1R_{ov}d_2) \end{eqnarray}

## Node Execution Independence

In the following example a client computes the gradient magnitude and gradient phase from a blurred input image. The vxMagnitudeNode and vxPhaseNode are independently computed, in that each does not depend on the output of the other. OpenVX does not mandate that they are run simultaneously or in parallel, but it could be implemented this way by the OpenVX vendor.

A simple graph with some independent nodes.

The code to construct such a graph can be seen below.

vx_image images[] = {
vxCreateImage(context, 640, 480, VX_DF_IMAGE_UYVY),
vxCreateImage(context, 640, 480, VX_DF_IMAGE_S16),
vxCreateImage(context, 640, 480, VX_DF_IMAGE_U8),
};
vx_graph graph = vxCreateGraph(context);
vx_image virts[] = {
};
vxChannelExtractNode(graph, images[0], VX_CHANNEL_Y, virts[0]),
vxGaussian3x3Node(graph, virts[0], virts[1]),
vxSobel3x3Node(graph, virts[1], virts[2], virts[3]),
vxMagnitudeNode(graph, virts[2], virts[3], images[1]),
vxPhaseNode(graph, virts[2], virts[3], images[2]),
status = vxVerifyGraph(graph);
if (status == VX_SUCCESS)
{
status = vxProcessGraph(graph);
}
vxReleaseContext(&context); /* this will release everything */

## Verification

Graphs within OpenVX must go through a rigorous validation process before execution to satisfy the design concept of eliminating run-time overhead (parameter checking) that guarantees safe execution of the graph. OpenVX must check for (but is not limited to) these conditions:

Parameters To Nodes:

• Each required parameter is given to the node (The parameter state type constants.). Optional parameters may not be present and therefore are not checked when absent. If present, they are checked.
• Each parameter given to a node must be of the right direction (a value from Parameter direction enumeration).
• Each parameter given to a node must be of the right object type (from the object range of The VX_TYPE Constants).
• Each parameter attribute or value must be verified. In the case of a scalar value, it may need to be range checked (e.g., $$0.5 <= k <= 1.0$$). The implementation is not required to do run-time range checking of scalar values. If the value of the scalar changes at run time to go outside the range, the results are undefined. The rationale is that the potential performance hit for run-time range checking is too large to be enforced. It will still be checked at graph verification time as a time-zero sanity check. If the scalar is an output parameter of another node, it must be initialized to a legal value. In the case of vxScaleImageNode, the relation of the input image dimensions to the output image dimensions determines the scaling factor. These values or attributes of data objects must be checked for compatibility on each platform.
• Graph Connectivity - the vx_graph must be a Directed Acyclic Graph (DAG). No cycles or feedback is allowed. The vx_delay object has been designed to explicitly address feedback between Graph executions.
• Resolution of Virtual Data Objects - Any changes to Virtual data objects from unspecified to specific format or dimensions, as well as the related creation of objects of specific type that are observable at processing time, takes place at Verification time.

The implementation must check that all node parameters are the correct type at node creation time, unless the parameter value is set to NULL. Additional checks may also be made on non-NULL parameters. The user must be allowed to set parameters to NULL at node creation time, even if they are required parameters, in order to create "exemplar" nodes that are not used in graph execution, or to create nodes incrementally. Therefore the implementation must not generate an error at node creation time for parameters that are explicitly set to NULL. However, the implementation must check that all required parameters are non-NULL and the correct type during vxVerifyGraph. Other more complex checks may also be done during vxVerifyGraph. The implementation should provide specific error reporting of NULL parameters during vxVerifyGraph, e.g., "Parameter<parameter> of Node<node> is NULL."

# Callbacks

Callbacks are a method to control graph flow and to make decisions based on completed work. The vxAssignNodeCallback call takes as a parameter a callback function. This function will be called after the execution of the particular node, but prior to the completion of the graph. If nodes are arranged into independent sets, the order of the callbacks is unspecified. Nodes that are arranged in a serial fashion due to data dependencies perform callbacks in order. The callback function may use the node reference first to extract parameters from the node, and then extract the data references. Data outputs of Nodes with callbacks shall be available (via Map/Unmap/Copy methods) when the callback is called.

# User Kernels

OpenVX supports the concept of client-defined functions that shall be executed as Nodes from inside the Graph or are Graph internal. The purpose of this paradigm is to:

• Further exploit independent operation of nodes within the OpenVX platform.
• Allow componentized functions to be reused elsewhere in OpenVX.
• Formalize strict verification requirements (i.e., Contract Programming).

A graph with User Kernel nodes which are independent of the “base” nodes.

In this example, to execute client-supplied functions, the graph does not have to be halted and then resumed. These nodes shall be executed in an independent fashion with respect to independent base nodes within OpenVX. This allows implementations to further minimize execution time if hardware to exploit this property exists.

## Parameter Validation

User Kernels must aid in the Graph Verification effort by providing an explicit validation function for each vision function they implement. Each parameter passed to the instanced Node of a User Kernel is validated using the client-supplied validation function. The client must check these attributes and/or values of each parameter:

• Each attribute or value of the parameter must be checked. For example, the size of array, or the value of a scalar to be within a range, or a dimensionality constraint of an image such as width divisibility. (Some implementations may have restrictions, such as an image width be evenly divisible by some fixed number).
• If the output parameters depend on attributes or values from input parameters, those relationships must be checked.

### The Meta Format Object

The Meta Format Object is an opaque object used to collect requirements about the output parameter, which then the OpenVX implementation will check. The Client must manually set relevant object attributes to be checked against output parameters, such as dimensionality, format, scaling, etc.

## User Kernels Naming Conventions

User Kernels must be exported with a unique name (see Naming Conventions for information on OpenVX conventions) and a unique enumeration. Clients of OpenVX may use either the name or enumeration to retrieve a kernel, so collisions due to non-unique names will cause problems. The kernel enumerations may be extended by following this example:

#define VX_KERNEL_NAME_KHR_XYZ "org.khronos.example.xyz"
#define VX_LIBRARY_XYZ (0x3) // assigned from Khronos, vendors control their own
#define VX_KERNEL_KHR_XYZ (VX_ENUM_KERNEL(VX_ID_DEFAULT, VX_LIBRARY_XYZ, 0x0))
// up to 0xFFF kernel enums can be created.

Each vendor of a vision function or an implementation must apply to Khronos to get a unique identifier (up to a limit of $$2^{12}-1$$ vendors). Until they obtain a unique ID vendors must use VX_ID_DEFAULT.

To construct a kernel enumeration, a vendor must have both their ID and a library ID. The library ID's are completely vendor defined (however when using the VX_ID_DEFAULT ID, many libraries may collide in namespace).

Once both are defined, a kernel enumeration may be constructed using the VX_KERNEL_BASE macro and an offset. (The offset is optional, but very helpful for long enumerations.)

# Targets

A 'Target' specifies a physical or logical devices where a node is executed. This allows the use of different implementations of vision functions on different targets. The existence of allowed Targets is exposed to the applications by the use of defined APIs. The choice of a Target allows for different levels of control on where the nodes can be executed. An OpenVX implementation must support at least one target. Additional supported targets are specified using the appropriate enumerations. See vxSetNodeTarget, and The Target Enumeration Constants.. An OpenVX implementation must support at least one target VX_TARGET_ANY as well as VX_TARGET_STRING enumerates. An OpenVX implementation may also support more than these two to indicate the use of specific devices. For example, an implementation may add VX_TARGET_CPU and VX_TARGET_GPU enumerates to indicate the support of two possible targets to assign a nodes to . Another way an implementation can indicate the existence of multiple targets, for example CPU and GPU, is by specifying the target as VX_TARGET_STRING and using strings 'CPU' and 'GPU'. Thus defining targets using names rather than enumerates. The specific naming of string or enumerates is not enforced by the specification and it is up to the vendors to document and communicate the Target naming. Once available in a given implementation Applications can assign a Target to a node to specify the target that must execute that node by using the API vxSetNodeTarget.

# Base Vision Functions

OpenVX comes with a standard or base set of vision functions. The following table lists the supported set of vision functions, their input types (first table) and output types (second table), and the version of OpenVX in which they are supported.

## Inputs

Vision Function U8 U16 S16 U32 S32 F32 color
AbsDiff 1.0 1.0.1
Accumulate 1.0
AccumulateSquared 1.0
AccumulateWeighted 1.0
And 1.0
Box3x3 1.0
CannyEdgeDetector 1.0
ChannelCombine 1.0
ChannelExtract 1.0
ColorConvert 1.0
ConvertDepth 1.0 1.0
Convolve 1.0
Dilate3x3 1.0
EqualizeHistogram 1.0
Erode3x3 1.0
FastCorners 1.0
Gaussian3x3 1.0
HarrisCorners 1.0
HalfScaleGaussian 1.0
Histogram 1.0
IntegralImage 1.0
TableLookup 1.0 1.1
LaplacianPyramid 1.1
LaplacianReconstruct 1.1
Magnitude 1.0
MeanStdDev 1.0
Median3x3 1.0
MinMaxLoc 1.0 1.0
Multiply 1.0 1.0
NonLinearFilter 1.1
Not 1.0
OpticalFlowPyrLK 1.0
Or 1.0
Phase 1.0
GaussianPyramid 1.0
Remap 1.0
ScaleImage 1.0
Sobel3x3 1.0
Subtract 1.0 1.0
Threshold 1.0
WarpAffine 1.0
WarpPerspective 1.0
Xor 1.0

## Outputs

Vision Function U8 U16 S16 U32 S32 F32 color
AbsDiff 1.0 1.0.1
Accumulate 1.0
AccumulateSquared 1.0
AccumulateWeighted 1.0
And 1.0
Box3x3 1.0
CannyEdgeDetector 1.0
ChannelCombine 1.0
ChannelExtract 1.0
ColorConvert 1.0
ConvertDepth 1.0 1.0
Convolve 1.0 1.0
Dilate3x3 1.0
EqualizeHistogram 1.0
Erode3x3 1.0
FastCorners 1.0
Gaussian3x3 1.0
HarrisCorners 1.0
HalfScaleGaussian 1.0
Histogram 1.0
IntegralImage 1.0
TableLookup 1.0 1.1
LaplacianPyramid 1.1
LaplacianReconstruct 1.1
Magnitude 1.0
MeanStdDev 1.0
Median3x3 1.0
MinMaxLoc 1.0 1.0 1.0
Multiply 1.0 1.0
NonLinearFilter 1.1
Not 1.0
OpticalFlowPyrLK
Or 1.0
Phase 1.0
GaussianPyramid 1.0
Remap 1.0
ScaleImage 1.0
Sobel3x3 1.0
Subtract 1.0 1.0
Threshold 1.0
WarpAffine 1.0
WarpPerspective 1.0
Xor 1.0

# Lifecycles

## OpenVX Context Lifecycle

The lifecycle of the context is very simple.

The lifecycle model for an OpenVX Context.

## Graph Lifecycle

OpenVX has four main phases of graph lifecycle:

• Construction - Graphs are created via vxCreateGraph, and Nodes are connected together by data objects.
• Verification - The graphs are checked for consistency, correctness, and other conditions. Memory allocation may occur.
• Execution - The graphs are executed via vxProcessGraph or vxScheduleGraph. Between executions data may be updated by the client or some other external mechanism. The client of OpenVX may change reference of input data to a graph, but this may require the graph to be validated again by checking vxIsGraphVerified.
• Deconstruction - Graphs are released via vxReleaseGraph. All Nodes in the Graph are released.

Graph Lifecycle

## Data Object Lifecycle

All objects in OpenVX follow a similar lifecycle model. All objects are

• Created via vxCreate<Object><Method> or retreived via vxGet<Object><Method> from the parent object if they are internally created.
• Used within Graphs.
• Then objects must be released via vxRelease<Object> or via vxReleaseContext when all objects are released.

### OpenVX Image Lifecycle

This is an example of the Image Lifecycle using the OpenVX Framework API. This would also apply to other data types with changes to the types and function names.

Image Object Lifecycle

# Host Memory Data Object Access Patterns

For objects retrieved from OpenVX that are 2D in nature, such as vx_image, vx_matrix, and vx_convolution, the manner in which the host-side has access to these memory regions is well-defined. OpenVX uses a row-major storage (that is each unit in a column is memory-adjacent to its row adjacent unit). Two-dimensional objects are always created (using vxCreateImage or vxCreateMatrix) in width (columns) by height (rows) notation, with the arguments in that order. When accessing these structures in “C” with two-dimensional arrays of declared size, the user must therefore provide the array dimensions in the reverse of the order of the arguments to the Create function. This layout ensures row-wise storage in C on the host. A pointer could also be allocated for the matrix data and would have to be indexed in this row-major method.

## Matrix Access Example

const vx_size columns = 3;
const vx_size rows = 4;
vx_matrix matrix = vxCreateMatrix(context, VX_TYPE_FLOAT32, columns, rows);
vx_status status = vxGetStatus((vx_reference)matrix);
if (status == VX_SUCCESS)
{
vx_int32 j, i;
#if defined(OPENVX_USE_C99)
vx_float32 mat[rows][columns]; /* note: row major */
#else
vx_float32 *mat = (vx_float32 *)malloc(rows*columns*sizeof(vx_float32));
#endif
for (j = 0; j < (vx_int32)rows; j++)
for (i = 0; i < (vx_int32)columns; i++)
#if defined(OPENVX_USE_C99)
mat[j][i] = (vx_float32)rand()/(vx_float32)RAND_MAX;
#else
mat[j*columns + i] = (vx_float32)rand()/(vx_float32)RAND_MAX;
#endif
}
#if !defined(OPENVX_USE_C99)
free(mat);
#endif
}

## Image Access Example

Images and Array differ slightly in how they are accessed due to more complex memory layout requirements.

void *base_ptr = NULL;
vx_uint32 width = 640, height = 480, plane = 0;
vx_image image = vxCreateImage(context, width, height, VX_DF_IMAGE_U8);
vx_map_id map_id;
rect.start_x = rect.start_y = 0;
rect.end_x = rect.end_y = PATCH_DIM;
status = vxMapImagePatch(image, &rect, plane, &map_id,
if (status == VX_SUCCESS)
{
vx_uint32 x,y,i,j;
vx_uint8 pixel = 0;
/* a couple addressing options */
/* use linear addressing function/macro */
for (i = 0; i < addr.dim_x*addr.dim_y; i++) {
*ptr2 = pixel;
}
/* 2d addressing option */
for (y = 0; y < addr.dim_y; y+=addr.step_y) {
for (x = 0; x < addr.dim_x; x+=addr.step_x) {
*ptr2 = pixel;
}
}
/* direct addressing by client
* for subsampled planes, scale will change
*/
for (y = 0; y < addr.dim_y; y+=addr.step_y) {
for (x = 0; x < addr.dim_x; x+=addr.step_x) {
vx_uint8 *tmp = (vx_uint8 *)base_ptr;
tmp[i] = pixel;
}
}
/* more efficient direct addressing by client.
* for subsampled planes, scale will change.
*/
for (y = 0; y < addr.dim_y; y+=addr.step_y) {
for (x = 0; x < addr.dim_x; x+=addr.step_x) {
vx_uint8 *tmp = (vx_uint8 *)base_ptr;
tmp[i] = pixel;
}
}
/* this commits the data back to the image.
*/
status = vxUnmapImagePatch(image, map_id);
}
vxReleaseImage(&image);

## Array Access Example

Arrays only require a single value, the stride, instead of the entire addressing structure that images need.

vx_size i, stride = sizeof(vx_size);
void *base = NULL;
vx_map_id map_id;
/* access entire array at once */
vxMapArrayRange(array, 0, num_items, &map_id, &stride, &base, VX_READ_AND_WRITE, VX_MEMORY_TYPE_HOST, 0);
for (i = 0; i < num_items; i++)
{
vxArrayItem(mystruct, base, i, stride).some_uint += i;
vxArrayItem(mystruct, base, i, stride).some_double = 3.14f;
}
vxUnmapArrayRange(array, map_id);

Map/Unmap pairs can also be called on individual elements of array using a method similar to this:

/* access each array item individually */
for (i = 0; i < num_items; i++)
{
mystruct *myptr = NULL;
vxMapArrayRange(array, i, i+1, &map_id, &stride, (void **)&myptr, VX_READ_AND_WRITE, VX_MEMORY_TYPE_HOST, 0);
myptr->some_uint += 1;
myptr->some_double = 3.14f;
vxUnmapArrayRange(array, map_id);
}

# Concurrent Data Object Access

Accessing OpenVX data-objects using the functions Map, Copy, Read concurrently to an execution of a graph that is accessing the same data objects is permitted only if all accesses are read-only. That is, for Map, Copy to have a read-only access mode and for nodes in the graph to have that data-object as an input parameter only. In all other cases, including write or read-write modes and Write access function, as well as a graph nodes having the data-object as output or bidirectional, the application must guarantee that the access is not performed concurrently with the graph execution. That can be achieved by calling un-map following a map before calling vxScheduleGraph or vxProcessGraph. In addition, the application must call vxWaitGraph after vxScheduleGraph before calling Map, Read, Write or Copy to avoid restricted concurrent access. An application that fails to follow the above might encounter an undefined behavior and/or data loss without being notified by the OpenVX framework. Accessing images created from ROI (vxCreateImageFromROI) or created from a channel (vxCreateImageFromChannel) must be treated as if the entire image is being accessed.

• Setting an attribute is considered as writing to a data object in this respect.
• For concurrent execution of several graphs please see Execution Model
• Also see the graph formalism section for guidance on accessing ROIs of the same image within a graph.

# Valid Image Region

The valid region mechanism informs the application as to which pixels of the output images of a graph's execution have valid values (see valid pixel definition below). The mechanism supports the communication of the valid region between different graph executions. Some vision functions, mainly those providing statistics and summarization of image information, use the valid region to ignore pixels that are not valid on their inputs (potentially bad or unstable pixel values). A good example of such a function is Min/Max Location. Formalization of the valid region mechanism is given below.

• Valid Pixels - All output pixels of an OpenVX function are considered valid by default, unless their calculation depends on input pixels that are not valid. An input pixel is not valid in one of two situations:
1. The pixel is outside of the image border and the border mode in use is VX_BORDER_UNDEFINED
2. The pixel is outside the valid region of the input image.
• Valid Region - The region in the image that contains all the valid pixels. Theoretically this can be of any shape. OpenVX currently only supports rectangular valid regions. In subsequent text the term 'valid rectangle' denotes a valid region that is rectangular in shape.
• Valid Rectangle Reset - In some cases it is not possible to calculate a valid rectangle for the output image of a vision function (for example, warps and remap). In such cases, the vision function is said to reset the valid Region to the entire image. The attribute VX_NODE_VALID_RECT_RESET is a read only attribute and is used to communicate valid rectangle reset behavior to the application. When it is set to vx_true_e for a given node the valid rectangle of the output images will reset to the full image upon execution of the node, when it is set to vx_false_e  the valid rectangle will be calculated. All standard OpenVX functions will have this attribute set to vx_false_e  by default, except for Warp and Remap where it will be set to vx_true_e.
• Valid Rectangle Initialization - Upon the creation of an image, its valid rectangle is the entire image. One exception to this is when creating an image via vxCreateImageFromROI; in that case, the valid region of the ROI image is the subset of the valid region of the parent image that is within the ROI. In other words, the valid region of an image created using an ROI is the largest rectangle that contains valid pixels in the parent image.
• Valid Rectangle Calculation - The valid rectangle of an image changes as part of the graph execution, the correct value is guaranteed only when the execution finishes. The valid rectangle of an image remains unchanged between graph executions and persists between graph executions as long as the application doesn't explicitly change the valid region via vxSetImageValidRectangle. Notice that using vxMapImagePatch, vxUnmapImagePatch or vxSwapImageHandle does not change the valid region of an image. If a non-UNDEFINED border mode is used on an image where the valid region is not the full image, the results at the border and resulting size of the valid region are implementation-dependent. This case can occur when mixing UNDEFINED and other border mode, which is not recommended.
• Valid Region Usage - For all standard OpenVX functions, the framework must guarantee that all pixel values inside the valid rectangle of the output images are valid. The framework does not guarantee that input pixels outside of the valid rectangle are processed. For the following vision functions, the framework guarantees that pixels outside of the valid rectangle do not participate in calculating the vision function result: Equalize Histogram, Integral Image, Fast Corners, Histogram, Mean and Standard Deviation, Min Max Location, Optical Flow Pyramid (LK) and Canny Edge Detector. An application can get the valid rectangle of an image by using vxGetValidRegionImage.
• User kernels - User kernels may change the valid rectangles of their output images. To change the valid rectangle, the programmer of the user kernel must provide a call-back function that sets the valid rectangle. The output validator of the user kernel must provide this callback by setting the value of the vx_meta_format attribute VX_VALID_RECT_CALLBACK during the output validator. The callback function must be callable by the OpenVX framework during graph validation and execution. Assumptions must not be made regarding the order and the frequency by which the valid rectangle callback is called. The framework will recalculate the valid region when a change in the input valid regions is detected. For user nodes, the default value of VX_NODE_VALID_RECT_RESET is vx_true_e. Setting VX_VALID_RECT_CALLBACK during parameter validation to a value other than NULL will result in setting VX_NODE_VALID_RECT_RESET to vx_false_e. Note: the above means that when VX_VALID_RECT_CALLBACK is not set or set to NULL the user-node will reset the valid rectangle to the entire image.
• In addition, valid rectangle reset occurs in the following scenarios:
1. A reset of the valid rectangle of a parent image when a node writes to one of its ROIs. The only case where the reset does not occur is when the child ROI image is identical to the parent image.
2. For nodes that have the VX_NODE_VALID_RECT_RESET set to vx_true_e

# Extending OpenVX

Beyond User Kernels there are other mechanisms for vendors to extend features in OpenVX. These mechanisms are not available to User Kernels. Each OpenVX official extension has a unique identifier, comprised of capital letters, numbers and the underscore character, prefixed with "KHR_", for example "KHR_NEW_FEATURE".

## Extending Attributes

When extending attributes, vendors must use their assigned ID from The Vendor ID list for OpenVX. in conjunction with the appropriate macros for creating new attributes with VX_ATTRIBUTE_BASE. The typical mechanism to extend a new attribute for some object type (for example a vx_node attribute from VX_ID_TI) would look like this:

enum {
VX_NODE_TI_NEWTHING = VX_ATTRIBUTE_BASE(VX_ID_TI, VX_TYPE_NODE) + 0x0,
}

## Vendor Custom Kernels

Vendors wanting to add more kernels to the base set supplied to OpenVX should provide a header of the form

#include <VX/vx_ext_<vendor>.h>

that contains definitions of each of the following.

• New Node Creation Function Prototype per function.
vx_node vxXYZNode(vx_graph graph, vx_image input, vx_uint32 value, vx_image output, vx_array temp);
• A new Kernel Enumeration(s) and Kernel String per function.
#define VX_KERNEL_NAME_KHR_XYZ "org.khronos.example.xyz"
#define VX_LIBRARY_XYZ (0x3) // assigned from Khronos, vendors control their own
#define VX_KERNEL_KHR_XYZ (VX_ENUM_KERNEL(VX_ID_DEFAULT, VX_LIBRARY_XYZ, 0x0))
// up to 0xFFF kernel enums can be created.
This should come with good documentation for each new part of the extension. Ideally, these sorts of extensions should not require linking to new objects to facilitate usage.

## Vendor Custom Extensions

Some extensions affect base vision functions and thus may be invisible to most users. In these circumstances, the vendor must report the supported extensions to the base nodes through the VX_CONTEXT_EXTENSIONS attribute on the context.

vx_char *tmp, *extensions = NULL;
vx_size size = 0;
vxQueryContext(context,VX_CONTEXT_EXTENSIONS_SIZE,&size,sizeof(size));
extensions = malloc(size);
extensions, size);

Extensions in this list are dependent on the extension itself; they may or may not have a header and new kernels or framework feature or data objects. The common feature is that they are implemented and supported by the implementation vendor.

## Hinting

The specification defines a Hinting API that allows Clients to feed information to the implementation for optional behavior changes. See Framework: Hints. It is assumed that most of the hints will be vendor- or implementation-specific. Check with the OpenVX implementation vendor for information on vendor-specific extensions.

## Directives

The specification defines a Directive API to control implementation behavior. See Framework: Directives. This may allow things like disabling parallelism for debugging, enabling cache writing-through for some buffers, or any implementation-specific optimization.

# Import and Export Framework

OpenVX provides a way of exporting and importing pre-verified graphs or other objects, in vendor-specific formats, for use cases, such as:

• Embedded systems using fixed graphs, to minimise the amount of code required.
• Safety-critical systems where the OpenVX library does not have a node API.
• Extension (such as Neural Networks) which require the ability to import binary objects.

## Import and Export of Objects

• Application must be able to specify which objects are to be exported.
• The framework will also export any other objects required; for example, if a graph is to be exported then all components of that graph will also be exported even if their references were not given.
• Upon Import, only those objects that were specified for export will be visible in the imported entity; all other objects may be present but are not directly accessible. For example, a pyramid object may be exported, in which case the levels of the pyramid will be available in the usual way. As another example, an image that is part of a pyramid is exported. Since an image has no API that allows accessing the pyramid of which it is part, then there is no requirement to export the rest of the pyramid.

## Creation of Objects Upon Import

• To make it possible to implement certain scenarios, for example when an image needs to be created in a different way in the import environment than the export environment, certain objects may be created by the application and passed to the import routine. These objects need to be specified at the time of export, and provided again at the time of import.
• All other required objects will be created by the framework upon import.

## Import and Export of Data Values For Objects To Be Created By The Framework

• Some objects may contain data values (as distinct from Meta Data) that require preservation across the export and import routines. The application can specify this at the time of export; those objects which are listed (by giving references) for export will then either be stripped of data values or have their data values entirely exported.
• For those objects which are not listed, the following rules apply:
1. In any one graph, if an object is not connected as an output parameter then its data values will be exported (and imported).
2. Where the object in (1) is a composite object such as a Pyramid or ObjectArray, then rule (1) applies to all sub-objects by definition.
3. Where the object in (1) is a sub-object such as a Region Of Interest or member of an ObjectArray, and the composite object does not meet the conditions of rule (1), then rule (1) applies to the sub-object only.
4. When objects are imported, the exported data values are assigned. However, if parts of the data were not defined at the time of export, then there is no guarantee that upon import the same values will be present. For example, consider an image where values had been written only to some (rectangular) part of the image before export. After import, only this part of the image will be guaranteed to contain the same values; those parts which were undefined before will be set to the default value for the data field. In the absence of any other definition the default value is zero.
• For those objects which are listed, then:
• If the application requires, all defined values shall be exported.
• The application requires, no values need be exported. The behavior here is as though no values had been defined (written) for the object.
• Areas of undefined values will remain undefined (and possibly containing different random values) upon import.
• All values are initialized upon import. If data was not defined, then it is set to the default value for the data field. In the absence of any other definition the default value is zero.

## Import and Export of Values For Objects To Be Created By The Application

• Objects created by the application before import of the binary object must have their data values defined by the application before the import operation.
• Sometimes changing the value stored in an object that is an input parameter of a verified graph will require that the graph is verified again before execution. If such an object is listed as to be supplied by the application, then the export operation will fail.

## Import and Export of Meta Data

• For all objects that are visible in the import, all query-able Meta Data must appear the same after import as before export.
• Objects created by the application before import and provided to the import API must match in type, size, etc. and therefore the export must export sufficient information for this check to be done.
• An Import may fail if the application-provided objects do not match those given at the time of export.
• Graphs with delays that are registered for auto-ageing at the time of export will be in the same condition after import of the objects.

## Restrictions Upon What References May Be Exported

• Export will fail if a vx_context is given in a list to export.
• Export will fail if a vx_import is given in a list to export. (vx_import is the type of the object returned by the import functions).
• Export will fail if a reference to a virtual object is given in the list to export.
• Export will fail if a vx_node, vx_kernel, or vx_parameter is given in the list to export.
• Export is otherwise defined for “objects”.

## Access To Object References In The Imported Object

• References are obtained from the import API for those objects whose references were listed at the time of export. These are not the same objects; they are equivalent objects created by the framework at import time. The implementation guarantees that references will be available and valid for all objects listed at the time of export, or the import will fail.
• References additionally may be obtained using a name given to an object before export.
• Before export, objects may be named for retrieval by name using the existing API vx_status vxSetReferenceName(vx_reference ref, const vx_char * name).
• Export will fail if duplicate names are found for listed references.
• Import will fail if duplicate names are found in the import object.
• If references are obtained by name, only those objects whose references were listed at the time of export can be found by name.
• A vx_node, vx_kernel, or vx_parameter cannot be obtained from the import object.

# Safety-critical Features

## The Development and Deployment Feature Sets

The safety-critical environment (for example ISO26262) requires an implementation to satisfy rigorous demands for deployment. For development, an implementation must satisfy the lesser demands of a software tool used to create such a deployment. A developer may use the full set of development features to create and export a graph, and then for deployment this graph is imported by a program that only uses features in the deployment feature set.

The safety-critical environment requires that graphs must execute in a deterministic, reproducible way. It is up to the implementation to guarantee this behavior in some way.

This section defines the differences between deployment feature set and development feature set.

## Node creation APIs

None of the vxXXXNode() functions in the “Vision Functions” section of the specification are in the deployment feature set (since graphs may not be constructed) and thus all requirements in that section are not directly applicable to the deployment feature set, and specifically none of the APIs defined in that section are applicable to the deployment feature set. However, the export and import APIs demand that a graph that has been exported and then imported must execute in the same way as before export. Hence it is implicit that all requirements relating to the operation of a graph built from nodes as defined by the “Vision Functions” section using the development feature set also apply to the operation of the same graph when it is executed using the deployment feature set.

For completeness, the following table lists the node creation functions that are present in the development feature set, but not in the deployment feature set.

Node APIs, present only in the development feature set
vxColorConvertNode vxMeanStdDevNode vxLaplacianPyramidNode
vxAddNode vxChannelExtractNode vxThresholdNode
vxLaplacianReconstructNode vxSubtractNode vxChannelCombineNode
vxIntegralImageNode vxAccumulateImageNode vxConvertDepthNode
vxPhaseNode vxErode3x3Node vxAccumulateWeightedImageNode
vxCannyEdgeDetectorNode vxSobel3x3Node vxDilate3x3Node
vxAccumulateSquareImageNode vxWarpAffineNode vxMagnitudeNode
vxMedian3x3Node vxMinMaxLocNode vxWarpPerspectiveNode
vxScaleImageNode vxBox3x3Node vxAndNode
vxHarrisCornersNode vxTableLookupNode vxGaussian3x3Node
vxOrNode vxFastCornersNode vxHistogramNode
vxNonLinearFilterNode vxXorNode vxOpticalFlowPyrLKNode
vxEqualizeHistNode vxConvolveNode vxNotNode
vxRemapNode vxAbsDiffNode vxGaussianPyramidNode
vxMultiplyNode vxHalfScaleGaussianNode

## Basic and Administrative Features APIs

The rest of the framework API, as described in the “Basic Features” and “Administrative Features” sections of the specification are partitioned into those functions that are required for both development and deployment feature sets, and those that are required in the development feature set only. The following table lists these.

API Group API Function Is deployment feature?
CONTEXT vxCreateContext Yes
vxReleaseContext Yes
vxGetContext Yes
vxQueryContext Yes
vxSetContextAttribute Yes
vxHint Yes
vxDirective Yes
vxGetStatus Yes
vxRegisterUserStruct
vxAllocateUserKernelId
vxAllocateUserKernelLibraryId
IMAGE vxCreateImage Yes
vxCreateImageFromROI Yes
vxCreateUniformImage Yes
vxCreateVirtualImage
vxCreateImageFromHandle Yes
vxSwapImageHandle Yes
vxQueryImage Yes
vxSetImageAttribute Yes
vxReleaseImage Yes
vxComputeImagePatchSize Yes
vxFormatImagePatchAddress1d Yes
vxFormatImagePatchAddress2d Yes
vxGetValidRegionImage Yes
vxCopyImagePatch Yes
vxMapImagePatch Yes
vxUnmapImagePatch Yes
vxCreateImageFromChannel Yes
vxSetImageValidRectangle Yes
KERNEL vxLoadKernels
vxUnloadKernels
vxGetKernelByName
vxGetKernelByEnum
vxQueryKernel
vxReleaseKernel
vxAddUserKernel
vxFinalizeKernel
vxAddParameterToKernel
vxRemoveKernel
vxSetKernelAttribute
vxGetKernelParameterByIndex
GRAPH vxCreateGraph
vxReleaseGraph Yes
vxVerifyGraph
vxProcessGraph Yes
vxScheduleGraph Yes
vxWaitGraph Yes
vxQueryGraph Yes
vxSetGraphAttribute
vxAddParameterToGraph
vxSetGraphParameterByIndex Yes
vxGetGraphParameterByIndex
vxIsGraphVerified
NODE vxCreateGenericNode
vxQueryNode
vxSetNodeAttribute
vxReleaseNode
vxRemoveNode
vxAssignNodeCallback
vxRetrieveNodeCallback
vxSetNodeTarget
vxReplicateNode
PARAMETER vxGetParameterByIndex
vxReleaseParameter
vxSetParameterByIndex
vxSetParameterByReference
vxQueryParameter
SCALAR vxCreateScalar Yes
vxReleaseScalar Yes
vxQueryScalar Yes
vxCopyScalar Yes
REFERENCE vxQueryReference Yes
vxReleaseReference Yes
vxRetainReference Yes
vxSetReferenceName Yes
DELAY vxQueryDelay Yes
vxReleaseDelay Yes
vxCreateDelay Yes
vxGetReferenceFromDelay Yes
vxAgeDelay Yes
vxRegisterAutoAging
LOGGING vxAddLogEntry
vxRegisterLogCallback
LUT vxCreateLUT Yes
vxReleaseLUT Yes
vxQueryLUT Yes
vxCopyLUT Yes
vxMapLUT Yes
vxUnmapLUT Yes
DISTRIBUTION vxCreateDistribution Yes
vxReleaseDistribution Yes
vxQueryDistribution Yes
vxCopyDistribution Yes
vxMapDistribution Yes
vxUnmapDistribution Yes
THRESHOLD vxCreateThreshold Yes
vxReleaseThreshold Yes
vxSetThresholdAttribute Yes
vxQueryThreshold Yes
MATRIX vxCreateMatrix Yes
vxReleaseMatrix Yes
vxQueryMatrix Yes
vxCopyMatrix Yes
vxCreateMatrixFromPattern Yes
CONVOLUTION vxCreateConvolution Yes
vxReleaseConvolution Yes
vxQueryConvolution Yes
vxSetConvolutionAttribute Yes
vxCopyConvolutionCoefficients Yes
PYRAMID vxCreatePyramid Yes
vxCreateVirtualPyramid
vxReleasePyramid Yes
vxQueryPyramid Yes
vxGetPyramidLevel Yes
REMAP vxCreateRemap Yes
vxReleaseRemap Yes
vxSetRemapPoint Yes
vxGetRemapPoint Yes
vxQueryRemap Yes
ARRAY vxCreateArray Yes
vxCreateVirtualArray
vxReleaseArray Yes
vxQueryArray Yes
vxAddArrayItems Yes
vxTruncateArray Yes
vxCopyArrayRange Yes
vxMapArrayRange Yes
vxUnmapArrayRange Yes
OBJECT ARRAY vxCreateObjectArray Yes
vxCreateVirtualObjectArray
vxGetObjectArrayItem Yes
vxReleaseObjectArray Yes
vxQueryObjectArray Yes
META FORMAT vxSetMetaFormatAttribute
vxSetMetaFormatFromReference
EXPORT vxExportObjectsToMemory
vxReleaseExportedMemory
IMPORT vxImportObjectsFromMemory Yes
vxReleaseImport Yes
vxGetImportReferenceByName Yes

## Attributes

The following two requirements are not part of the deployment feature set:

• Calling vxQueryGraph with the attribute VX_GRAPH_NUMNODES
• Calling vxQueryGraph with the attribute VX_GRAPH_PERFORMANCE