Skip to content

Fix/issue 4268 forward declared adjoint#4306

Open
KevinSailema wants to merge 3 commits intoNVIDIA:mainfrom
KevinSailema:fix/issue-4268-forward-declared-adjoint
Open

Fix/issue 4268 forward declared adjoint#4306
KevinSailema wants to merge 3 commits intoNVIDIA:mainfrom
KevinSailema:fix/issue-4268-forward-declared-adjoint

Conversation

@KevinSailema
Copy link
Copy Markdown
Contributor

Fixes #4268

This PR fixes a crash in apply-op-specialization when adjoint is requested for a forward-declared kernel whose body is not available in the current translation unit.

Instead of crashing with an internal assertion, the compiler now emits a clear diagnostic and fails gracefully.

Root Cause

During specialization, the pass attempted to generate an adjoint variant for declaration-only functions. Since no function body exists, the transformation pipeline eventually hit an invalid internal state and aborted with an assertion.

What Changed

  • Added a guard in apply-op-specialization before generating adjoint/adjoint-control variants.
  • If the target function is declaration-only, emit a diagnostic:
    cannot create adjoint variant for forward-declared kernel ... (kernel body is unavailable in this translation unit)
  • Added a regression test that reproduces this case and checks for the expected error.

Validation

  • Regression test passes: the expected diagnostic is emitted.
  • Original 2-translation-unit repro now behaves correctly:
    • prep.cpp compiles
    • main.cpp reports the diagnostic
    • no internal assertion crash (isKnownSentinel) appears

Impact

  • No behavior change for valid kernels with available definitions.
  • Unsupported forward-declared adjoint now fails predictably with a user-facing error instead of a compiler crash.

@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented Apr 12, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@atgeller
Copy link
Copy Markdown
Collaborator

atgeller commented Apr 13, 2026

/ok to test 7d0aca7

Command Bot: Processing...

github-actions Bot pushed a commit that referenced this pull request Apr 14, 2026
@github-actions
Copy link
Copy Markdown

CUDA Quantum Docs Bot: A preview of the documentation can be found here.

auto &variant = variantIter->second;

// We cannot synthesize an adjoint if only a declaration is available.
if ((variant.needsAdjointVariant || variant.needsAdjointControlVariant) &&
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a variant.needsControlVariant to the check?

A user who writes quake.apply [%ctl] @prep %q against a forward-declared @prep will hit the same class of crash this PR is fixing, just through a different code path.

e.g.

// ctl_decl.qke
module {
  func.func private @prep(!quake.ref)
  func.func @kernel() {
    %ctl = quake.alloca !quake.ref
    %q = quake.alloca !quake.ref
    quake.apply @prep [%ctl] %q : (!quake.ref, !quake.ref) -> ()
    return
  }
}
$ cudaq-opt --apply-op-specialization ctl_decl.qke
cudaq-opt: /opt/llvm/include/llvm/ADT/ilist_iterator.h:138: ...
  Assertion `!NodePtr->isKnownSentinel()' failed.
Aborted (core dumped)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apply-op-specialization crashes instead of erroring when adjointing a forward-declared kernel

3 participants