# Multicore Device Creation and NSP Selection ## Overview Some Qualcomm platforms expose multiple HTP/NSP hardware devices, each containing one or more execution cores. By default, when no explicit device handle is provided, QNN executes using the default device configuration reported by the backend. The mapping of operations to cores is determined during context or binary generation. However, certain applications require explicit control over: - The NSP/HTP device instance used for execution - The subset of cores enabled on a device - Compatibility with pre-serialized binaries targeting a specific number of cores This section demonstrates how to query platform information, select a specific NSP device and cores, construct a custom multicore device, and create a device handle suitable for context creation. This flow extends the example in `_static/resources/multicore_device_create.txt` with explicit NSP selection support. ## When to Use This Flow Use this approach if **any** of the following apply: - Multiple NSP/HTP devices are present on the platform - Execution must be restricted to specific cores - A pre-serialized binary was compiled for a known core configuration - Explicit selection of the NSP device and enabled cores is required at runtime ## Step 1: Retrieve Platform Information The first step is to retrieve platform information from the backend. This data enumerates all available NSP/HTP devices and their associated cores. const QnnDevice_PlatformInfo_t* platformInfo = NULL; QnnDevice_getPlatformInfo(&platformInfo); Copy to clipboard The returned `platformInfo` describes the hardware devices recognized by the backend. Each device entry includes: - `deviceId` – Identifier of the NSP device instance - `numCores` – Number of cores available on the device - `cores[]` – Core descriptors associated with the device Applications should check the return status of `QnnDevice_getPlatformInfo()` and handle errors appropriately. ## Step 2: Select Target NSP Device and Cores Using the platform information, select the desired NSP device and specific cores. The example below selects two cores from a single NSP device. At runtime, the application explicitly selects which NSP device and which cores are enabled for execution. The backend does not automatically select or remap cores. uint32_t deviceId = ; uint32_t coreA = ; uint32_t coreB = ; QnnDevice_CoreInfo_t coreInfo[2]; coreInfo[0] = platformInfo->v1.hwDevices[deviceId].v1.cores[coreA]; coreInfo[1] = platformInfo->v1.hwDevices[deviceId].v1.cores[coreB]; Copy to clipboard Only the cores copied into `coreInfo` will be visible to the QNN runtime. ## Step 3: Construct a Custom Hardware Device Descriptor Next, populate a `QnnDevice_HardwareDeviceInfo_t` structure describing a logical NSP device composed of the selected cores. QnnDevice_HardwareDeviceInfo_t hwDeviceInfo; hwDeviceInfo.v1.deviceId = platformInfo->v1.hwDevices[deviceId].v1.deviceId; hwDeviceInfo.v1.deviceType = platformInfo->v1.hwDevices[deviceId].v1.deviceType; hwDeviceInfo.v1.numCores = 2; hwDeviceInfo.v1.cores = &coreInfo[0]; Copy to clipboard The `deviceType` value is propagated from the backend-reported platform information and should not be modified by the application. The logical device restricts the set of cores visible to the QNN runtime without altering the underlying hardware topology. ## Step 4: Assemble a Custom PlatformInfo Wrap the custom hardware device descriptor in a `QnnDevice_PlatformInfo_t` structure. This platform info exposes **exactly one** hardware device. QnnDevice_PlatformInfo_t customPlatformInfo; customPlatformInfo.v1.numHwDevices = 1; customPlatformInfo.v1.hwDevices = &hwDeviceInfo; Copy to clipboard ## Step 5: Create the Multicore Device Handle Pass the custom platform information to `QnnDevice_create()` using `QNN_DEVICE_CONFIG_OPTION_PLATFORM_INFO`. QnnDevice_Config_t deviceConfig; deviceConfig.option = QNN_DEVICE_CONFIG_OPTION_PLATFORM_INFO; deviceConfig.hardwareInfo = &customPlatformInfo; QnnDevice_Config_t* configList[] = { &deviceConfig, NULL }; Qnn_DeviceHandle_t multicoreDeviceHandle; QnnDevice_create(logHandle, configList, &multicoreDeviceHandle); Copy to clipboard The returned device handle represents a logical NSP device with the selected core configuration. ## Step 6: Use the Device Handle During Context Creation The custom device handle **must** be provided when creating a context, including when loading a pre-serialized binary. QnnContext_createFromBinary( backendHandle, multicoreDeviceHandle, NULL, binaryBuffer, &contextHandle); Copy to clipboard This ensures execution occurs on the specified NSP device and selected cores. ## Important Notes Warning The number of cores (numCores) exposed by the device handle must match the number of cores encoded in the pre-serialized binary. If these values do not match, context deserialization will fail. Additional considerations: - To select a **single NSP core**, set `numCores = 1` and provide one core descriptor. - The same flow applies for selecting a **single NSP device**. - This mechanism allows applications to restrict execution to a subset of the backend-reported cores available on a device. When no device handle is provided during context creation, QNN uses the default device configuration, which corresponds to Device 0 with Core 0 enabled. `QnnDevice_create()` provides low-level control over NSP/HTP execution and is recommended when explicit device or core selection is required. Last Published: Aug 06, 2026 [Previous Topic How to Use the Sample App](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/tutorial_tutorial_sample_app_linux.md) [Next Topic Sample App Tutorial](https://docs.qualcomm.com/bundle/publicresource/80-63442-10/topics/sample_app.md)