Skip to content

PML-286 g2 noise#222

Open
LF-Vigneux wants to merge 39 commits into
merlinquantum:release/0.4-PML-277-SLOS-noise-and-differentiationfrom
LF-Vigneux:PML-286-g2-g2_dist
Open

PML-286 g2 noise#222
LF-Vigneux wants to merge 39 commits into
merlinquantum:release/0.4-PML-277-SLOS-noise-and-differentiationfrom
LF-Vigneux:PML-286-g2-g2_dist

Conversation

@LF-Vigneux
Copy link
Copy Markdown
Contributor

Summary

Added the g2 noise simulations in the MerLin's quantum layer's pipeline. The simulations can now be .

Related Issue

PML-286

Type of change

  • Bug fix
  • New feature
  • Documentation update
  • Refactor / Cleanup
  • Performance improvement
  • CI / Build / Tooling
  • Breaking change (requires migration notes)

Proposed changes

  • There is now a NoisyG2SLOSComputeGraph class that is used whenthere is g2 noise.
  • This class simulates the probs of the circuit with the g2 noise.
  • The same modifications in the pipeline as the NoisySLOSComputeGraph for indistinguishability wew done plus:
    • Added a guard preventing grouping strategies with g2 noises as the output is not a tensor and is sector dependant.
    • Changed the sampling function handling in the quantum layer. We do not pass a sampling function anymore but a class that has a normal sampler and a g2 sampler that samples across all photon sectors.
  • Added new types to handle those photon sectors.

How to test / How to run

  1. Command lines
pytest -q

Performance considerations (optional)

  • G2 SLOS simulations are heavier as expected

Documentation

  • User docs updated (Sphinx)
  • Examples / notebooks updated
  • Docstrings updated
  • Updated the API

@CassNot CassNot requested a review from Copilot May 28, 2026 16:11
@CassNot
Copy link
Copy Markdown
Contributor

CassNot commented May 28, 2026

@codex review with a focus on scaling and memory usage

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 55188a3099

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread merlin/pcvl_pytorch/slos_torchscript.py
Comment thread merlin/core/process.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for simulating g2 (multi-photon emission) source noise in Merlin’s SLOS-based quantum pipeline by introducing a sectored (per photon-number) probability output and wiring it through measurement + sampling + docs/tests.

Changes:

  • Introduces NoisyG2SLOSComputeGraph and a new SectoredDistribution / SectorResult output type to represent probabilities across photon-number sectors.
  • Updates the measurement pipeline to accept a sampling process object (with a g2-aware sampling method) and blocks grouping when outputs are sectored.
  • Adds extensive regression/unit tests and Sphinx API/docs entries for the new g2 functionality.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/pcvl_pytorch/test_noisy_g2_slos.py New comprehensive test suite for g2 sectored outputs, normalization, gradients, and Perceval comparison.
tests/measurement/test_measurement_strategy.py Updates tests to use the new sampler object interface instead of a sampling function.
tests/algorithms/test_noise_contract.py Updates/extends noise contract tests to reflect g2 now being supported and adds regressions.
merlin/pcvl_pytorch/slos_torchscript.py Routes source-noise graph building to NoisyG2SLOSComputeGraph when g2 is present.
merlin/pcvl_pytorch/noisy_slos.py Implements NoisyG2SLOSComputeGraph and adds plumbing for shared SLOS subgraphs.
merlin/pcvl_pytorch/init.py Exports NoisyG2SLOSComputeGraph from the pcvl_pytorch package.
merlin/measurement/strategies.py Allows SectoredDistribution through distribution strategies; blocks grouping for g2.
merlin/measurement/process.py Adds SamplingProcess.pcvl_sampler_g2 for sampling over sectored outputs.
merlin/core/sectored_distribution.py Adds new core data classes representing sectored probability outputs.
merlin/core/process.py Updates computation process to return SectoredDistribution for g2 noisy simulations and mix superpositions per sector.
merlin/core/init.py Re-exports SectoredDistribution and SectorResult.
merlin/algorithms/layer.py Extends QuantumLayer.forward typing/logic to pass sectored distributions through measurement.
merlin/algorithms/layer_utils.py Removes “g2 not implemented” guard so g2 source noise is allowed.
merlin/algorithms/kernels.py Explicitly rejects g2 noise for kernels (raises NotImplementedError).
docs/source/quantum_expert_area/noisy_simulations.rst Documents new constraint: no grouping when g2>0 due to multiple photon sectors.
docs/source/api_reference/api/merlin.pcvl_pytorch.noisy_slos.rst Adds API docs for NoisyG2SLOSComputeGraph.
docs/source/api_reference/api/merlin.core.sectored_distribution.rst Adds API docs page for sectored distribution classes.
docs/source/api_reference/api/merlin.core.rst Adds the new core module to the API reference index.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread merlin/measurement/process.py
Comment thread merlin/pcvl_pytorch/noisy_slos.py Outdated
Comment thread merlin/pcvl_pytorch/noisy_slos.py
Comment thread merlin/measurement/strategies.py Outdated
Comment thread docs/source/quantum_expert_area/noisy_simulations.rst
Comment thread merlin/core/sectored_distribution.py Outdated
Comment thread tests/algorithms/test_noise_contract.py Outdated
Comment thread merlin/measurement/strategies.py
Comment thread merlin/pcvl_pytorch/noisy_slos.py Outdated
@CassNot CassNot added this to the v0.4 milestone May 28, 2026
@ben9871 ben9871 self-assigned this May 29, 2026
Copy link
Copy Markdown
Contributor

@ben9871 ben9871 left a comment

Choose a reason for hiding this comment

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

Some issues with behaviour of G2 and accessibility of keys to be fixed before merging

Comment thread merlin/measurement/strategies.py Outdated
f"A grouping strategy cannot be applied to the output of a simulation with g2 noise. Indeed, since this noise creates input states with more photons than expected, multiple photon sectors are explored. The fock spaces explored are m={distribution.sectors[0].n_modes} modes and n_photons={min(distribution._photon_map.keys())} to 2*n_photons={max(distribution._photon_map.keys())} that all have different space dimensions. To still apply a grouping strategy, you can iterate over the :class:`~merlin.core.sectored_distribution.SectorResult`s of the :class:`~merlin.core.sectored_distribution.SectoredDistribution` and apply one grouping per sector."
)
for sector_result in distribution.sectors:
sector_result.tensor = apply_photon_loss(sector_result.tensor)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This reuses the photon-loss and detector transforms built from the original n_photons Fock basis for all g2 sectors. Higher sectors have different basis-sizes, so post-measurement loss/detectors either crash or would map against the wrong basis.

)

# Creating the n_photons + num_photons_added sector
sector = SectorResult(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SectorResult.keys is never populated, so the output does not actually carry the sector basis metadata promised by the API. This is also why the measurement layer cannot safely build per-sector loss/detector transforms.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed in next commit

Comment thread merlin/pcvl_pytorch/noisy_slos.py
Comment thread merlin/core/sectored_distribution.py Outdated
"""Returns the total probability across the sectors."""
total_prob = 0.0
for sector in self.sectors:
total_prob += sector.tensor.sum().item()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

total_probability() should return a tensor, not a Python float. The .item() calls detach the result from autograd, which works against the differentiable output contract.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed in next commit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed in next commit

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants