Thanks to visit codestin.com
Credit goes to github.com

Skip to content

The fork is out of sync with the upstream: SOLUTION #27

Description

@romancone

Hi there! I've tried to modify your patch for the QCS6490 v68 platform without success.

I investigated that the QNN/QAIRT path (chraac fork) is blocked by unsigned PD firmware, but the upstream Hexagon backend (GGML_HEXAGON=ON) uses FastRPC directly with custom HVX/HMX kernels — it does NOT use QNN stub/skel at all. This means the unsigned PD blocker may not apply to the upstream path, since it compiles its own DSP code and loads it via FastRPC directly, not through the QNN SDK's transport layer.

I won't work on the patch of this fork for v68 anymore, but I created working upstream sync instructions.

Anyone can update the code - just paste it to you agent. Hope you can use it too, @chraac

Issue: QNN Backend API Compatibility + SoC Support for Recent Upstream

Summary

The dev-refactoring branch is ~1560 commits behind upstream/master. This causes:

  1. Build failures from upstream API changes in ggml_backend_i and ggml_backend_buffer_i
  2. Missing model support (Qwen3.5, etc.) — upstream arch definitions not present
  3. Missing backend registrationqnn not in ggml_backend_load_all_from_path() search list

This issue documents the changes needed to keep the QNN fork compatible with recent upstream.


1. Merge Upstream Master

The fork needs an upstream merge. Conflicts are minimal and mechanical:

Conflict Resolution for CMakeLists.txt

Keep both QNN deprecation warning AND CURL deprecation warning (upstream added new ones).

Conflict Resolution for ggml/src/ggml-backend-reg.cpp

Keep the QNN backend registration line. Upstream may add new backends (OpenVINO, virtgpu) — keep those too.


2. API Compatibility Patches

After merging upstream, these patches are needed for the QNN backend to compile:

Patch A: New op GGML_OP_GATED_DELTA_NET

Added in upstream, needs entries in 3 QNN tables:

File: ggml/src/ggml-qnn/qnn/backend-ops.cpp

     false,  // GGML_OP_SOLVE_TRI
+    false,  // GGML_OP_GATED_DELTA_NET

File: ggml/src/ggml-qnn/qnn/op-config-caps.cpp

     {}, // GGML_OP_SOLVE_TRI
+    {}, // GGML_OP_GATED_DELTA_NET

And in the same file, op constructors table:

     nullptr,  // GGML_OP_SOLVE_TRI
+    nullptr,  // GGML_OP_GATED_DELTA_NET

Patch B: New 2D tensor fields in ggml_backend_i

Upstream added set_tensor_2d_async and get_tensor_2d_async to the interface struct.

File: ggml/src/ggml-qnn/qnn/ggml-qnn.cpp

     /* .get_tensor_async        = */ nullptr,
+    /* .set_tensor_2d_async     = */ nullptr,
+    /* .get_tensor_2d_async     = */ nullptr,

Patch C: New 2D tensor fields in ggml_backend_buffer_i

Upstream added set_tensor_2d and get_tensor_2d to the buffer interface struct.

File: ggml/src/ggml-qnn/qnn/ggml-qnn.cpp

     /* .get_tensor      = */ ggml_backend_qnn_buffer_get_tensor,
+    /* .set_tensor_2d   = */ nullptr,
+    /* .get_tensor_2d   = */ nullptr,

3. Backend Registration Fix

Upstream changed ggml_backend_load_all_from_path() to use a sorted search list. The QNN backend is missing from this list.

File: ggml/src/ggml-backend-reg.cpp — in ggml_backend_load_all_from_path(), add:

    ggml_backend_load_best("qnn", silent, dir_path);

(Place it alongside other backends like "hexagon", "opencl", etc.)


4. Build System Fixes

POSITION_INDEPENDENT_CODE

The qnn-backend static library needs PIC for linking into the MODULE target:

File: ggml/src/ggml-qnn/qnn/CMakeLists.txt

set_target_properties(qnn-backend PROPERTIES POSITION_INDEPENDENT_CODE ON)

ggml-qnn-dl.cpp in CMakeLists

The dynamic loading support file must be included:

File: ggml/src/ggml-qnn/CMakeLists.txt

ggml_add_backend_library(ggml-qnn
    ../../include/ggml-qnn.h
    ggml-qnn-dl.cpp   # <-- add this line
)

5. SoC Model Fallback + Unsigned PD Support (Recommended)

For broader SoC compatibility (QCS6490/socModel=93 not in QNN SDK enum), enhance qnn_init() in qnn-lib.cpp:

5a: Enable unsigned module at init

// In qnn_init(), before load_system():
{
    fastrpc_capability ctrl = {CDSP_DOMAIN_ID, UNSIGNED_PD_SUPPORT, 0};
    typedef int (*remote_session_control_fn)(uint32_t, void*, uint32_t);
    void * rpc_lib = dlopen("libcdsprpc.so", RTLD_NOW);
    if (rpc_lib) {
        auto fn = (remote_session_control_fn)dlsym(rpc_lib, "remote_session_control");
        if (fn) {
            fn(2 /* DSPRPC_CONTROL_UNSIGNED_MODULE */, &ctrl, sizeof(ctrl));
        }
    }
}

5b: SOC model fallback with unsigned PD config

Replace the single qnn_device_create() call with a loop trying multiple SoC configs:

uint32_t soc_models[] = {93, 29, 30, 31, 0};  // raw QCS6490, SM6350, SM8350, SM4350, none
const char *soc_names[] = {"raw93", "SM6350", "SM8350", "SM4350", "no-soc-config"};

for (int attempt = 0; attempt < 5 && !_qnn_device_handle; attempt++) {
    const QnnDevice_Config_t *configs[3] = {nullptr};
    int cc = 0;

    // Arch config: HTP V68
    configs[cc++]->option = QNN_DEVICE_CONFIG_OPTION_CUSTOM;
    configs[cc++]->customConfig = &htp_arch_config;

    if (attempt < 4) {
        // SOC config for this attempt
        configs[cc++]->option = QNN_DEVICE_CONFIG_OPTION_CUSTOM;
        configs[cc++]->customConfig = &htp_soc_config;
    }

    // Unsigned PD config: useSignedProcessDomain = false
    configs[cc++]->option = QNN_DEVICE_CONFIG_OPTION_CUSTOM;
    configs[cc++]->customConfig = &htp_unsigned_pd_config;

    qnn_device_create(_qnn_log_handle, configs, &_qnn_device_handle);
}

6. QAIRT SDK Version Note

QAIRT 2.42/2.43 reject socModel=93 (QCS6490) with INVALID_CONFIG. QAIRT 2.45+ recognizes QCS6490: "Detected Snapdragon SOC QCS6490 with 4 SOCs". The CMake config should document this requirement or detect available SDK versions.


Verification Checklist

After applying the above:

  • cmake configure succeeds
  • Full build completes (no compile errors in QNN files)
  • libggml-qnn.so loads and registers correctly
  • Qwen3.5 models load without "unknown model architecture" error
  • Backend enumeration shows qnn-npu: Hexagon NPU

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions