# QAIRT API Migration Guide On this page - [Motivation](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#motivation) - [Impacted Systems](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#impacted-systems) - [ABI Compatibility](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#abi-compatibility) - [Ecosystem](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#ecosystem) - [Unification of QNN and SNPE](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#unification-of-qnn-and-snpe) - [QAIRT C API Design Overview](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#qairt-c-api-design-overview) - [Structureless API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#structureless-api) - [Common Patterns](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#common-patterns) - [Interface Retrieval](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#interface-retrieval) - [Migrating from QNN to QAIRT](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#migrating-from-qnn-to-qairt) - [QAIRT C++ Header-Only API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#qairt-c-header-only-api) - [Known Differences](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#known-differences) - [Migrating from SNPE to QAIRT](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#migrating-from-snpe-to-qairt) - [Code Examples](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#code-examples) - [Retrieving an Interface](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#retrieving-an-interface) - [Creating a Logger](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#creating-a-logger) - [Creating and Configuring a Backend and Context](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#creating-and-configuring-a-backend-and-context) - [Executing a Context Binary](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#executing-a-context-binary) - [Using the QAIRT API Package](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#using-the-qairt-api-package) - [Windows toolchains (MSVC)](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#windows-toolchains-msvc) - [Linux toolchains](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#linux-toolchains) - [Android toolchains](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#android-toolchains) - [Binary and Library Renaming Map](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#binary-and-library-renaming-map) - [Runtime Backend Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#runtime-backend-libraries) - [System Library](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#system-library) - [Backend Extensions](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#backend-extensions) - [Stub Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#stub-libraries) - [Prepare and Skel Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#prepare-and-skel-libraries) - [Conversion and Execution Tools](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#conversion-and-execution-tools) - [CLI Tool Migration Notes](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#cli-tool-migration-notes) - [Glossary](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#glossary) ## [Motivation](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id1) Qualcomm currently offers two AI acceleration runtime products: **Qualcomm AI Engine Direct (QNN)** and **Snapdragon Neural ProcessingEngine (SNPE)**. The **QAIRT API** consolidates these offerings into a single, unified runtime and programming model. QAIRT introduces a new API surface that is source-incompatible with QNN and SNPE, while providing a strong guarantee of **Application BinaryInterface (ABI) compatibility** across QAIRT releases. Applications built against one QAIRT version can upgrade to newer QAIRT runtime libraries without recompilation. This guide is intended to: - Explain the design principles behind QAIRT - Describe the scope and impact of migration - Provide concrete examples for migrating from QNN/SNPE to QAIRT Readers primarily interested in API concepts should review Sections 1–2. Readers migrating existing applications should focus on Sections 3–6. ### [Impacted Systems](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id2) Migration to the QAIRT API primarily affects applications that directly link against QNN or SNPE runtime libraries. Key considerations: - Applications must transition from QNN/SNPE APIs to QAIRT APIs to maintain equivalent functionality. - QAIRT runtime libraries remain forward-compatible with future QAIRT releases. - Context binaries and DLCs generated using QAIRT Converters or the QNN Context Binary Generator remain compatible. - Context binaries generated by QNN tools remain loadable by QAIRT backends, provided the binary format version is supported. - `model.so` libraries produced by QNN converters are **notcompatible** with QAIRT. These models must be reconverted into DLC format. Language requirements: - **QAIRT C API**: C99 or newer - **QAIRT C++ API**: C++17 or newer ### [ABI Compatibility](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id3) QAIRT guarantees ABI stability across releases of the runtime libraries. This ensures: - No recompilation is required when upgrading QAIRT libraries - Existing binaries remain functional with newer runtimes - Interfaces evolve only by extension, not removal ### [Ecosystem](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id4) QAIRT supports both C and modern C++ integration strategies. #### C and C++ Standards - C API: C99+ - C++ Header-Only API: C++17 The C API ensures maximum portability and ABI stability. The header-only C++ API provides a safer, more expressive interface using modern C++ patterns. ### [Unification of QNN and SNPE](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id5) QAIRT unifies QNN and SNPE functionality under a single API surface. Applications can: - Combine model-level abstractions (formerly SNPE-centric) - Use accelerator-specific backend APIs (formerly QNN-centric) Model-centric features emphasize **Deep Learning Containers (DLC)**, while backend APIs provide fine-grained control over execution, configuration, and graph management. ## [QAIRT C API Design Overview](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id6) This section will give an overview of new design principles and patterns with an emphasis on differences from QNN and SNPE APIs to QAIRT APIs. This section focuses on the QAIRT C API. It is recommended that users interested in the QAIRT C++ go to section [QAIRT C++ Header-Only API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#cpp-header-only-api). ### [Structureless API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id7) To preserve ABI compatibility, QAIRT avoids exposing compound structure in the API. Instead, all non-primitive objects are represented as: - An opaque handle - An associated interface (function table) #### Example: Struct to Handle Migration QNN-style structure: typedef struct { uint32_t dataSize; void* data; } Buffer_t; Copy to clipboard Equivalent QAIRT-style handle and interface: typedef void* BufferHandle_t; void Buffer_create(BufferHandle_t* outHandle); void Buffer_free(BufferHandle_t handle); void Buffer_setDataSize(BufferHandle_t buffer, uint32_t dataSize); void Buffer_getDataSize(BufferHandle_t buffer, uint32_t* dataSize); void Buffer_setData(BufferHandle_t buffer, void* data); void Buffer_getData(BufferHandle_t buffer, void** data); // Interface that implements these functions typedef struct { uint64_t size; Qairt_GetInterfaceFn_t getInterface; BufferCreateFn_t create; BufferFreeFn_t free; BufferSetDataSizeFn_t setDataSize; BufferGetDataSizeFn_t getDataSize; BufferSetDataFn_t setData; BufferGetDataFn_t getData; } Buffer_t; Copy to clipboard A user may have had: // Create Buffer_t instance Buffer_t buffer; // Set members buffer.dataSize = 10; buffer.data = static_cast(new uint8_t[10]); // Access previously set member if(buffer.dataSize > 5) std::cout << "Data size is large!"; // Structure is automatically deleted when it goes out of scope Copy to clipboard The corresponding QAIRT API usage looks like: // Create buffer handle and // interface. BufferHandle_t buffer; Buffer_t bufferInterface; bufferInterface->create(&buffer); // Set members bufferInterface->setDataSize(buffer, 10); void* data = static_cast(new uint8_t[10]); bufferInterface->setData(buffer, data); // Access previously set member uint32_t dataSize = 0; bufferInterface->getDataSize(buffer, &dataSize); if (dataSize > 5) std::cout << "Data size is large!"; // Explicitly free handle bufferInterface->free(buffer); Copy to clipboard #### Lifecycle Management Since clients of the QAIRT C API are not directly creating data containing structures, they manage the lifetime of the structures via creation and freeing of handles. This is the same as handle based objects in the existing QNN API, however it differs from non-handle based structures which are inherently client managed in QNN. In QAIRT, handle lifetimes are managed explicitly and fall into two distinct categories: **owning handles** and **non-owning handles**. 1. Handles are valid only while the originating library is loaded. 2. Handles returned from `*_create()` are **owning handles** and **must** be released using the corresponding `*_free()` call. The lifecycle of handles created by `*_create()` is managed by the client. 3. Handles obtained from getter-style APIs (functions other than `*_create()`) are **non-owning handles** and **must not be freedby the client**. If an owning object is modified or destroyed, any non-owning handles previously retrieved from that object become invalid and must no longer be used. Note In the QAIRT C++ Header-Only API, lifecycle management (including ownership tracking of non-owning handles) is handled automatically via RAII. ### [Common Patterns](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id8) #### Compound Types Compound types are types which are composed of multiple other types. typedef struct { uint32_t dataSize; void* data; } Buffer_t; typedef struct { uint32_t offset; float scale; } ScaleOffset_t; typedef struct { const char* name; ScaleOffset_t scaleOffset; Buffer_t buffer; } Tensor_t; Copy to clipboard Compound types in QAIRT utilize the same handle and interface pattern as before, with the ability to set and retrieve encapsulated handles on the encapsulating object. // Definition of Buffer typedef void* BufferHandle_t; Buffer_create(BufferHandle_t* outHandle); Buffer_free(BufferHandle_t inHandle); Buffer_setDataSize(BufferHandle_t buffer, uint32_t dataSize); Buffer_getDataSize(BufferHandle_t buffer, uint32_t* dataSize); Buffer_setData(BufferHandle_t buffer, void* data); Buffer_getData(BufferHandle_t buffer, void** offset); typedef struct { BufferCreate create; BufferFree free; BufferSetDataSize setDataSize; BufferGetDataSize getDataSize; BufferSetData setData; BufferGetData getData; } Buffer_t; // Definition of ScaleOffset typedef void* ScaleOffsetHandle_t; ScaleOffset_create(ScaleOffsetHandle_t* outHandle); ScaleOffset_free(ScaleOffsetHandle_t inHandle); ScaleOffset_setOffset(ScaleOffsetHandle_t so, uint32_t offset); ScaleOffset_getOffset(ScaleOffsetHandle_t so, uint32_t* offset); ScaleOffset_setScale(ScaleOffsetHandle_t so, float scale); ScaleOffset_getScale(ScaleOffsetHandle_t so, float* scale); typedef struct { ScaleOffsetCreate create; ScaleOffsetFree free; ScaleOffsetSetOffset setOffset; ScaleOffsetGetOffset getOffset; ScaleOffsetSetScale setScale; ScaleOffsetGetScale getScale; } ScaleOffset_t; // Definition of Tensor typedef void* TensorHandle_t; Tensor_create(TensorHandle_t* outHandle); Tensor_free(TensorHandle_t inHandle); Tensor_setName(TensorHandle_t tensor, const char* name); Tensor_getName(TensorHandle_t tensor, const char** name); Tensor_getBuffer(TensorHandle_t tensor, BufferHandle_t* buffer); Tensor_setBuffer(TensorHandle_t tensor, BufferHandle_t buffer); Tensor_setScaleOffset(TensorHandle_t tensor, ScaleOffsetHandle_t so); Tensor_getScaleOffset(TensorHandle_t tensor, ScaleOffsetHandle_t* so); typedef struct { TensorCreate create; TensorFree free; TensorSetName setName; TensorGetName getName; TensorSetBuffer setBuffer; TensorGetBuffer getBuffer; TensorSetScaleOffset setScaleOffset; TensorGetScaleOffset getScaleOffset; } Tensor_t; Copy to clipboard *Encapsulated handles retrieved via getters are not client-owned and mustnot be freed.* #### Unions Union-like constructs are modeled as variant-style objects, exposing: - Explicit setters for each possible type - A `getType()` function to query the active variant This avoids undefined ownership and invalid state combinations. #### Arrays Arrays are accessed through count-and-index patterns to avoid client-side allocations: Qairt_ErrorHandle_t getNumElements(InType_t in, uint32_t* numElements); Qairt_ErrorHandle_t getElementAt(InType_t in, uint32_t index, OutType_t* out); Copy to clipboard As an example, a structure in QNN like so: // An op config, with an array // of input tensors typedef struct { OpType_t type; uint32_t numInputs; Tensor_t* inputs; } OpConfig_t; Copy to clipboard Becomes the following in QAIRT: // An op config, with an array // of input tensors typedef void* OpConfigHandle_t; OpConfig_setType(OpConfigHandle_t op, OpType_t type); OpConfig_getType(OpConfigHandle_t op, OpType_t* type); OpConfig_addInput(OpConfigHandle_t op, TensorHandle_t input); OpConfig_getNumInputs(OpConfigHandle_t op, uint32_t* numInputs); OpConfig_getInputAt(OpConfigHandle_t op, uint32_t idx, TensorHandle_t* input); typedef struct { OpConfigCreate create; OpConfigFree free; OpConfigSetType setType; OpConfigAddInput addInput; OpConfigGetNumInputs getNumInputs; OpConfigGetInputAt getInputAt; } OpConfig_t; Copy to clipboard This usage in QNN: // Create op config OpConfig_t opConfig; // Set op type opConfig.type = RELU_OP; // Create and add tensor to the config opConfig.numInputs = 1; Tensor_t* inputs = new Tensor_t[1]; inputs[0].name = "Tensor"; opConfig.inputs = inputs; // Extract the input from the op std::cout << "There are " << opConfig.numInputs << " inputs: " << opConfig.inputs[0].name; Copy to clipboard Becomes the following in QAIRT: // Create op config OpConfigHandle_t opConfig; OpConfig_t opConfigInterface; opConfigInterface->create(&opConfig); // Set op type opConfigInterface->setType(opConfig, RELU_OP); // Create and add tensor to the config TensorHandle_t tensor; tensorInterface->create(&tensor); tensorInterface->setName(tensor, "Tensor"); opConfigInterface->addInput(opConfig, tensor); // Extract the input of the op TensorHandle_t retrievedTensor; uint32_t numInputs; opConfigInterface->getNumInputs(opConfig, &numInputs); opConfigInterface->getInputAt(opConfig, 0, &retrievedTensor); const char* name; tensorInterface->getName(retrievedTensor, &name); std::cout << "There are " << numInputs << " inputs: " << name; Copy to clipboard ### [Interface Retrieval](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id9) QAIRT introduces a standardized interface discovery mechanism: - All interfaces are versioned - Functions within an interface version will never be removed - Interfaces contain a `size` field allowing backward compatibility checks #### Interface IDs Each interface can be retrieved from an interface identifier – a numerical value defined in the respective component header for that interface. This value is used in the function `QairtInterface_getInterface()`. Here is a generic example ExampleInterfaceV1_t* iface; QairtInterface_getInterface(QAIRT_EXAMPLE_INTERFACE_V1_ID, (void**)&iface); iface->function(); Copy to clipboard #### Compatibility Checking Within a major interface version, it is guaranteed that behavior will not be removed when upgrading to new runtime libraries. However, it may be possible that if a client would like to use an older runtime library without recompilation that the old runtime library is missing functionality. To address these cases, each interface contains a size member which can be used to check if a function is available to be called. As an example if (iface->size > offsetof(ExampleInterfaceV1_t, function)) { iface->function(); } Copy to clipboard The C++ API performs this validation automatically and throws exceptions if unsupported functionality is called. auto example = api.make(); try { example->function(); } catch(qairt::Exception& e) { std::cerr << "Function call failed with error" << e.what(); } Copy to clipboard ## [Migrating from QNN to QAIRT](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id10) This section focuses on migrating applications that currently use the QNN API to the QAIRT API. The examples in this section use the QAIRT C++ Header-Only API, which is the recommended integration path for C++ applications. ### [QAIRT C++ Header-Only API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id11) It is recommended that C++ applications migrate to QAIRT using the QAIRT C++ Header-Only API rather than integrating directly with the C API if possible. The QAIRT C++ Header-Only API provides the following benefits: - Modern C++ abstractions for all QAIRT objects - Automatic interface retrieval and compatibility checking - RAII-based lifetime management for handles - Reduced boilerplate when porting existing QNN-based code All QAIRT C++ objects are created through a central `qairt::Api` object, which is responsible for loading the runtime library and serving as a factory for all other QAIRT objects. System-level operations (DLC loading, binary metadata) use a separate `qairt::SystemApi` object that loads `libQairtSystem.so`. qairt::Api api("libQairtHtp.so"); auto log = api.makeShared(logCallback, logLevel); auto backend = api.makeShared(*log); Copy to clipboard The lifetime of all QAIRT objects created through the factory is tied to the lifetime of the `qairt::Api` instance. ### [Known Differences](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id12) While QAIRT maintains many of the same conceptual models as QNN, there are several important differences that users should be aware of when migrating existing code. #### Tensor Properties In QNN, tensor ownership and mutability are represented using a single enumeration value. QAIRT replaces this model with a dedicated `TensorProperties` object to improve extensibility and clarity. auto tensorProperties = api.make(); tensorProperties.setIsInput(true); tensorProperties.setIsUpdateable(true); auto tensor = api.make(); tensor.setTensorProperties(tensorProperties); Copy to clipboard #### Ion Memory ION memory handles are no longer supported in QAIRT. Applications that previously used ION memory should migrate to using DMA Buffer file descriptors instead. The QAIRT memory API (`QairtMem`) provides DMA buffer management through the standard handle and interface pattern. #### Configurations QAIRT configurations are conceptually similar to those in QNN, but their structure has changed. Instead of supplying a vector of configuration objects, QAIRT uses tabular configuration objects that group related configuration options together. auto contextConfig = api.make(); contextConfig.setPersistentBinary(true); contextConfig.setPriority(QAIRT_PRIORITY_HIGH); Copy to clipboard #### Error Handling The standalone Error API has been removed in QAIRT. ### [Migrating from SNPE to QAIRT](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id13) SNPE users will find that the familiar builder pattern is preserved in QAIRT through `QairtSystemBuilder`, which provides a high-level API that closely mirrors the SNPE `SNPEBuilder` workflow. #### QairtSystemBuilder `QairtSystemBuilder` follows the same fluent builder pattern as `SNPEBuilder`. It accumulates configuration via setter calls and performs the full backend + context + graph initialization in a single `build()` call: auto systemApi = std::make_shared("libQairtSystem.so"); auto systemDlc = systemApi->makeShared("model.dlc"); auto builder = systemApi->make(); builder.setDlc(systemDlc) .setBackendType(qairt::BackendType::Htp) .setLogLevel(qairt::LogLevel::Warn) .setPerfProfile(qairt::PerfProfile::HighPerformance); auto qairt = builder.build(); // fully initialized, ready for inference Copy to clipboard #### Execution After building, inference follows a similar pattern to SNPE — get graph info, prepare buffers, execute: auto& graphInfo = qairt.getGraphInfoAt(0); auto& inputs = graphInfo.getGraphInputs(); auto& outputs = graphInfo.getGraphOutputs(); // Allocate and fill input/output buffers... qairt.executeGraph(graphInfo.getGraphName(), inputData, outputData); Copy to clipboard #### API Mapping | SNPE | QAIRT | | --- | --- | | `SNPEBuilder` | `qairt::QairtSystemBuilder` | | `SNPEBuilder::setDlcPath()` | `builder.setDlc(systemDlc)` | | `SNPEBuilder::setPerformanceProfile()` | `builder.setPerfProfile(qairt::PerfProfile::...)` | | `SNPEBuilder::setRuntimeProcessorOrder()` | `builder.setBackendType(qairt::BackendType::...)` | | `SNPE::execute()` | `qairt.executeGraph(graphName, inputs, outputs)` | | `libSNPE.so` | Per-backend: `libQairtCpu.so`, `libQairtHtp.so`, etc. | #### Key Differences from SNPE - **Per-backend libraries**: SNPE used a single `libSNPE.so` for all backends. QAIRT provides separate backend libraries (`libQairtCpu.so`, `libQairtHtp.so`, etc.), giving applications finer control over which accelerators are loaded. - **DLC compatibility**: Existing SNPE DLC files are compatible with QAIRT and can be loaded directly via `qairt::SystemDlc`. - **Low-level access**: In addition to the high-level builder path, QAIRT also exposes the Backend → Context → Graph lifecycle directly (see [QAIRT C++ Header-Only API](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#cpp-header-only-api)) for applications that need finer-grained control. ## [Code Examples](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id14) This section provides examples of basic API usage of the QAIRT C++ Header-Only API. More detailed examples can be found in the QAIRT sample application (QairtSampleApp.cpp). Users are encouraged to reference the sample code for comprehensive usage patterns. ### [Retrieving an Interface](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id15) The first step in using the QAIRT API is to retrieve an interface. This is easily done with the QAIRT C++ API. qairt::Api api("libQairtHtp.so"); auto tensor = api.make(); Copy to clipboard Interfaces are retrieved lazily and automatically as objects are created through the API factory. ### [Creating a Logger](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id16) To enable logging, a user can create a shared log object. This object may be shared across multiple QAIRT components and configured using a callback. auto log = api->makeShared( [](const char* fmt, QairtLog_Level_t level, uint64_t timestamp, void* /*userData*/, va_list argp) { (void)timestamp; char str[1000]; auto deferredVsnprintf = [&] { str[0] = '\0'; vsnprintf(str, sizeof(str), fmt, argp); return const_cast(str); }; std::cerr << "\e[93m#LOG2#\t" << deferredVsnprintf() << "\e[0m\n"; }, logLevel); Copy to clipboard ### [Creating and Configuring a Backend and Context](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id17) After creating the API object, a backend instance can be created and configured with backend-specific options. qairt::Api api("libQairtHtp.so"); auto backend = api.makeShared(*log); // Core context configuration auto contextConfig = api.make(); contextConfig.setPersistentBinary(true); contextConfig.setPriority(QAIRT_PRIORITY_HIGH); // HTP-specific context configuration auto htpConfig = api.make(); htpConfig.setEnableWeightSharing(true); // Group registration controls shared spill/fill memory between contexts auto groupReg = api.make(); groupReg.setMaxSpillFill(1024); htpConfig.setGroupRegistration(groupReg); // Custom configs extend the core ContextCustomConfig interface, // allowing backend-specific options to be passed through the // backend-agnostic ContextConfiguration. contextConfig.setCustomConfig(htpConfig); auto context = backend->createContext(contextConfig); Copy to clipboard Each QAIRT component (Backend, Context, Graph, Device) has its own custom config hierarchy. Backend-specific types like `HtpContextCustomConfig` extend the core `ContextCustomConfig` interface, allowing backend-agnostic code to pass through backend-specific options. Refer to the QAIRT C++ headers under `QairtCpp/HTP/`, `QairtCpp/GPU/`, and `QairtCpp/DSP/` for the full set of backend-specific configuration options. ### [Executing a Context Binary](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id18) This example demonstrates loading and executing a context binary using the QAIRT API. auto context = backend->createContextFromBinary(config, rawBuffer, profile); auto graph = context->retrieveGraph("GraphName"); graph->finalize(); graph->execute(inputs, outputs); Copy to clipboard More details on the usage mechanics can be found in the sample application. ## [Using the QAIRT API Package](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id19) The QAIRT package includes: - QAIRT C and C++ headers - CPU, GPU, HTP, DSP, and LPAI backend libraries - Sample applications - CLI tools (`qairt-net-run`, `qairt-dlc-prepare`) Supported platforms (runtime execution): - Linux x86\_64 - Android AArch64 - Windows x64 Note QAIRT prebuilt tools and libraries are provided for multiple toolchains and architectures across these platforms, as outlined below. ### [Windows toolchains (MSVC)](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id20) - `x86_64-windows-msvc` - `aarch64-windows-msvc` - `arm64x-windows-msvc` These toolchains provide `qairt-net-run`, `qairt-dlc-prepare`, and matching QAIRT CPU/GPU/HTP runtime libraries (`QairtCpu`, `QairtGpu`, `QairtHtp`). ### [Linux toolchains](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id21) - `x86_64-linux-clang` - `aarch64-oe-linux-gcc8.2` - `aarch64-oe-linux-gcc9.3` - `aarch64-oe-linux-gcc11.2` - `aarch64-ubuntu-gcc9.4` Linux distributions include `qairt-net-run` and `qairt-dlc-prepare` for each supported toolchain. ### [Android toolchains](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id22) - `aarch64-android` Android packages provide QAIRT execution and preparation tools targeting AArch64 devices. ## [Binary and Library Renaming Map](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id23) ### [Runtime Backend Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id24) | QNN | QAIRT | Notes | | --- | --- | --- | | libQnnCpu.so / QnnCpu.dll | libQairtCpu.so / QairtCpu.dll | | | libQnnGpu.so / QnnGpu.dll | libQairtGpu.so / QairtGpu.dll | | | libQnnHtp.so / QnnHtp.dll | libQairtHtp.so / QairtHtp.dll | | | libQnnDsp.so | libQairtDsp.so | | | libQnnLpai.so | libQairtLpai.so | | ### [System Library](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id25) | QNN | QAIRT | Notes | | --- | --- | --- | | libQnnSystem.so / QnnSystem.dll | libQairtSystem.so / QairtSystem.dll | Ships under `QAIRT/lib/` in the SDK | ### [Backend Extensions](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id26) The backend extension libraries have been renamed from `NetRunExtensions` to `BackendExtensions`: | QNN | QAIRT | | --- | --- | | libQnnCpuNetRunExtensions.so | libQairtCpuBackendExtensions.so | | libQnnGpuNetRunExtensions.so | libQairtGpuBackendExtensions.so | | libQnnHtpNetRunExtensions.so | libQairtHtpBackendExtensions.so | | libQnnDspNetRunExtensions.so | libQairtDspBackendExtensions.so | | libQnnLpaiNetRunExtensions.so | libQairtLpaiBackendExtensions.so | ### [Stub Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id27) Stub libraries follow a consistent renaming pattern: | QNN | QAIRT | | --- | --- | | libQnnHtpV##Stub.so | libQairtHtpV##Stub.so | | libQnnDspV##Stub.so | libQairtDspV##Stub.so | | libQnnLpaiStub.so | libQairtLpaiStub.so | ### [Prepare and Skel Libraries](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id28) | QNN | QAIRT | Notes | | --- | --- | --- | | libQnnHtpPrepare.so | libQairtHtpPrepare.so | Offline graph preparation | | libQnnHtpV{ver}Skel.so | libQairtHtpV{ver}Skel.so | Hexagon target libraries | | libQnnDspV{ver}Skel.so | libQairtDspV{ver}Skel.so | Hexagon target libraries | ### [Conversion and Execution Tools](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id29) | QNN | QAIRT | Notes | | --- | --- | --- | | qnn-net-run | qairt-net-run | See [CLI Tool Migration Notes](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#cli-tool-migration-notes) | | qnn-context-binary-generator | qairt-dlc-prepare | Renamed to reflect DLC-centric model | ### [CLI Tool Migration Notes](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id30) #### qairt-net-run `qairt-net-run` replaces `qnn-net-run` with a simplified interface focused on DLC-based execution. **New flags:** | Flag | Description | | --- | --- | | `--use_cpu`, `--use_gpu`, `--use_htp` | Convenience backend selection (no need to specify `.so` path) | | `--use_high_level_apis` | Uses simplified high-level QAIRT APIs for model execution. This
flag provides a migration path for SNPE users accustomed to the
higher-level `SNPE::execute()` style interface. | | `--input_name` / `--input_dimensions` | Runtime tensor resizing (e.g.,
`--input_name=input --input_dimensions=1,512,512,3`) | **Renamed flags:** | qnn-net-run | qairt-net-run | | --- | --- | | `--dlc_path` | `--input_dlc` | | `--retrieve_context` | `--input_context_binary` | **Removed (not applicable in QAIRT):** | Flag | Reason | | --- | --- | | `--model` / `--model_prefix` | `model.so` format is not supported; use DLC | | `--op_packages` | Op packages are not supported in QAIRT | #### qairt-dlc-prepare `qairt-dlc-prepare` replaces `qnn-context-binary-generator`. The tool name reflects the shift to DLC as the primary model format. The core functionality — offline preparation of context binaries — remains the same. ## [Glossary](https://docs.qualcomm.com/doc/80-63442-10/topic/migration-guide.html#id31) - ABI (Application Binary Interface) - The low-level binary contract between compiled applications and libraries. - Backend - An accelerator-specific runtime implementation (CPU, GPU, HTP, DSP, LPAI). - Backend Extension - The mechanism by which backends provide custom configuration options (e.g., HTP weight sharing, group registration) that extend the core QAIRT API. Backend extensions allow backend-specific types to be passed through backend-agnostic interfaces like `ContextConfiguration`. - Context Binary - A serialized execution context generated by QAIRT or QNN tools. - DLC (Deep Learning Container) - The primary model representation format used by QAIRT. - DMA Buffer - Direct Memory Access buffer; the replacement for ION memory handles in QAIRT for shared memory between application and accelerator. - Handle - An opaque reference to a runtime-managed object. - Interface - A versioned function table used to operate on handles. - Non-owning Handle - A handle whose lifetime is managed by another object and **mustnot be freed by the client**. Non-owning handles are typically returned by getter-style APIs (i.e., functions other than `_create()`), and they become invalid if the owning object is modified or destroyed. - QAIRT - Qualcomm AI Runtime, a unified API consolidating QNN and SNPE. - QairtSystemBuilder - A fluent builder class that provides a high-level API for QAIRT initialization, analogous to SNPE’s `SNPEBuilder`. - RAII - Resource Acquisition Is Initialization; a C++ lifetime management pattern. - SystemApi - A separate API entry point (`qairt::SystemApi`) for system-level operations including DLC loading, binary metadata inspection, and high-level builder construction. Last Published: Aug 06, 2026 [Previous Topic Windows](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/tutorial_sample_app_windows.md) [Next Topic C API](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/index_c-api.md)