Repository: PennyLaneAI/pennylane
Pull request #7136 (2025-03-21 19:20:04)

Revert "Fixes `Wires` objects as wire labels bug (#6933)"
This reverts commit e0b21748136c69e924be7d776c2588f47508f0b1.

### Before submitting

Please complete the following checklist when submitting a PR:

- [x] All new features must include a unit test.
      If you've fixed a bug or added code that should be tested, add a test to the
      test directory!

- [x] All new functions and code must be clearly commented and documented.
      If you do make documentation changes, make sure that the docs build and
      render correctly by running `make docs`.

- [x] Ensure that the test suite passes, by running `make test`.

- [x] Add a new entry to the `doc/releases/changelog-dev.md` file, summarizing the
      change, and including a link back to the PR.

- [x] The PennyLane source code conforms to
      [PEP8 standards](https://www.python.org/dev/peps/pep-0008/).
      We check all of our code against [Pylint](https://www.pylint.org/).
      To lint modified files, simply `pip install pylint`, and then
      run `pylint pennylane/path/to/file.py`.

When all the above are checked, delete everything above the dashed
line and fill in the pull request template.

------------------------------------------------------------------------------------------------------------

**Context:** Due to non-negligible performance impacts, PR #6933 is to be reverted. Flattening each wire contents introduced overheads between 5-60% in benchmarking, and will be reassessed for support in a follow-up release.

**Description of the Change:** As above.

**Benefits:** Restores lost performance.

**Possible Drawbacks:** Reintroduces incompatibility for nesting of wires 

**Related GitHub Issues:**
[sc-87017]

andrijapau: So long 🫡 , thanks both for the help here. 🥇 

Excited to see how we can improve on it in Q2  😎 ❗ 
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7136?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.62%. Comparing base [(`35f705f`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/35f705f6494425704257d0e5479ee8fbb48a3cc6?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) to head [(`2e319b5`)](https://app.codecov.io/gh/PennyLaneAI/pennylane/commit/2e319b574f2db8118c39f0ec42892ef64631159f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).
> Report is 2 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff            @@
##           master    #7136    +/-   ##
========================================
  Coverage   99.62%   99.62%            
========================================
  Files         503      505     +2     
  Lines       49024    49250   +226     
========================================
+ Hits        48839    49065   +226     
  Misses        185      185            
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/PennyLaneAI/pennylane/pull/7136?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index ff8fa4500..8baad71e1 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -795,6 +795,9 @@
 
 <h3>Bug fixes 🐛</h3>
 
+* Revert [(#6933)](https://github.com/PennyLaneAI/pennylane/pull/6933) to remove non-negligible performance impact due to wire flattening.
+  [(#7136)](https://github.com/PennyLaneAI/pennylane/pull/7136)
+
 * Fixes a bug that caused the output of `qml.fourier.qnode_spectrum()` to
   differ depending if equivalent gate generators are defined using
   different PennyLane operators. This was resolved by updating
diff --git a/pennylane/wires.py b/pennylane/wires.py
index ba1fc175a..3ca770031 100644
--- a/pennylane/wires.py
+++ b/pennylane/wires.py
@@ -93,8 +93,7 @@ def _process(wires):
     if len(set_of_wires) != len(tuple_of_wires):
         raise WireError(f"Wires must be unique; got {wires}.")
 
-    # required to make `Wires` object idempotent
-    return tuple(itertools.chain(*(_flatten_wires_object(x) for x in tuple_of_wires)))
+    return tuple_of_wires
 
 
 class Wires(Sequence):
@@ -732,13 +731,5 @@ class Wires(Sequence):
 
 WiresLike = Union[Wires, Iterable[Hashable], Hashable]
 
-
-def _flatten_wires_object(wire_label):
-    """Converts the input to a tuple of wire labels."""
-    if isinstance(wire_label, Wires):
-        return wire_label.labels
-    return [wire_label]
-
-
 # Register Wires as a PyTree-serializable class
 register_pytree(Wires, Wires._flatten, Wires._unflatten)  # pylint: disable=protected-access


Test patch:
diff --git a/tests/test_wires.py b/tests/test_wires.py
index d80f5e5cd..0ae3e85b6 100644
--- a/tests/test_wires.py
+++ b/tests/test_wires.py
@@ -34,12 +34,6 @@ else:
 class TestWires:
     """Tests for the ``Wires`` class."""
 
-    def test_wires_object_as_label(self):
-        """Tests that a Wires object can be used as a label for another Wires object."""
-        assert Wires([0, 1]) == Wires([Wires([0]), Wires([1])])
-        assert Wires(["a", "b", 1]) == Wires([Wires(["a", "b"]), Wires([1])])
-        assert Wires([Wires([(0, 0), (0, 1)])]) == Wires([(0, 0), (0, 1)])
-
     def test_error_if_wires_none(self):
         """Tests that a TypeError is raised if None is given as wires."""
         with pytest.raises(TypeError, match="Must specify a set of wires."):
@@ -80,7 +74,7 @@ class TestWires:
         """Tests that a Wires object can be created from a list of Wires."""
 
         wires = Wires([Wires([0]), Wires([1]), Wires([2])])
-        assert wires.labels == (0, 1, 2)
+        assert wires.labels == (Wires([0]), Wires([1]), Wires([2]))
 
     @pytest.mark.parametrize(
         "iterable", [[1, 0, 4], ["a", "b", "c"], [0, 1, None], ["a", 1, "ancilla"]]
@@ -154,7 +148,7 @@ class TestWires:
         wires = Wires([0, 1, 2, 3, Wires([4, 5]), None])
 
         assert 0 in wires
-        assert Wires([4, 5]) not in wires
+        assert Wires([4, 5]) in wires
         assert None in wires
         assert Wires([1]) not in wires
         assert Wires([0, 3]) not in wires
@@ -176,7 +170,7 @@ class TestWires:
 
         assert not wires.contains_wires(0)  # wrong type
         assert not wires.contains_wires([0, 1])  # wrong type
-        assert wires.contains_wires(
+        assert not wires.contains_wires(
             Wires([4, 5])
         )  # looks up 4 and 5 in wires, which are not present