Skip to content

PML-320: shared simple builder for simple circuits through QuantumLayer and FeatureMap#223

Open
CassNot wants to merge 10 commits into
merlinquantum:release/0.4from
CassNot:PML-320-simple-unify
Open

PML-320: shared simple builder for simple circuits through QuantumLayer and FeatureMap#223
CassNot wants to merge 10 commits into
merlinquantum:release/0.4from
CassNot:PML-320-simple-unify

Conversation

@CassNot
Copy link
Copy Markdown
Contributor

@CassNot CassNot commented May 28, 2026

Summary

Introduces a single shared circuit-building helper _build_simple_circuit so that QuantumLayer.simple and FeatureMap.simple both delegate to the same method instead of duplicating it.
Also deprecates FidelityKernel.simple and the n_modes parameter on both FeatureMap.simple and FidelityKernel.simple

A follow-up ticket will extend this deprecation to KernelCircuitBuilder.build_fidelity_kernel to complete the removal of all circuit-building paths in FidelityKernel.

EDIT: input_state in FidelityKernel can now be inferred from the number of modes in the circuit or from a n_photons parameter (similar to QuantumLayer). This way, we can have a FidelityKernel with a FeatureMap.simple that stays simple, without having to precise the number of photons (it is not the case in QuantumLayer)

Related Issue

PML-320

Type of change

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

Proposed changes

  • layer_utils.py:
  1. added _build_simple_circuit(input_size, n_modes, angle_encoding_scale): the single source of truth for the LI_simple → angle_encoding → RI_simple topology.
  2. QuantumLayer.simple now delegates to _build_simple_circuit.
  • kernels.py:
  1. FeatureMap.simple now delegates to _build_simple_circuit.
  2. FeatureMap.simple: n_modes parameter deprecated; mode count is now always input_size + 1 + Marked for removal in 0.5.
  3. FidelityKernel.simple: deprecated in favour of FeatureMap.simple + FidelityKernel; duplicate DeprecationWarning suppressed when forwarding to FeatureMap.simple. Marked for removal in 0.5.
  4. Fixed None-safety bug in post-select checks (post_select_fn can be None); same fix applied in layer_utils.vet_experiment and FidelityKernel._validate_experiment (due to Perceval new release).
  5. input_state is inferred from n_photons if given, otherwise from the nb of modes
  • deprecations.py: extended sanitize_parameters to cover the new deprecated parameters.
  • test_layer_utils.py: new test file covering _build_simple_circuit.
  • test_kernels.py, test_kernels_deprecation.py: updated to assert new deprecation warnings and correct behaviour.
  • Kernels.ipynb, binary_classification.ipynb, kernels.rst: updated to use FeatureMap.simple directly and not FidelityKernel.simple (as it will be deprecated)

How to test / How to run

  1. Command lines
pytest tests/algorithms/test_layer_utils.py tests/algorithms/test_kernels.py tests/algorithms/test_kernels_deprecation.py tests/algorithms/test_layer.py -v

Documentation

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

Checklist

  • PR title includes Jira issue key (e.g., PML-126)
  • "Related Jira ticket" section includes the Jira issue key (no URL)
  • Code formatted (ruff format)
  • Lint passes (ruff)
  • Static typing passes (mypy) if applicable
  • Unit tests added/updated (pytest)
  • Tests pass locally (pytest)
  • Tests pass on GPU (pytest)
  • Test coverage not decreased significantly
  • Docs build locally if affected (sphinx)
  • With this command: SPHINXOPTS="-W --keep-going -n" make -C docs clean html the docs are built without any warning or errors.
  • New public classes/methods/packages are added in the API following the methodology presented in other files.
  • Dependencies updated (if needed) and pinned appropriately
  • PR description explains what changed and how to validate it

@CassNot CassNot requested a review from Copilot May 28, 2026 21:29
@CassNot CassNot marked this pull request as ready for review May 28, 2026 21:30
@CassNot CassNot requested a review from LF-Vigneux May 28, 2026 21:30
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 refactors the “simple” circuit construction path to reduce duplication by introducing a shared _build_simple_circuit helper used by both QuantumLayer.simple and FeatureMap.simple. It also introduces deprecations around FidelityKernel.simple and the n_modes parameter, while updating tests and docs to match.

Changes:

  • Add _build_simple_circuit(input_size, n_modes, angle_encoding_scale) in layer_utils.py and route QuantumLayer.simple / FeatureMap.simple through it.
  • Deprecate FidelityKernel.simple and deprecate (but still accept) n_modes for FeatureMap.simple and FidelityKernel.simple, including warning registry updates.
  • Update tests, warning filters, and user docs/notebook examples to use FeatureMap.simple + FidelityKernel(...) directly; also adjust post-select validation to handle None.

Reviewed changes

Copilot reviewed 8 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/algorithms/test_layer_utils.py Adds unit tests for the new shared _build_simple_circuit helper and topology parity checks.
tests/algorithms/test_kernels.py Updates kernel tests for new defaults and deprecation-warning behavior.
pytest.ini Adds warning filters for new deprecations to keep test output stable during migration.
merlin/utils/deprecations.py Extends deprecation registry to cover FeatureMap.simple.n_modes, FidelityKernel.simple, and FidelityKernel.simple.n_modes.
merlin/algorithms/layer.py Replaces inlined “simple” circuit assembly with _build_simple_circuit.
merlin/algorithms/layer_utils.py Adds _build_simple_circuit and fixes post-select None handling in vet_experiment.
merlin/algorithms/kernels.py Switches FeatureMap.simple to _build_simple_circuit, deprecates FidelityKernel.simple, and hardens post-select checks.
docs/source/user_guide/kernels.rst Updates guidance/examples away from FidelityKernel.simple.
docs/source/notebooks/Kernels.ipynb Updates notebook narrative and code examples to use FeatureMap.simple + FidelityKernel.
Comments suppressed due to low confidence (1)

merlin/algorithms/kernels.py:693

  • The n_modes argument is deprecated but still accepted; this docstring now says ValueError is raised only when input_size is outside the supported range. The implementation below can still raise ValueError for invalid n_modes values (e.g., < 2 or > 20) when callers pass the deprecated parameter, so the Raises section should mention n_modes as well (or clarify that errors may occur when using deprecated n_modes).
        Raises
        ------
        ValueError
            If ``input_size`` is outside the supported range.
        """
        # TODO: In release 0.5.x, remove n_modes handling and always use input_size + 1.
        if n_modes is None:
            n_modes = input_size + 1

        if n_modes < 2:
            raise ValueError(f"The number of modes must be at least 2, got {n_modes}")
        if input_size > 19 or n_modes > 20:
            raise ValueError(
                "Input size too large for the simple layer construction. For large inputs (with larger size than 20), please use the CircuitBuilder. Here is a quick tutorial on how to use it: https://merlinquantum.ai/quickstart/first_quantum_layer.html#circuitbuilder-walkthrough"

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

Comment on lines +186 to +192
# FeatureMap.simple deprecations
"FeatureMap.simple.n_modes": (
"The number of modes is fixed to 'input_size + 1'. "
"Use CircuitBuilder directly if you need a different mode count.",
False,
None,
),
Comment on lines +202 to +208
# FidelityKernel.simple parameter-level deprecations
"FidelityKernel.simple.n_modes": (
"The number of modes is fixed to 'input_size + 1'. "
"Use CircuitBuilder directly if you need a different mode count.",
False,
None,
),
Comment thread merlin/algorithms/kernels.py Outdated
Comment on lines +1810 to +1821
# Suppress the DeprecationWarning from FeatureMap.simple when n_modes is
# forwarded: FidelityKernel.simple already warned the caller via its own
# registry entry, so a second warning would be confusing.
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
feature_map = FeatureMap.simple(
input_size=input_size,
n_modes=n_modes,
dtype=dtype,
device=device,
angle_encoding_scale=angle_encoding_scale,
)
@LF-Vigneux LF-Vigneux self-assigned this May 28, 2026
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: a22c78e649

ℹ️ 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 on lines +74 to +78
kernel = FidelityKernel(
feature_map=feature_map,
shots=0, # exact probabilities (no sampling)
computation_space=ComputationSpace.FOCK, # allow bunched outcomes if needed
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Provide the required input_state in kernel examples

This new FidelityKernel(feature_map=...) example omits input_state, but FidelityKernel.__init__ still requires input_state: list[int] with no default. Users copying this quickstart (and the same pattern in the scikit-learn example below) will hit a TypeError before computing any kernel; add the alternating input state for the FeatureMap.simple mode count or use a builder/helper that generates it.

Useful? React with 👍 / 👎.

@CassNot CassNot added this to the v0.4 milestone May 29, 2026
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.

3 participants