Skip to content

Conversation

@rniczh
Copy link

@rniczh rniczh commented Jan 6, 2026

Context:

from catalyst import *
import pennylane as qml

qml.capture.enable()

@qjit
@qml.qnode(qml.device("lightning.qubit", wires=3, shots=10))
def circuit():
    with qml.allocate(2) as qs:
        qml.X(qs[1])

    return qml.sample(wires=[0, 1])

print(circuit())

It get unexpected result due to the aux wires involved.

[[0 0]
 [0 1]
 [0 0]
 [1 0]
 [0 0]
 [0 0]
 [0 1]
 [0 0]
 [1 0]
 [0 0]]

Description of the Change:

Only take the device wires for generating samples
Compact state vector before measurement.

For state vector normalization:

$|\psi| = \sqrt{\sum_i |\psi_i|^2}$
$normalized_i = \psi_i / |\psi|$

Benefits:

Possible Drawbacks:

Related GitHub Issues:

PennyLaneAI/catalyst#2339
[[sc-107206]]

@github-actions
Copy link
Contributor

github-actions bot commented Jan 6, 2026

Hello. You may have forgotten to update the changelog!
Please edit .github/CHANGELOG.md with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@blacksmith-sh

This comment has been minimized.

Copy link
Contributor

@dime10 dime10 left a comment

Choose a reason for hiding this comment

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

Thank you @rniczh !

@blacksmith-sh

This comment has been minimized.

@codecov
Copy link

codecov bot commented Jan 7, 2026

Codecov Report

❌ Patch coverage is 99.58333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.89%. Comparing base (e7d82a2) to head (6c8cdb2).

Files with missing lines Patch % Lines
...rs/lightning_qubit/catalyst/LightningSimulator.cpp 98.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff               @@
##           v0.44.0_rc    #1321      +/-   ##
==============================================
- Coverage       96.01%   93.89%   -2.13%     
==============================================
  Files             307      243      -64     
  Lines           46923    40264    -6659     
==============================================
- Hits            45055    37804    -7251     
- Misses           1868     2460     +592     
Flag Coverage Δ
unit_tests 93.89% <99.58%> (-2.13%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@blacksmith-sh

This comment has been minimized.

@maliasadi maliasadi self-requested a review January 8, 2026 15:06
Copy link
Member

@maliasadi maliasadi left a comment

Choose a reason for hiding this comment

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

Thanks @rniczh! A few things:

  • If we need this to go out with the release, you will need to rebase it against #1317 and sync ASAP with @jzaia18
  • Update Lighnting-Kokkos and Lightning-GPU catalyst impl similar to Lightning-Qubit
  • Please add a changelog entry for this fix

@rniczh rniczh changed the base branch from master to v0.44.0_rc January 8, 2026 15:19
@jzaia18 jzaia18 added this to the 0.44.0 milestone Jan 8, 2026
@rniczh rniczh force-pushed the rniczh/fix-dynamic-wires-with-samples branch from d3abf70 to 6e9f177 Compare January 8, 2026 15:32
@rniczh rniczh changed the base branch from v0.44.0_rc to master January 8, 2026 15:37
@rniczh rniczh changed the base branch from master to v0.44.0_rc January 8, 2026 15:37
Copy link
Contributor

@jzaia18 jzaia18 left a comment

Choose a reason for hiding this comment

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

Nice work Hongsheng! Just a few questions and comments. Is there any reason we're implementing this for lightning.qubit but not the other devices? Does this issue exist for the others as well? nvm, just saw Ali already addressed this

@rniczh rniczh removed the ci:use-gpu-runner Enable usage of GPU runner for this Pull Request label Jan 8, 2026
*(this->device_sv)};
}

void LightningGPUSimulator::CompactStateVector() {
Copy link
Member

Choose a reason for hiding this comment

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

Where are these tested? I couldn't find any tests for these methods for all devices.

Copy link
Author

Choose a reason for hiding this comment

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

The function is triggered by getMeasurements(), ensuring that any test executing the measurement process also updates the state vector. Currently, only one test case is added (the one that reported from the issue PennyLaneAI/catalyst#2339). The specific test can be found here:

https://github.com/PennyLaneAI/pennylane-lightning/pull/1321/changes#diff-6f0e99f87b0a9753689936392636b52eb19b81aac144b24d12de297f3c617447R335

Copy link
Member

@maliasadi maliasadi Jan 9, 2026

Choose a reason for hiding this comment

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

Will this be added to Catalyst for the release?

per our offline discussions, what if these aux wires are entangled, we should test and add some handling mechanism for these cases in both Lightning & Catalyst?

auto GenerateSamples(size_t shots) -> std::vector<size_t>;

// Compact state vector by removing released qubits
void CompactStateVector();
Copy link
Member

Choose a reason for hiding this comment

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

minor: this is the style we've been following for a while:

Suggested change
void CompactStateVector();
void compactStateVector();

Copy link
Member

Choose a reason for hiding this comment

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

Should we call this reducedStateVector instead of compact?

Copy link
Author

Choose a reason for hiding this comment

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

Sure! I updated the name here: a5e2132

@jzaia18
Copy link
Contributor

jzaia18 commented Jan 8, 2026

Could you also bump the rc version to 3 within pennylane_lightning/core/_version.py?

@rniczh
Copy link
Author

rniczh commented Jan 9, 2026

Could you also bump the rc version to 3 within pennylane_lightning/core/_version.py?

Sure abd373d

@rniczh rniczh added the ci:use-gpu-runner Enable usage of GPU runner for this Pull Request label Jan 9, 2026
Copy link
Contributor

@jzaia18 jzaia18 left a comment

Choose a reason for hiding this comment

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

Looking good, just 1 last comment

@paul0403 paul0403 requested a review from mlxd January 9, 2026 18:43
@jzaia18 jzaia18 removed this from the 0.44.0 milestone Jan 9, 2026
Copy link
Contributor

@dime10 dime10 left a comment

Choose a reason for hiding this comment

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

Nice work! Let's get this across the finish line to make sure the dynamic allocation feature actually works :)

Only one question to resolve really:

Comment on lines 119 to 121
// maintained,
// in particular: measurements must not compute results for released
// qubits, only for active/allocated qubits
Copy link
Contributor

Choose a reason for hiding this comment

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

We can remove the TODO now :)

* @param data State vector data to normalize.
*/
template <class ComplexT, class Alloc = std::allocator<ComplexT>>
inline void normalizeStateVector(std::vector<ComplexT, Alloc> &data) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wanted to mention I believe most devices already have a normalize method, since it's needed for the measure implementation:

Comment on lines -122 to -123
// TODO: We don't have to check whether the released qubit is pure, but it
// is something we can add easily to catch program errors.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should get consensus on the desired behaviour. I don't think this needs to be a big thing, just picking one of the options and checking with product what they think. As far as I know the options are:

  • (1) it is enforced that qubits must be pure (disentangled) before release
    • implementation: (simulator-only) raise an error if the user releases an entangled qubit
    • benefit: nice to catch (likely) programming errors for the user, no undefined or non-deterministic behaviour
    • issues:
      • if an entire subset of qubits is released at once, it should be okay if they are entangled with each other, but here we do the release one-by-one so that complicates the detection
      • takes a bit of work each qubit release
  • (2) it is well-defined what happens when qubits are not pure:
    • implementation: reset affected qubits projecting the remainder of state onto of the two subspaces
      • this could be random (like on hw) or a forced projection onto 0 for example (simulator-only)
      • since we want the behaviour to be well defined and observable, I think this should happen immediately upon release (e.g. a snapshot would reflect this right away, but I'm not sure that even with option 3 the partial statevector would ever be observable?)
    • benefit: can be deterministic still, is observable
    • issues: takes a bit of work each qubit release
  • (3) it is undefined behaviour what happens when releasing non-pure qubits:
    • implementation: undefined means we can do whatever is convenient, but at the very least we have to project (and compact) the state before measurement processes and before handing out fresh qubits that reuse previously deallocated space in the statevector
    • benefit: could be faster to delay than doing something immediately like in the other options
    • issues: least clean?

Although, even if the projection is done lazily we could still raise an error at that point, it might just be less precise than if we do it immediately. So maybe there is only two choices (error or silent projection), and the question of whether to do it eagerly or lazily is orthogonal to that choice. Another variant could check for an error eagerly, but compact lazily. Or another one could be have a safe release and an unsafe release, which can be toggled by the user.

Copy link
Contributor

Choose a reason for hiding this comment

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

My gut decision would probably be option 1 for safety (and compact later, and/or safety toggle).

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

Labels

ci:use-gpu-runner Enable usage of GPU runner for this Pull Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants