Feat cirq custom gate#200
Conversation
| ┌──────────┐ | ||
| q_0: ┤2 ├ | ||
| │ │ | ||
| q_1: ┤1 Unitary ├ | ||
| │ │ | ||
| q_2: ┤0 ├ | ||
| └──────────┘ |
There was a problem hiding this comment.
this looks like a regression to me: previous version seemed more representative
There was a problem hiding this comment.
Yes but it made that we couldn't translate them back (cannot decompose into qasm).
So it had translatability issues.
There was a problem hiding this comment.
there is a difference between display and what's actually stored, see this comment: #200 (comment)
| from typing import Any, Optional | ||
|
|
||
| from mpqp.environment.var_cache import ( | ||
| _INSTALLED_MPQP_PROVIDERS, # pyright: ignore[reportPrivateUsage] |
There was a problem hiding this comment.
is there a reason to have it private ? I don't remember
There was a problem hiding this comment.
I don't know either I just know it was done that way before.
| if not is_unitary(v): | ||
| v = closest_unitary(v) |
There was a problem hiding this comment.
we could move this test in "clostest_unitary"
| circuit.add(rotation(angle, position)) | ||
| circuit.add(CNOT(control + position, position)) | ||
| circuit.add(rotation(angle, int(targets[position]))) | ||
| circuit.add(CNOT(int(control + targets[position]), int(targets[position]))) |
There was a problem hiding this comment.
It was a bug with a test where the typing got messed up here and it broken when adding gates.
So it's a failsafe that I put here because I never saw it happen anywhere else.
There was a problem hiding this comment.
maybe we should rather fix the test ?
There was a problem hiding this comment.
not part of the PR but not super clear
| changed = _gray_code(i) ^ _gray_code(i + 1) | ||
| control = next(i for i in range(len(thetas)) if (changed >> i & 1)) | ||
| control = max(-control - position - 1 + circuit.nb_qubits, 1) | ||
| control = max(-control - targets[position] - 1 + circuit.nb_qubits, 1) |
There was a problem hiding this comment.
linked to previous comment
| if abs >= 1: | ||
| beta = 0 | ||
| else: | ||
| beta = 2 * math.acos(abs) |
There was a problem hiding this comment.
small preference for ternary here but you can ignore this comment if you will
| circuit.add(Rz(alpha, int(targets[position]))) | ||
| circuit.add(Ry(beta, int(targets[position]))) | ||
| circuit.add(Rz(gamma, int(targets[position]))) |
There was a problem hiding this comment.
same as before, why the int casting ? targets is supposed to be a list of ints
There was a problem hiding this comment.
removed all int casting df88af6
The issue seems to be fixed
| InstalledProviders, | ||
| ) | ||
|
|
||
| if InstalledProviders.BRAKET in _INSTALLED_MPQP_PROVIDERS: |
There was a problem hiding this comment.
moving the export to another file, why not, but maybe we should give it some more thought ? because as is we are duplicating some code for each supported language
There was a problem hiding this comment.
My main reason for this change is that in some translation context we might need provider specific parameters that would be tougher to keep clean in one to_other_language function.
|
|
||
| # This method adds a lot of identities so for a much cleaner circuit we remove them. | ||
| # Maybe add this as an option | ||
| c.instructions = [i for i in c.instructions if not isinstance(i, Id)] |
There was a problem hiding this comment.
what are we doing with c ? it seems to me like we completely ignore it once built
| # If the CustomControlledGate contains itself a custom gate it's better to return a bigger custom gate for compatibilities issues. | ||
| # If the non_controlled_gate is a NativeGate it shouldn't pose a problem. | ||
| # TODO: check how to decompose a ComposeGate that is inside a CCG, (example: a C-PRX) |
There was a problem hiding this comment.
maybe have an exception for circuit drawing ? to solve the first comment I wrote in the PR
| return [gate] | ||
|
|
||
|
|
||
| def mpqp_to_qiskit( |
There was a problem hiding this comment.
a inconvenient of moving the code here is that it makes the job of reviewing much trickier
There was a problem hiding this comment.
could we have a meeting to recap what changed ? it would save me some time ^^
There was a problem hiding this comment.
Maybe this was already discussed but I would like to know the reason why we would keep this here? (I take liberty to unresolve the comment)
I meen mpqp.tools.circuit is supposed to be for tools on manipulation of circuit. Anything related to translation should have another dedicated file/location in the code I believe
There was a problem hiding this comment.
@MathieuG-Colibri so my suggestion, as discussed this week, is to regroup all translation/conversion features and code in a new module/package mpqp.translationor whatever.
The idea is to regroup all specifc functions/block of code called in to_other_language and from_other_language, or other helper functions or tools related to translation. This should also include the package concerning qasm conversion, (we would typically now have mpqp.translation.qasm instead of mpqp.qasm for instance)
Co-authored-by: Henri de Boutray <133855265+Henri-ColibrITD@users.noreply.github.com>
|
|
||
| Note: | ||
| If the circuit contains ComposedGate type instructions you need to include the gate in the authorize_gates set for it to avoid decomposition, otherwise, the translation will always | ||
| try to use the gate's decomposition (see example). Also in the case of CustomGates it will always be decomposed into the {Ry, Rz, CNOT} basis for translation compatibilities. |
There was a problem hiding this comment.
To update docs, we no longer decomposed into the {Ry, Rz, CNOT}
There was a problem hiding this comment.
Solved (forgot which commit)
| for instruction in circuit.instructions: | ||
| if isinstance(instruction, (Measure, Breakpoint)): | ||
| continue | ||
| options = {"printing": printing} if isinstance(instruction, CustomGate) else {} |
There was a problem hiding this comment.
So, printing=True apply only when the instruction is CustomGate?, I mean it is also propagated CustomControlledGate(...)?
There was a problem hiding this comment.
Yes printing was used at the beginning to make sure we could print parametrized CG, I did something similar with Custom Controlled Gates.
| if isinstance(gate, Operator): | ||
| gate = gate.to_instruction() | ||
| gate = gate.control(len(self.controls)) | ||
| gate.control() |
There was a problem hiding this comment.
Is this call intentional?
| return UnitaryGate(self.matrix) | ||
| dummy_circuit.id(0) | ||
| return dummy_circuit.to_gate( | ||
| label=f"CustomGate({', '.join([str(s) for s in gate_symbols])})" |
There was a problem hiding this comment.
Why did we change to this? the previous way of generating the label was not taking into account all the gate symbols?
There was a problem hiding this comment.
Yes I think the issue was that not all the params were displayed.
There was a problem hiding this comment.
Is there a risk, when we have too much parameters, that the display become weird ? in that case we can put "..." and not list them all but the first and last.
If this never happens you can resolve this comment
|
|
||
| return quantum_shannon_decomposition(self.matrix) | ||
| # non ordered targets | ||
| if any( |
There was a problem hiding this comment.
raise a warning or something in this case?
There was a problem hiding this comment.
Is it necessary to raise a warning if the edge case is taken into account anyway ?
There was a problem hiding this comment.
It's taken into account by tweaking the user's input, which may affect few stuff between what he submitted and what is actually run on the backend, right?
In that case it is nice if we can inform, or warn the user of the changes we make.
Change the cirq custom gate implem and behavior
Cleanup and bug fixing
Refactored to_other_language