# API overview
The current version of the Qualcomm® AI Engine Direct API is:
- QNN\_API\_VERSION\_MAJOR 2
-
- QNN\_API\_VERSION\_MINOR 29
-
- QNN\_API\_VERSION\_PATCH 0
-
The QNN API is source-level backwards compatible. However, it is not guaranteed to be binary (ABI) backwards compatible.
## Components
Clients interact with Qualcomm® AI Engine Direct through the backend library by invoking [QNN API](https://docs.qualcomm.com/doc/80-63442-50/topic/api_root.html).
The QNN API is C-style to facilitate portability across different platforms.
The API is organized into components, marked with *QnnComponent* as depicted in the diagram
[QNN API Components](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-api-components-figure).
Each of the API components has a corresponding header file, e.g., `QnnGraph.h`.
**QNN API Components**

The QNN API components are categorized in
[QNN API Components Summary Table](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-api-components-table).
| API Component | Category | Backend Specialization | Description |
| --- | --- | --- | --- |
| [QnnBackend](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnBackend_h.html##file-include-qnn-qnnbackend-h) | Core | Yes | This is a top level QNN API component. Most QNN APIs require a backend to be
initialized first. Provides QNN OpPackage Registry API. |
| [QnnDevice](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnDevice_h.html##file-include-qnn-qnndevice-h) | Core | Yes | This is a top level QNN API component which provides multi-core support. Provides all constructs required to
associate desired hardware accelerator resources for execution of user composed graphs. A platform is broken down
into potentially multiple devices. Devices may have multiple cores. Provides API for performance control. |
| [QnnContext](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnContext_h.html##file-include-qnn-qnncontext-h) | Core | Yes | Context provides execution environment for graphs and operations.
Graphs and tensors which are shared in between graphs are created within a context.
Context content can be cached into a binary form which later can be used for faster
context/graph loading.
It provides configuration option for Priority control. |
| [QnnGraph](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnGraph_h.html##file-include-qnn-qnngraph-h) | Core | Yes | Provides composable graph API. A graph is created inside a context, and is composed from
nodes and tensors.
Nodes are connected with tensors. Once finalized, graph is ready for execution. |
| [QnnTensor](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnTensor_h.html##file-include-qnn-qnntensor-h) | Core | No | Tensors hold either operation’s static/constant data or input/output activation data.
Tensors can have either Context or Graph scope. Tensors created with Context scope can be
used within Graphs that belong to the same Context. |
| [QnnOpPackage](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnOpPackage_h.html##file-include-qnn-qnnoppackage-h) | Core | Yes | Provides interface to the backend to use registered OpPackage libraries. |
| [QnnProfile](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnProfile_h.html##file-include-qnn-qnnprofile-h) | Utility | Yes | Provides means to profile QNN backends to evaluate performance (memory and timing) of
graphs and operations. |
| [QnnLog](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnLog_h.html##file-include-qnn-qnnlog-h) | Utility | No | Provides means for QNN backends to output logging data, can be extended to the
OpPackage as well.
Can be initialized before QnnBackend. |
| [QnnProperty](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnProperty_h.html##file-include-qnn-qnnproperty-h) | System | No | Provides means for client to discover capabilities of a backend. Can be used without
QnnBackend initialization. |
| [QnnMem](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnMem_h.html##file-include-qnn-qnnmem-h) | System | No | Provides API to register externally allocated memory with a backend. |
| [QnnSignal](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnSignal_h.html##file-include-qnn-qnnsignal-h) | System | No | Provides means to manage Signal objects. Signal objects are used to control execution of
other components. |
## Usage sequences
As highlighted in the [Overview](https://docs.qualcomm.com/doc/80-63442-50/topic/overview.html) section, the QNN architecture and unified API is
designed with the intent to ease integration into third-party NN frameworks, with the flexibility
to support varying use case needs.
The following sections describe typical QNN API interaction workflows.
### Basic call flow
The most common use case for clients interacting with the QNN API is to construct a graph representing
their network model by adding operation nodes and tensors to connect them. Once the construction is
complete, the user can start graph execution by supplying input tensors to the designated input nodes
of the graph. Frameworks like SNPE and ANN use this workflow to construct and execute QNN graphs.
The QNN SDK also includes neural network converters that can assist the user in constructing such
graphs by translating a source network model into an equivalent QNN representation. This is
essentially a C++ file consisting of invocations to the exact same QNN APIs that perform operations
described above. Clients can use this converter-based workflow to compile and link the QNN
representation of their models into applications. Some tools in the QNN SDK, such as qnn-net-run,
use this workflow.
The [QNN Basic Call Flow](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-basic-call-flow-figure)
diagram demonstrates this basic scenario.
Note that this illustration does not showcase the usage of all API components described above.
For simplicity, the illustration is limited to the loading and execution of an entire graph
inside one context and on one backend.
**QNN Basic Call Flow**

#### Initialization and Op Package registration
Applications interacting with the QNN API must first create the backend on which to create contexts and graphs. This is
done using [QnnBackend\_create()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnBackend_8h_1a495313092040347c75894f8f2db97f97.html#exhale-function-qnnbackend-8h-1a495313092040347c75894f8f2db97f97).
Native operations supported in the QNN SDK are automatically registered with the backend at the
time of initialization. If an application wants to use custom Op Packages, it must register
them manually using [QnnBackend\_registerOpPackage()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnBackend_8h_1a95dd59ad0b59872f3649f7c363c23441.html#exhale-function-qnnbackend-8h-1a95dd59ad0b59872f3649f7c363c23441).
#### Context and graph composition
QNN graphs live in QNN contexts that provide an execution environment for their operations, as
explained in [QNN API Components](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-api-components-figure). An application creates a context
using [QnnContext\_createFromBinary()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1aa261465dd9bdfe51532a9d33fe4a2fa9.html#exhale-function-qnncontext-8h-1aa261465dd9bdfe51532a9d33fe4a2fa9).
Optionally, it can customize the context using the argument
[QnnContext\_Config\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnnContext__Config__t.html#exhale-struct-structqnncontext-config-t).
The application then creates an empty graph with desired configuration within the context using
[QnnGraph\_create()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1acef7b5c50463d8b02bb4abd769ae5ea9.html#exhale-function-qnngraph-8h-1acef7b5c50463d8b02bb4abd769ae5ea9).
It then starts translating the source framework model into the QNN graph by adding nodes and
interconnecting them by adding tensors to the graph. The QNN tensors that connect these nodes are
created using the QNN APIs in [QnnTensor.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnTensor_h.html##file-include-qnn-qnntensor-h).
Tensors that connect nodes within a graph are referred to as *graph tensors*, and can be created
using [QnnTensor\_createGraphTensor()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnTensor_8h_1acf98aa32e9fc9db88e2250f75c7e21ac.html#exhale-function-qnntensor-8h-1acf98aa32e9fc9db88e2250f75c7e21ac).
Tensors that are defined in the scope of a QNN context, and connect different graphs are
referred to as *context tensors*, and can be created using
[QnnTensor\_createContextTensor()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnTensor_8h_1ae4cb118c85d47fcc5f68dbe4f095cfec.html#exhale-function-qnntensor-8h-1ae4cb118c85d47fcc5f68dbe4f095cfec).
Input tensors that represent static data, such as weights and biases, can be created by supplying
data as part of [Qnn\_Tensor\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnn__Tensor__t.html#exhale-struct-structqnn-tensor-t).
QNN tensors can be designated to be of different types based on the purpose that they are used in
an application. Graph input tensors are specified with type QNN\_TENSOR\_TYPE\_APP\_WRITE.
Graph output tensors are specified with type QNN\_TENSOR\_TYPE\_APP\_READ. All other intermediate
tensors in a graph are specified with type QNN\_TENSOR\_TYPE\_NATIVE, and tensors containing static
data are specified with type QNN\_TENSOR\_TYPE\_STATIC. Context tensors that intend to connect
two or more graphs are specified with type QNN\_TENSOR\_TYPE\_APP\_READWRITE.
QNN prescribes rules and imposes certain restrictions in using these types when creating different
types of QNN tensors to safeguard applications from creating them using invalid combinations.
Refer to [QnnTensor.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_QnnTensor_h.html##file-include-qnn-qnntensor-h) for a comprehensive listing of all rules
as applicable to tensor creation.
Note
QNN tensors must be created with a name unique in the context. Duplication is not
permitted and results in undefined behavior.
Nodes are instances of QNN operations. Each node is created with an operation configuration
that defines the type and attributes of the operation this node represents. See
[Qnn\_OpConfig\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnn__OpConfig__t.html#exhale-struct-structqnn-opconfig-t) for more details.
Nodes are added to a graph using
[QnnGraph\_addNode()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1a1c6363e459cb7092356572f5af1c952b.html#exhale-function-qnngraph-8h-1a1c6363e459cb7092356572f5af1c952b),
which accepts a user argument for such an op configuration specified by its OpConfig.
Adding nodes to the QNN graph should be done in the node dependency order.
Note
There are no QNN APIs to *remove* nodes and tensors registered with a context or graph.
#### Graph finalization
After all tensors and nodes have been configured and added to the graph the application must
inform QNN that composition is complete and the graph can be finalized by calling
[QnnGraph\_finalize()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1addff55c1a315d0141c821f771d622d56.html#exhale-function-qnngraph-8h-1addff55c1a315d0141c821f771d622d56).
This step allows the backend to perform a series of optimizations, such as collapsing
multiple nodes into single nodes, and produce a highly performant and efficient graph.
Note
This step of finalizing a graph is mandatory to allow applications to run inference cycles.
Note
A finalized graph cannot be modified any further; no new nodes or tensors can be
added to the graph after this step.
#### Graph execution
After having successfully created and finalized a graph, the application can now start running
inference on the backend with the graph execution APIs. Graphs can be executed synchronously
using [QnnGraph\_execute()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1a3ea05f42a9295f9a74a2e3a0cdd64228.html#exhale-function-qnngraph-8h-1a3ea05f42a9295f9a74a2e3a0cdd64228),
or asynchronously using
[QnnGraph\_executeAsync()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1a690b74571029dd9f36e38cd902c86784.html#exhale-function-qnngraph-8h-1a690b74571029dd9f36e38cd902c86784).
The asynchronous version accepts additional arguments to notify the application when
execution completes, along with optional notification parameters.
#### Termination
An application can tear down contexts it has created using
[QnnContext\_free()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1ada3a582e9ab571599958c60665c7a2c8.html#exhale-function-qnncontext-8h-1ada3a582e9ab571599958c60665c7a2c8),
which in turn destroys any graphs they hold. Subsequently, an application can free a
backend handle with [QnnBackend\_free()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnBackend_8h_1ac50a3953174657f1bc4affb2be9cc3a5.html#exhale-function-qnnbackend-8h-1ac50a3953174657f1bc4affb2be9cc3a5), which invalidates all resources and handles associated to the backend handle during
the course of using contexts and graphs within it.
### Context caching
The QNN framework allows applications to cache composed graphs and contexts in binary form for
future use. Among others, one of the reasons an application may choose to do so is to save on the
time in constructing graphs, thereby reducing network initialization time. A backend may take
advantage of this approach by allowing applications to compose and cache QNN contexts offline on
an x86-based desktop machine, and subsequently loading and executing graphs from the cache at
runtime on the target device.
The diagram [QNN Context Caching Call flow](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-context-caching-call-flow-figure)
demonstrates the sequence of calls involved in context caching.
**QNN Context Caching Call flow**

A QNN context can be cached in binary form and retrieved from the backend with
[QnnContext\_getBinary()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1aa1c220389821ddf1e9d0de46b8fba0f9.html#exhale-function-qnncontext-8h-1aa1c220389821ddf1e9d0de46b8fba0f9).
The application is expected to allocate sufficient memory to hold the context cache. An estimate
of the size of the binary can be obtained with
[QnnContext\_getBinarySize()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1a3e2fe7d890123f7eb2c0ee5b26ccccba.html#exhale-function-qnncontext-8h-1a3e2fe7d890123f7eb2c0ee5b26ccccba).
The description of the contents in the binary buffer is determined by each backend individually,
and therefore is backend-specific. However, there is additional metadata that describes the
contents of the binary buffer that can be queried by the user, and is common across all backends.
It contains, among other things, all the information about graphs and input/output tensors to such
graphs that users can reference later during cache-based graph inference. For full reference,
look up [QnnSystemContext\_BinaryInfo\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnnSystemContext__BinaryInfo__t.html#exhale-struct-structqnnsystemcontext-binaryinfo-t).
Note
Tensors are uniquely identified by their IDs. Therefore they remain the same between context caching and
runtime cache-based inference. Graph input/output tensor IDs may be obtained from a context cache via
[QnnSystemContext\_BinaryInfo\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnnSystemContext__BinaryInfo__t.html#exhale-struct-structqnnsystemcontext-binaryinfo-t).
Note
Context caching succeeds only if entities within the context, such as graphs if they exist,
have been properly formed and finalized.
### Cache-based execution
The primary objective of this workflow is to allow an application to skip graph composition by
loading a precomposed context from the cached binary produced by the step above.
The [QNN Cache-based Execution Call flow](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-cache-exec-call-flow-figure)
diagram demonstrates the sequence of steps to execute graphs loaded from a cached context.
**QNN Cache-based Execution Call flow**

An application first loads a context from the cached binary into the QNN backend using
[QnnContext\_createFromBinary()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1aa261465dd9bdfe51532a9d33fe4a2fa9.html#exhale-function-qnncontext-8h-1aa261465dd9bdfe51532a9d33fe4a2fa9).
The backend returns a context handle that can be used to further
retrieve a graph constructed within that context using
[QnnGraph\_retrieve()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1a126bc4d0a25a5d47c10c44f95e13ba95.html#exhale-function-qnngraph-8h-1a126bc4d0a25a5d47c10c44f95e13ba95).
These graphs are ensured to have been finalized by virtue of having been successfully cached
in the step above. Once this is done, the application can start forward inference by supplying
input tensors, just as in the basic call flow described above.
An application can optionally choose to use additional services provided by the QNN API to inspect
the contents of the context binary produced in the step above. This eliminates the requirement
on applications to cache all context-related metadata themselves during graph preparation.
These backend-independent services are made available through the so-called *QnnSystem* API
exposed through a standalone QnnSystem library. For reference, the API
[QnnSystemContext\_getBinaryInfo()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnSystemContext_8h_1ac3ac16e68a41c7d8c141402c2ef9bd4e.html#exhale-function-qnnsystemcontext-8h-1ac3ac16e68a41c7d8c141402c2ef9bd4e)
in the diagram above provides context binary information when presented with a serialized binary buffer.
Note
Custom Op Packages registered with a backend do not get cached along with any contexts.
They have to be manually registered during the cache retrieval sequence using
[QnnBackend\_registerOpPackage()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnBackend_8h_1a95dd59ad0b59872f3649f7c363c23441.html#exhale-function-qnnbackend-8h-1a95dd59ad0b59872f3649f7c363c23441).
The application terminates the constructed context using
[QnnContext\_free()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnContext_8h_1ada3a582e9ab571599958c60665c7a2c8.html#exhale-function-qnncontext-8h-1ada3a582e9ab571599958c60665c7a2c8), as before.
## Backend API specialization
Some QNN API components provide means for backend specialization through opaque objects for which
structure definition must be provided by the backend.
The [QNN API Components Summary Table](https://docs.qualcomm.com/doc/80-63442-50/topic/api_overview.html#qnn-api-components-table) indicates API components
that provide backend specialization capability.
API specialization is optional, and is subject to the needs and discretion of a backend.
Backends publish their specialized headers at `/include/QNN//`
using the following convention:
- Headers are named as `Qnn.h`
- For example, `QnnCpuOpPackage.h` is the CPU backend’s specialization of the `QnnOpPackage.h` header,
and can be found in the `/include/QNN/CPU/` folder.
- Each backend-specialized header includes base API component headers as required. For example,
- `QnnCpuOpPackage.h` will `#include "QnnOpPackage.h"`
- Clients should include specialized headers with <Backend> in the path.
- For example, `#include "CPU/QnnCpuOpPackage.h"`
- Clients are responsible to ensure casting the correct backend-specific type into API
specialization interface. For example, to specify a custom graph configuration for the DSP backend,
a client must cast the data structure
[QnnDspGraph\_CustomConfig\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnnDspGraph__CustomConfig__t.html#exhale-struct-structqnndspgraph-customconfig-t)
defined in [DSP/QnnDspGraph.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_file_include_QNN_DSP_QnnDspGraph_h.html##file-include-qnn-dsp-qnndspgraph-h) into the generic
`QnnGraph_CustomConfig_t` used in
[QnnGraph\_Config\_t](https://docs.qualcomm.com/doc/80-63442-50/topic/structQnnGraph__Config__t.html#exhale-struct-structqnngraph-config-t) as part of
[QnnGraph\_create()](https://docs.qualcomm.com/doc/80-63442-50/topic/function_QnnGraph_8h_1acef7b5c50463d8b02bb4abd769ae5ea9.html#exhale-function-qnngraph-8h-1acef7b5c50463d8b02bb4abd769ae5ea9).
Current versions of backend specific APIs are found at the following locations:
- [QnnCpuCommon.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_program_listing_file_include_QNN_CPU_QnnCpuCommon_h.html##program-listing-file-include-qnn-cpu-qnncpucommon-h)
- [QnnGpuCommon.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_program_listing_file_include_QNN_GPU_QnnGpuCommon_h.html##program-listing-file-include-qnn-gpu-qnngpucommon-h)
- [QnnDspCommon.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_program_listing_file_include_QNN_DSP_QnnDspCommon_h.html##program-listing-file-include-qnn-dsp-qnndspcommon-h)
- [QnnHtpCommon.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_program_listing_file_include_QNN_HTP_QnnHtpCommon_h.html##program-listing-file-include-qnn-htp-qnnhtpcommon-h)
- [QnnHtaCommon.h](https://docs.qualcomm.com/doc/80-63442-50/topic/api-rst_program_listing_file_include_QNN_HTA_QnnHtaCommon_h.html##program-listing-file-include-qnn-hta-qnnhtacommon-h)
Last Published: Oct 10, 2025
[Previous Topic
API](https://docs.qualcomm.com/bundle/publicresource/80-63442-50/topics/api.md) [Next Topic
Usage Guidelines](https://docs.qualcomm.com/bundle/publicresource/80-63442-50/topics/api_usage_guidelines.md)