Skip to content

Qualcomm AI Engine Direct - Refactor QnnDlcManager#19105

Open
chenweng-quic wants to merge 1 commit intopytorch:mainfrom
CodeLinaro:dev1/chenweng/update_dlc_manager
Open

Qualcomm AI Engine Direct - Refactor QnnDlcManager#19105
chenweng-quic wants to merge 1 commit intopytorch:mainfrom
CodeLinaro:dev1/chenweng/update_dlc_manager

Conversation

@chenweng-quic
Copy link
Copy Markdown
Collaborator

@chenweng-quic chenweng-quic commented Apr 24, 2026

- Change experimental API call to formal one
@pytorch-bot
Copy link
Copy Markdown

pytorch-bot Bot commented Apr 24, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/19105

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

❌ 1 New Failure, 4 Unrelated Failures

As of commit 33d9fa0 with merge base 8e5ec80 (image):

NEW FAILURE - The following job has failed:

BROKEN TRUNK - The following jobs failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 24, 2026
@github-actions
Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@chenweng-quic chenweng-quic added the module: qnn Issues related to Qualcomm's QNN delegate and code under backends/qualcomm/ label Apr 24, 2026
@shewu-quic
Copy link
Copy Markdown
Collaborator

@claude Review this PR.

@shewu-quic
Copy link
Copy Markdown
Collaborator

Hi @abhinaykukkadapu ,

I noticed that I’m unable to request a Claude review. Is there any plan to allow collaborators access to this feature?

@abhinaykukkadapu
Copy link
Copy Markdown
Contributor

@claude review this PR.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 26, 2026

Claude finished @abhinaykukkadapu's task in 2m 49s —— View job


Review of PR #19105: Qualcomm AI Engine Direct - Refactor QnnDlcManager

  • Gather context and understand the PR
  • Review changed files in detail
  • Post review feedback

Overall: Good refactoring. Moving from the experimental libQnnModelDlc.so / QnnModel_composeGraphsFromDlc API to the formal QnnSystemDlc API via libQnnSystem.so is a solid improvement. The new API is cleaner, eliminates the memfd_create/mmap workaround, and removes a runtime dlopen/dlsym dependency. A few issues to address:


Issues

1. dlc_handle is never freed (resource leak)
QnnDlcManager.h:59RegisterGraphsFromDLC creates a QnnSystemDlc_Handle_t dlc_handle via qnn_system_dlc_create_from_binary, but never frees it after qnn_system_dlc_compose_graphs completes. Per the Qualcomm docs, there should be a corresponding QnnSystemDlc_free or equivalent cleanup call. Consider either:

  • Storing dlc_handle as a member and freeing it in Destroy(), or
  • Freeing it at the end of RegisterGraphsFromDLC if it's not needed after graph composition.

Fix this →

2. Commented-out code left in
QnnDlcManager.h:81-82 — Two commented-out variable declarations remain:

// QnnSystemContext_GraphInfo_t* graphs = nullptr;
// uint32_t num_graphs = 0;

These appear to be leftover from development and should be removed.

Fix this →

3. Dead type alias and stale include
QnnDlcManager.h:17,23 — The #include "QnnWrapperUtils.hpp" and the using QnnModel_composeGraphsFromDlc = qnn_wrapper_api::ModelError_t (*)(...) type alias are no longer used anywhere (the old composeGraphsFromDlc call site is deleted). These should be removed.

Fix this →

4. Missing error check on qnn_graph_retrieve
QnnManager.cpp:553-556 — The return value of qnn_graph_retrieve is discarded. If the graph name doesn't exist in the context, this would silently return an invalid handle that's then used in GraphFinalize. Consider checking the error:

error = backend_bundle_ptr_->implementation->GetQnnInterface().qnn_graph_retrieve(
    backend_params_ptr_->qnn_context_ptr_->GetHandle(),
    graphInfo.graphName,
    &graphHandle);
if (error != QNN_SUCCESS) {
    QNN_EXECUTORCH_LOG_ERROR("Failed to retrieve graph %s. Error %d.",
        graphInfo.graphName, QNN_GET_ERROR_CODE(error));
    return Error::Internal;
}

Fix this →


Minor / Nits

5. RegisterGraphsFromDLC is now a large inline method in the header
QnnDlcManager.h:49-104 — This ~55-line method with non-trivial logic (API calls, error handling, loops) is defined inline in the header. This works, but putting non-trivial implementations in headers increases compilation coupling and rebuild times. The host-side override was removed (ir/host/QnnDlcManager.cpp no longer has RegisterGraphsFromDLC), so the header definition is shared across host and target. Consider whether this should be a virtual method with a target-side implementation, or at minimum, a method defined in a common .cpp file.

6. Implicit nullptr safety for system_implementation_ on host path
QnnContextCommon.cpp:90-91 — On the host (IR) path, system_implementation_ is nullptr (the host QnnDlcManager doesn't load libQnnSystem.so). The ONLINE_PREPARE cache state guard protects against reaching this code, but if that invariant ever breaks, this will segfault with no diagnostic. A null check or assertion would be cheap insurance.

7. QnnBackendBundle destructor ordering
QnnBackendUnifiedRegistry.h:43-48system_implementation is reset after implementation in the destructor. Since system_implementation may hold symbols used by contexts that reference implementation, it might be safer to reset system_implementation before or alongside implementation. Worth verifying the dependency order.


Positive observations

  • Removing the memfd_create / mmap / /proc/self/fd/ workaround significantly simplifies the target-side code and removes platform-specific dependencies (__ANDROID_API__ checks).
  • Removing the libQnnModelDlc.so runtime dependency (from export_utils.py and the dlopen in target code) reduces the deployment surface.
  • The _adb error-check improvement in export_utils.py is a nice catch — previously, non-callback ADB failures were silently ignored.
  • The Destroy() reorder in QnnManager (DLC manager destroyed before backend params) is correct and prevents use-after-free.

@abhinaykukkadapu
Copy link
Copy Markdown
Contributor

Hi @abhinaykukkadapu ,

I noticed that I’m unable to request a Claude review. Is there any plan to allow collaborators access to this feature?

Sorry, i think it is currently only enabled for maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: qnn Issues related to Qualcomm's QNN delegate and code under backends/qualcomm/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants