Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor improvement to quantum_info.random_clifford #1259

Merged
merged 13 commits into from
Mar 20, 2024
Merged

Conversation

BrunoLiegiBastonLiegi
Copy link
Contributor

@BrunoLiegiBastonLiegi BrunoLiegiBastonLiegi commented Mar 13, 2024

Minor improvement to quantum_info.random_clifford.

Checklist:

  • Reviewers confirm new code works as expected.
  • Tests are passing.
  • Coverage does not decrease.
  • Documentation is updated.

Copy link

codecov bot commented Mar 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.84%. Comparing base (44f5b83) to head (5552d06).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1259      +/-   ##
==========================================
- Coverage   99.85%   99.84%   -0.01%     
==========================================
  Files          73       73              
  Lines       10638    10645       +7     
==========================================
+ Hits        10623    10629       +6     
- Misses         15       16       +1     
Flag Coverage Δ
unittests 99.84% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

@renatomello renatomello self-requested a review March 14, 2024 05:04
@renatomello renatomello requested a review from stavros11 March 14, 2024 05:04
@renatomello renatomello added this to the Qibo 0.2.7 milestone Mar 14, 2024
@renatomello renatomello added the enhancement New feature or request label Mar 14, 2024
@renatomello renatomello marked this pull request as ready for review March 14, 2024 05:56
@BrunoLiegiBastonLiegi
Copy link
Contributor Author

Ok this is ready @renatomello

@renatomello renatomello added the quantum_info module PRs and issues related to the quantum information module label Mar 14, 2024
@@ -204,7 +204,8 @@ def _find_repeated(qubits: Sequence[int]) -> int:
def _check_control_target_overlap(self):
"""Checks that there are no qubits that are both target and
controls."""
common = set(self._target_qubits) & self._control_qubits
control_target = self._target_qubits + self._control_qubits
common = len(set(control_target)) != len(control_target)
if common:
raise_error(
ValueError,
Copy link
Member

Choose a reason for hiding this comment

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

common used to be a set but now it is a bool, therefore the error message defined under this line (GitHub does not let me comment there because it is not changed in this PR) will stop making sense. It will probably read:

ValueError("True qubits are both targets and controls for gate ...")

which doesn't make much sense. It should be modified accordingly.

Other than that, what is the motivation of switching _control_qubits from set to tuple? Just symmetry with _target_qubits? (not intending to say that the current code is the best, I am sure it can be simplified in many ways)

Copy link
Contributor

@renatomello renatomello Mar 19, 2024

Choose a reason for hiding this comment

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

Other than that, what is the motivation of switching _control_qubits from set to tuple? Just symmetry with _target_qubits? (not intending to say that the current code is the best, I am sure it can be simplified in many ways)

In [1]: %timeit set()
63.8 ns ± 4.93 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [2]: %timeit set()
55.9 ns ± 2.81 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [3]: %timeit list()
61.4 ns ± 3.49 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [4]: %timeit tuple()
28.8 ns ± 0.179 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [5]: %timeit []
23 ns ± 2.33 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [6]: %timeit ()
7.33 ns ± 0.0883 ns per loop (mean ± std. dev. of 7 runs, 100,000,000 loops each)

It's 7x faster. Even though it's in the ns scale, it makes a difference when creating tens or even hundreds of thousands of gates e.g. random_clifford for 1000+ qubits.

@renatomello
Copy link
Contributor

@stavros11

Another thing that we noted is that every single qubit gate is inheriting a control_qubits attribute from the abstract Gate class. This means that every single qubit gate carries an empty tuple with it, unless the method controlled_by is used and the tuple is filled. It may be worth for single qubit gates to move the initialization of control_qubits to inside the control_qubits method. That would make the creating of gates slightly faster and the objects slightly lighter.

Copy link
Member

@stavros11 stavros11 left a comment

Choose a reason for hiding this comment

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

Thanks @renatomello for the explanation regarding the set. I was not aware about this overhead. This PR looks good to me.

Another thing that we noted is that every single qubit gate is inheriting a control_qubits attribute from the abstract Gate class. This means that every single qubit gate carries an empty tuple with it, unless the method controlled_by is used and the tuple is filled. It may be worth for single qubit gates to move the initialization of control_qubits to inside the control_qubits method. That would make the creating of gates slightly faster and the objects slightly lighter.

I wouldn't expect that this adds that big of an overhead. If it does, I am fine with dropping it for single qubit gates, however, we should be a bit careful with .controlled_by because it is not good practice to add new attributes to objects outside __init__ (pylint may even complain if you do this). Then I guess .controlled_by would have to create a different gate instance for the controlled version of the gate (which has control_qubits), but I am also not sure if it's a good solution because we'd have to replicate every non-controlled gate to support that.

In any case, I would postpone to another PR, but feel free to open an issue if you think control_qubits should be dropped.

@renatomello renatomello added this pull request to the merge queue Mar 20, 2024
Merged via the queue into master with commit b1f0fe9 Mar 20, 2024
21 checks passed
@renatomello renatomello deleted the qinfo_jit branch March 20, 2024 12:16
@BrunoLiegiBastonLiegi BrunoLiegiBastonLiegi mentioned this pull request Jul 4, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request quantum_info module PRs and issues related to the quantum information module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants