-
Notifications
You must be signed in to change notification settings - Fork 66
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
Qiskit v0.18 updates #81
Changes from all commits
ec7be89
bcba866
aac9e32
c04b944
bc6f99a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,23 +59,24 @@ def pauli_eigs(n): | |
"PauliY": ex.YGate, | ||
"PauliZ": ex.ZGate, | ||
"Hadamard": ex.HGate, | ||
"CNOT": ex.CnotGate, | ||
"CZ": ex.CzGate, | ||
"CNOT": ex.CXGate, | ||
"CZ": ex.CZGate, | ||
"SWAP": ex.SwapGate, | ||
"RX": ex.RXGate, | ||
"RY": ex.RYGate, | ||
"RZ": ex.RZGate, | ||
"S": ex.SGate, | ||
"T": ex.TGate, | ||
|
||
# Adding the following for conversion compatibility | ||
"CSWAP": ex.FredkinGate, | ||
"CRZ": ex.CrzGate, | ||
"CSWAP": ex.CSwapGate, | ||
"CRX": ex.CRXGate, | ||
"CRY": ex.CRYGate, | ||
"CRZ": ex.CRZGate, | ||
Comment on lines
+72
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! |
||
"PhaseShift": ex.U1Gate, | ||
"QubitStateVector": ex.Initialize, | ||
"U2": ex.U2Gate, | ||
"U3": ex.U3Gate, | ||
"Toffoli": ex.ToffoliGate, | ||
"Toffoli": ex.CCXGate, | ||
"QubitUnitary": ex.UnitaryGate, | ||
} | ||
|
||
|
@@ -117,9 +118,11 @@ class QiskitDevice(Device, abc.ABC): | |
operations = set(_operation_map.keys()) | ||
observables = {"PauliX", "PauliY", "PauliZ", "Identity", "Hadamard", "Hermitian"} | ||
|
||
hw_analytic_warning_message = "The analytic calculation of expectations and variances "\ | ||
"is only supported on statevector backends, not on the {}. "\ | ||
"The obtained result is based on sampling." | ||
hw_analytic_warning_message = ( | ||
"The analytic calculation of expectations and variances " | ||
"is only supported on statevector backends, not on the {}. " | ||
"The obtained result is based on sampling." | ||
) | ||
|
||
_eigs = {} | ||
|
||
|
@@ -192,13 +195,18 @@ def apply(self, operation, wires, par): | |
if operation == "QubitStateVector": | ||
|
||
if self.backend_name == "unitary_simulator": | ||
raise QuantumFunctionError("The QubitStateVector operation is not supported on the unitary simulator backend.") | ||
raise QuantumFunctionError( | ||
"The QubitStateVector operation is not supported on the unitary simulator backend." | ||
) | ||
|
||
if len(par[0]) != 2 ** len(wires): | ||
raise ValueError("State vector must be of length 2**wires.") | ||
|
||
qregs = list(reversed(qregs)) | ||
|
||
# TODO: Once a fix is available in Qiskit-Aer, remove the following: | ||
par = (x.tolist() for x in par if isinstance(x, np.ndarray)) | ||
|
||
if operation == "QubitUnitary": | ||
|
||
if len(par[0]) != 2 ** len(wires): | ||
|
@@ -305,7 +313,11 @@ def pre_measure(self): | |
for e in self.obs_queue: | ||
# Add unitaries if a different expectation value is given | ||
# Exclude unitary_simulator as it does not support memory=True | ||
if hasattr(e, "return_type") and e.return_type == Sample and self.backend_name != 'unitary_simulator': | ||
if ( | ||
hasattr(e, "return_type") | ||
and e.return_type == Sample | ||
and self.backend_name != "unitary_simulator" | ||
): | ||
self.memory = True # make sure to return samples | ||
|
||
if isinstance(e.name, list): | ||
|
@@ -333,9 +345,7 @@ def expval(self, observable, wires, par): | |
|
||
if self.analytic: | ||
# Raise a warning if backend is a hardware simulator | ||
warnings.warn(self.hw_analytic_warning_message. | ||
format(self.backend), | ||
UserWarning) | ||
warnings.warn(self.hw_analytic_warning_message.format(self.backend), UserWarning) | ||
|
||
# estimate the ev | ||
return np.mean(self.sample(observable, wires, par)) | ||
|
@@ -349,9 +359,7 @@ def var(self, observable, wires, par): | |
|
||
if self.analytic: | ||
# Raise a warning if backend is a hardware simulator | ||
warnings.warn(self.hw_analytic_warning_message. | ||
format(self.backend), | ||
UserWarning) | ||
warnings.warn(self.hw_analytic_warning_message.format(self.backend), UserWarning) | ||
|
||
return np.var(self.sample(observable, wires, par)) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -240,7 +240,8 @@ def test_invalid_parameter_expression(self, recorder): | |
quantum_circuit(params={theta: qml.variable.Variable(0), phi: qml.variable.Variable(1)}) | ||
|
||
def test_extra_parameters_were_passed(self, recorder): | ||
"""Tests that loading raises an error when extra parameters were passed.""" | ||
"""Tests that loading raises an error when extra parameters were | ||
passed.""" | ||
|
||
theta = Parameter('θ') | ||
phi = Parameter('φ') | ||
|
@@ -253,23 +254,60 @@ def test_extra_parameters_were_passed(self, recorder): | |
with recorder: | ||
quantum_circuit(params={theta: 0.5, phi: 0.3}) | ||
|
||
def test_crz(self, recorder): | ||
"""Tests loading a circuit with the controlled-Z operation.""" | ||
@pytest.mark.parametrize("qiskit_operation, pennylane_name", [(QuantumCircuit.crx, "CRX"), (QuantumCircuit.crz, "CRZ")]) | ||
def test_controlled_rotations(self, qiskit_operation, pennylane_name, recorder): | ||
"""Tests loading a circuit with two qubit controlled rotations (except | ||
for CRY).""" | ||
Comment on lines
+259
to
+260
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come this test doesn't check |
||
|
||
q2 = QuantumRegister(2) | ||
qc = QuantumCircuit(q2) | ||
qc.crz(0.5, q2[0], q2[1]) | ||
|
||
qiskit_operation(qc, 0.5, q2[0], q2[1]) | ||
|
||
|
||
quantum_circuit = load(qc) | ||
|
||
with recorder: | ||
quantum_circuit() | ||
|
||
assert len(recorder.queue) == 1 | ||
assert recorder.queue[0].name == 'CRZ' | ||
assert recorder.queue[0].name == pennylane_name | ||
assert recorder.queue[0].params == [0.5] | ||
assert recorder.queue[0].wires == [0, 1] | ||
|
||
def test_cry(self, recorder): | ||
"""Tests that the decomposition of the controlled-Y operation is being | ||
loaded.""" | ||
# This test will be merged into the test_controlled_rotations test once | ||
# the native CRY is used in Qiskit and not a set of instructions | ||
# yielded from decomposition is being added | ||
Comment on lines
+281
to
+283
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come this is the case? Is Qiskit doing the decomposition? Or PL core? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's coming from Qiskit, but the question of why it is so got me wondering as well 😅 : from qiskit import QuantumCircuit, QuantumRegister
q2 = QuantumRegister(2)
qc = QuantumCircuit(q2)
instr_set = qc.cry(0.5, q2[0], q2[1])
instr_set.data Outputs: [(<qiskit.extensions.standard.u3.U3Gate object at 0x7fec26d88350>, [Qubit(QuantumRegister(2, 'q2'), 1)], []), (<qiskit.extensions.standard.x.CXGate object at 0x7fec26d88510>, [Qubit(QuantumRegister(2, 'q2'), 0), Qubit(QuantumRegister(2, 'q2'), 1)], []), (<qiskit.extensions.standard.u3.U3Gate object at 0x7fec26d885d0>, [Qubit(QuantumRegister(2, 'q2'), 1)], []), (<qiskit.extensions.standard.x.CXGate object at 0x7fec26d88610>, [Qubit(QuantumRegister(2, 'q2'), 0), Qubit(QuantumRegister(2, 'q2'), 1)], [])] |
||
|
||
q2 = QuantumRegister(2) | ||
qc = QuantumCircuit(q2) | ||
|
||
qc.cry(0.5, q2[0], q2[1]) | ||
|
||
quantum_circuit = load(qc) | ||
|
||
with recorder: | ||
quantum_circuit() | ||
|
||
assert len(recorder.queue) == 4 | ||
assert recorder.queue[0].name == "U3" | ||
assert recorder.queue[0].params == [0.25, 0, 0] | ||
assert recorder.queue[0].wires == [1] | ||
|
||
assert recorder.queue[1].name == "CNOT" | ||
assert recorder.queue[1].wires == [0, 1] | ||
|
||
assert recorder.queue[2].name == "U3" | ||
assert recorder.queue[2].params == [-0.25, 0, 0] | ||
assert recorder.queue[2].wires == [1] | ||
|
||
assert recorder.queue[3].name == "CNOT" | ||
assert recorder.queue[3].wires == [0, 1] | ||
|
||
|
||
def test_one_qubit_operations_supported_by_pennylane(self, recorder): | ||
"""Tests loading a circuit with the one-qubit operations supported by PennyLane.""" | ||
|
||
|
@@ -812,7 +850,7 @@ def test_qasm_from_file(self, tmpdir, recorder): | |
.format('Barrier') | ||
assert record[1].message.args[0] == "pennylane_qiskit.converter: The {} instruction is not supported by" \ | ||
" PennyLane, and has not been added to the template."\ | ||
.format('Cu1Gate') | ||
.format('CU1Gate') | ||
assert record[7].message.args[0] == "pennylane_qiskit.converter: The {} instruction is not supported by" \ | ||
" PennyLane, and has not been added to the template."\ | ||
.format('Measure') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why they renamed this? CNOT is much more established than CX
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good question. From what I saw they started porting every gate to this type of naming (e.g.
FredkingGate
was also renamed toCSwapGate
) and I also noticed a base class for controlled X that was created.They seem to not even mention
CNOT
with the new formalism (once theCnotGate
has been deprecated, it will not be in there):https://qiskit.org/documentation/_modules/qiskit/extensions/standard/x.html#CXGate