From 7600b1787a05a2f9ec85bbd6898576bfa092bbc9 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Fri, 19 Nov 2021 16:57:28 +0100 Subject: [PATCH 01/16] commit --- pennylane_qiskit/ibmq.py | 12 ++++++++++++ pennylane_qiskit/qiskit_device.py | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index 4c057d432..c2059b070 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -95,3 +95,15 @@ def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=10 p = provider or IBMQ.get_provider(hub=hub, group=group, project=project) super().__init__(wires=wires, provider=p, backend=backend, shots=shots, **kwargs) + + def _track(self): + """Provide runtime information.""" + + time_per_step = self._current_job.time_per_step() + job_time = { + "creating": (time_per_step["CREATED"] - time_per_step["CREATING"]).total_seconds(), + "validating": (time_per_step["VALIDATED"] - time_per_step["VALIDATING"]).total_seconds(), + "queued": (time_per_step["RUNNING"] - time_per_step["QUEUED"]).total_seconds(), + "running": (time_per_step["COMPLETED"] - time_per_step["RUNNING"]).total_seconds() + } + self.tracker.update(job_time=job_time) diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py index bdf959695..2d60efc78 100644 --- a/pennylane_qiskit/qiskit_device.py +++ b/pennylane_qiskit/qiskit_device.py @@ -316,6 +316,8 @@ def run(self, qcirc): self._current_job = self.backend.run(qcirc, shots=self.shots, **self.run_args) result = self._current_job.result() + self._track() + if self.backend_name in self._state_backends: self._state = self._get_state(result) @@ -412,3 +414,6 @@ def batch_execute(self, circuits): results.append(res) return results + + def _track(self): + """Update the tracker.""" From e5e35afd481ba16d63202f7babf08f849bbdc0ee Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Fri, 19 Nov 2021 17:01:11 +0100 Subject: [PATCH 02/16] black --- pennylane_qiskit/ibmq.py | 6 ++++-- tests/conftest.py | 17 ++++++++++++----- tests/test_ibmq.py | 3 ++- tests/test_integration.py | 36 +++++++++++++++++++++--------------- tests/test_inverses.py | 2 +- tests/test_qiskit_device.py | 13 ++++--------- 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index c2059b070..ed050dabf 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -102,8 +102,10 @@ def _track(self): time_per_step = self._current_job.time_per_step() job_time = { "creating": (time_per_step["CREATED"] - time_per_step["CREATING"]).total_seconds(), - "validating": (time_per_step["VALIDATED"] - time_per_step["VALIDATING"]).total_seconds(), + "validating": ( + time_per_step["VALIDATED"] - time_per_step["VALIDATING"] + ).total_seconds(), "queued": (time_per_step["RUNNING"] - time_per_step["QUEUED"]).total_seconds(), - "running": (time_per_step["COMPLETED"] - time_per_step["RUNNING"]).total_seconds() + "running": (time_per_step["COMPLETED"] - time_per_step["RUNNING"]).total_seconds(), } self.tracker.update(job_time=job_time) diff --git a/tests/conftest.py b/tests/conftest.py index 27f55460c..b573324c6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,7 +21,12 @@ A = np.array([[1.02789352, 1.61296440 - 0.3498192j], [1.61296440 + 0.3498192j, 1.23920938 + 0j]]) -state_backends = ["statevector_simulator", "unitary_simulator", "aer_simulator_statevector", "aer_simulator_unitary"] +state_backends = [ + "statevector_simulator", + "unitary_simulator", + "aer_simulator_statevector", + "aer_simulator_unitary", +] hw_backends = ["qasm_simulator", "aer_simulator"] @@ -75,8 +80,9 @@ def device(request, backend, shots): if backend not in state_backends and shots is None: pytest.skip("Hardware simulators do not support analytic mode") - if (issubclass(request.param, AerDevice) and "aer" not in backend) \ - or (issubclass(request.param, BasicAerDevice) and "aer" in backend): + if (issubclass(request.param, AerDevice) and "aer" not in backend) or ( + issubclass(request.param, BasicAerDevice) and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") def _device(n, device_options=None): @@ -90,8 +96,9 @@ def _device(n, device_options=None): @pytest.fixture(params=[AerDevice, BasicAerDevice]) def state_vector_device(request, statevector_backend, shots): - if (issubclass(request.param, AerDevice) and "aer" not in statevector_backend) \ - or (issubclass(request.param, BasicAerDevice) and "aer" in statevector_backend): + if (issubclass(request.param, AerDevice) and "aer" not in statevector_backend) or ( + issubclass(request.param, BasicAerDevice) and "aer" in statevector_backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") def _device(n): diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index d9e1c83d5..43211f491 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -224,7 +224,7 @@ def circuit(x, y): x = qml.numpy.array(0.543, requires_grad=True) y = qml.numpy.array(0.123, requires_grad=True) - res = qml.grad(circuit)(x,y) + res = qml.grad(circuit)(x, y) expected = np.array([[-np.sin(y) * np.sin(x), np.cos(y) * np.cos(x)]]) assert np.allclose(res, expected, **tol) @@ -235,6 +235,7 @@ def circuit(x, y): # running the circuit assert spy2.call_count == 2 + @pytest.mark.parametrize("shots", [1000]) def test_probability(token, tol, shots): """Test that the probs function works.""" diff --git a/tests/test_integration.py b/tests/test_integration.py index e45ee2762..8e484038a 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -21,8 +21,9 @@ class TestDeviceIntegration: @pytest.mark.parametrize("d", pldevices) def test_load_device(self, d, backend): """Test that the qiskit device loads correctly""" - if (d[0] == "qiskit.aer" and "aer" not in backend) \ - or (d[0] == "qiskit.basicaer" and "aer" in backend): + if (d[0] == "qiskit.aer" and "aer" not in backend) or ( + d[0] == "qiskit.basicaer" and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") dev = qml.device(d[0], wires=2, backend=backend, shots=1024) @@ -38,7 +39,9 @@ def test_incorrect_backend(self): def test_incorrect_backend_wires(self): """Test that exception is raised if number of wires is too large""" - with pytest.raises(ValueError, match=r"Backend 'aer_simulator\_statevector' supports maximum"): + with pytest.raises( + ValueError, match=r"Backend 'aer_simulator\_statevector' supports maximum" + ): qml.device("qiskit.aer", wires=100, method="statevector") def test_args(self): @@ -55,8 +58,9 @@ def test_args(self): @pytest.mark.parametrize("shots", [None, 8192]) def test_one_qubit_circuit(self, shots, d, backend, tol): """Test that devices provide correct result for a simple circuit""" - if (d[0] == "qiskit.aer" and "aer" not in backend) \ - or (d[0] == "qiskit.basicaer" and "aer" in backend): + if (d[0] == "qiskit.aer" and "aer" not in backend) or ( + d[0] == "qiskit.basicaer" and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") if backend not in state_backends and shots is None: @@ -83,8 +87,9 @@ def circuit(x, y, z): def test_basis_state_and_rot(self, shots, d, backend, tol): """Integration test for the BasisState and Rot operations for non-analytic mode.""" - if (d[0] == "qiskit.aer" and "aer" not in backend) \ - or (d[0] == "qiskit.basicaer" and "aer" in backend): + if (d[0] == "qiskit.aer" and "aer" not in backend) or ( + d[0] == "qiskit.basicaer" and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") dev = qml.device(d[0], wires=1, backend=backend, shots=shots) @@ -149,9 +154,7 @@ def test_noise_model_qasm_simulator(self, monkeypatch): cache = [] with monkeypatch.context() as m: - m.setattr( - aer.AerSimulator, "set_options", lambda *args, **kwargs: cache.append(kwargs) - ) + m.setattr(aer.AerSimulator, "set_options", lambda *args, **kwargs: cache.append(kwargs)) dev = qml.device("qiskit.aer", wires=2, noise_model="test value") assert cache[-1] == {"noise_model": "test value"} @@ -485,6 +488,7 @@ def circuit(): assert circuit() == -1 + class TestBatchExecution: """Test the devices work correctly with the batch execution pipeline.""" @@ -493,8 +497,9 @@ class TestBatchExecution: def test_one_qubit_circuit_batch_params(self, shots, d, backend, tol, mocker): """Test that devices provide correct result for a simple circuit using the batch_params transform.""" - if (d[0] == "qiskit.aer" and "aer" not in backend) \ - or (d[0] == "qiskit.basicaer" and "aer" in backend): + if (d[0] == "qiskit.aer" and "aer" not in backend) or ( + d[0] == "qiskit.basicaer" and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") if backend not in state_backends and shots is None: @@ -531,8 +536,9 @@ def circuit(x, y, z): def test_batch_execute_parameter_shift(self, shots, d, backend, tol, mocker): """Test that devices provide correct result computing the gradient of a circuit using the parameter-shift rule and the batch execution pipeline.""" - if (d[0] == "qiskit.aer" and "aer" not in backend) \ - or (d[0] == "qiskit.basicaer" and "aer" in backend): + if (d[0] == "qiskit.aer" and "aer" not in backend) or ( + d[0] == "qiskit.basicaer" and "aer" in backend + ): pytest.skip("Only the AerSimulator is supported on AerDevice") if backend not in state_backends and shots is None: @@ -553,7 +559,7 @@ def circuit(x, y): x = qml.numpy.array(0.543, requires_grad=True) y = qml.numpy.array(0.123, requires_grad=True) - res = qml.grad(circuit)(x,y) + res = qml.grad(circuit)(x, y) expected = np.array([[-np.sin(y) * np.sin(x), np.cos(y) * np.cos(x)]]) assert np.allclose(res, expected, **tol) diff --git a/tests/test_inverses.py b/tests/test_inverses.py index 8bb4daade..c61590504 100644 --- a/tests/test_inverses.py +++ b/tests/test_inverses.py @@ -22,7 +22,7 @@ class TestInverses: ("Hadamard", 0), ("S", 1), ("T", 1), - ("SX", 0) + ("SX", 0), ], ) def test_supported_gate_inverse_single_wire_no_parameters(self, name, expected_output): diff --git a/tests/test_qiskit_device.py b/tests/test_qiskit_device.py index ad987ca88..95427ce49 100644 --- a/tests/test_qiskit_device.py +++ b/tests/test_qiskit_device.py @@ -100,6 +100,7 @@ def test_backend_options_cleaned(self): dev2 = qml.device("qiskit.aer", wires=2) assert dev2.backend.options.get("noise_model") is None + @pytest.mark.parametrize("shots", [None]) class TestBatchExecution: """Tests for the batch_execute method.""" @@ -154,13 +155,9 @@ def test_result(self, device, tol): tape2_expected = dev.execute(self.tape2) assert len(res) == 2 - assert np.allclose( - res[0], tape1_expected, atol=0 - ) + assert np.allclose(res[0], tape1_expected, atol=0) - assert np.allclose( - res[1], tape2_expected, atol=0 - ) + assert np.allclose(res[1], tape2_expected, atol=0) def test_result_empty_tape(self, device, tol): """Tests that the result has the correct shape and entry types for empty tapes.""" @@ -174,6 +171,4 @@ def test_result_empty_tape(self, device, tol): # execution dev.reset() assert len(res) == 3 - assert np.allclose( - res[0], dev.execute(empty_tape), atol=0 - ) + assert np.allclose(res[0], dev.execute(empty_tape), atol=0) From c76cd07e68f20ca856e547b233ef4647c882c359 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 09:52:03 +0100 Subject: [PATCH 03/16] test --- pennylane_qiskit/ibmq.py | 2 +- pennylane_qiskit/qiskit_device.py | 6 +++--- tests/test_ibmq.py | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index ed050dabf..5916a04b3 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -96,7 +96,7 @@ def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=10 super().__init__(wires=wires, provider=p, backend=backend, shots=shots, **kwargs) - def _track(self): + def _track_run(self): """Provide runtime information.""" time_per_step = self._current_job.time_per_step() diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py index 2d60efc78..c8a45870d 100644 --- a/pennylane_qiskit/qiskit_device.py +++ b/pennylane_qiskit/qiskit_device.py @@ -315,8 +315,8 @@ def run(self, qcirc): """Run the compiled circuit, and query the result.""" self._current_job = self.backend.run(qcirc, shots=self.shots, **self.run_args) result = self._current_job.result() - - self._track() + if self.tracker.active: + self._track_run() if self.backend_name in self._state_backends: self._state = self._get_state(result) @@ -415,5 +415,5 @@ def batch_execute(self, circuits): return results - def _track(self): + def _track_run(self): """Update the tracker.""" diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index 43211f491..84d85cab0 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -260,3 +260,18 @@ def circuit(x): assert np.isclose(hw_prob.sum(), 1, **tol) assert np.allclose(prob_analytic(x), hw_prob, **tol) assert not np.array_equal(prob_analytic(x), hw_prob) + + +def test_track(token): + """Test that the tracker works.""" + IBMQ.enable_account(token) + dev = IBMQDevice(wires=1, backend="ibmq_armonk", shots=1) + dev.tracker.active = True + + @qml.qnode(dev) + def circuit(): + qml.PauliX(wires=0) + return qml.probs(wires=0) + + circuit() + assert "job_time" in dev.tracker.history From 63064b40692f3dcf3e4eee57ac2f0a4d27726b29 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 10:39:18 +0100 Subject: [PATCH 04/16] checking coverage --- tests/test_ibmq.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index 84d85cab0..b415d9447 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -261,6 +261,17 @@ def circuit(x): assert np.allclose(prob_analytic(x), hw_prob, **tol) assert not np.array_equal(prob_analytic(x), hw_prob) + dev = IBMQDevice(wires=1, backend="ibmq_armonk", shots=1) + dev.tracker.active = True + + @qml.qnode(dev) + def circuit(): + qml.PauliX(wires=0) + return qml.probs(wires=0) + + circuit() + assert "job_time" in dev.tracker.history + def test_track(token): """Test that the tracker works.""" From dc2da00489228046226359dc9a3c8e8b8b60ec0b Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 10:47:02 +0100 Subject: [PATCH 05/16] reset test --- tests/test_ibmq.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index b415d9447..84d85cab0 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -261,17 +261,6 @@ def circuit(x): assert np.allclose(prob_analytic(x), hw_prob, **tol) assert not np.array_equal(prob_analytic(x), hw_prob) - dev = IBMQDevice(wires=1, backend="ibmq_armonk", shots=1) - dev.tracker.active = True - - @qml.qnode(dev) - def circuit(): - qml.PauliX(wires=0) - return qml.probs(wires=0) - - circuit() - assert "job_time" in dev.tracker.history - def test_track(token): """Test that the tracker works.""" From 380d0713e3e7078940ba672c42bcda013132af80 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 10:52:41 +0100 Subject: [PATCH 06/16] qasm_simulator --- tests/test_ibmq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index 84d85cab0..b24d3b28f 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -265,7 +265,7 @@ def circuit(x): def test_track(token): """Test that the tracker works.""" IBMQ.enable_account(token) - dev = IBMQDevice(wires=1, backend="ibmq_armonk", shots=1) + dev = IBMQDevice(wires=1, backend="ibmq_qasm_simulator", shots=1) dev.tracker.active = True @qml.qnode(dev) From d2b77f6cc687d3e597a2b492ba2a5da9998dfaa5 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 11:32:47 +0100 Subject: [PATCH 07/16] test --- tests/test_ibmq.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index b24d3b28f..984fb58d9 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -264,6 +264,7 @@ def circuit(x): def test_track(token): """Test that the tracker works.""" + IBMQ.enable_account(token) dev = IBMQDevice(wires=1, backend="ibmq_qasm_simulator", shots=1) dev.tracker.active = True @@ -275,3 +276,4 @@ def circuit(): circuit() assert "job_time" in dev.tracker.history + assert 1 == 2 #check if we enter here From a8e83450d914a2d1e919d0596029a4a1fbdd0bc4 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 18:29:43 +0100 Subject: [PATCH 08/16] test --- tests/test_ibmq.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index 984fb58d9..22d99469c 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -276,4 +276,3 @@ def circuit(): circuit() assert "job_time" in dev.tracker.history - assert 1 == 2 #check if we enter here From 132f5bbc119fee5665c4ea0f1d47c337d25b9cc6 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Mon, 22 Nov 2021 18:56:44 +0100 Subject: [PATCH 09/16] change --- pennylane_qiskit/qiskit_device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py index c8a45870d..e7b8e869f 100644 --- a/pennylane_qiskit/qiskit_device.py +++ b/pennylane_qiskit/qiskit_device.py @@ -416,4 +416,4 @@ def batch_execute(self, circuits): return results def _track_run(self): - """Update the tracker.""" + """Update the runtime information of the tracker.""" From e3228b66d7daa30011a72bc667dd064388c582ad Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:40:37 +0100 Subject: [PATCH 10/16] update --- pennylane_qiskit/qiskit_device.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py index e7b8e869f..aa8fc8bc7 100644 --- a/pennylane_qiskit/qiskit_device.py +++ b/pennylane_qiskit/qiskit_device.py @@ -315,8 +315,6 @@ def run(self, qcirc): """Run the compiled circuit, and query the result.""" self._current_job = self.backend.run(qcirc, shots=self.shots, **self.run_args) result = self._current_job.result() - if self.tracker.active: - self._track_run() if self.backend_name in self._state_backends: self._state = self._get_state(result) @@ -364,7 +362,6 @@ def generate_samples(self, circuit=None): # hardware or hardware simulator samples = self._current_job.result().get_memory(circuit) - # reverse qubit order to match PennyLane convention return np.vstack([np.array([int(i) for i in s[::-1]]) for s in samples]) @@ -399,6 +396,9 @@ def batch_execute(self, circuits): self._current_job = self.backend.run(compiled_circuits, shots=self.shots, **self.run_args) result = self._current_job.result() + if self.tracker.active: + self._track_run() + # Compute statistics using the state and/or samples results = [] for circuit, circuit_obj in zip(circuits, compiled_circuits): @@ -413,6 +413,10 @@ def batch_execute(self, circuits): res = self.statistics(circuit.observables) results.append(res) + if self.tracker.active: + self.tracker.update(batches=1, batch_len=len(circuits)) + self.tracker.record() + return results def _track_run(self): From b4f189d8752185010286120200d57caa93b0c533 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Tue, 23 Nov 2021 11:52:09 +0100 Subject: [PATCH 11/16] record --- pennylane_qiskit/ibmq.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index 5916a04b3..e235d2b80 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -109,3 +109,4 @@ def _track_run(self): "running": (time_per_step["COMPLETED"] - time_per_step["RUNNING"]).total_seconds(), } self.tracker.update(job_time=job_time) + self.tracker.record() From 75ea1fe317f6be427d79eb80095c692982db05b3 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:09:00 +0100 Subject: [PATCH 12/16] Romain changes --- pennylane_qiskit/ibmq.py | 5 +++++ pennylane_qiskit/qiskit_device.py | 6 ------ tests/test_ibmq.py | 7 +++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index e235d2b80..9055554e7 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -96,6 +96,11 @@ def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=10 super().__init__(wires=wires, provider=p, backend=backend, shots=shots, **kwargs) + def batch_execute(self, circuits): + super()(circuits) + if self.tracker.active: + self._track_run() + def _track_run(self): """Provide runtime information.""" diff --git a/pennylane_qiskit/qiskit_device.py b/pennylane_qiskit/qiskit_device.py index aa8fc8bc7..68bd1d72f 100644 --- a/pennylane_qiskit/qiskit_device.py +++ b/pennylane_qiskit/qiskit_device.py @@ -396,9 +396,6 @@ def batch_execute(self, circuits): self._current_job = self.backend.run(compiled_circuits, shots=self.shots, **self.run_args) result = self._current_job.result() - if self.tracker.active: - self._track_run() - # Compute statistics using the state and/or samples results = [] for circuit, circuit_obj in zip(circuits, compiled_circuits): @@ -418,6 +415,3 @@ def batch_execute(self, circuits): self.tracker.record() return results - - def _track_run(self): - """Update the runtime information of the tracker.""" diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index 8f0649966..c3a0bead1 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -275,4 +275,11 @@ def circuit(): return qml.probs(wires=0) circuit() + assert "job_time" in dev.tracker.history + if "job_time" in dev.tracker.history: + assert "creating" in dev.tracker.history["job_time"] + assert "validating" in dev.tracker.history["job_time"] + assert "queued" in dev.tracker.history["job_time"] + assert "running" in dev.tracker.history["job_time"] + assert len(dev.tracker.history["job_time"]) == 4 From 23da2fcf813ddd6e1b0487918f72873e2d039816 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:20:57 +0100 Subject: [PATCH 13/16] Update ibmq.py --- pennylane_qiskit/ibmq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index 9055554e7..4d74f6eaf 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -97,7 +97,7 @@ def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=10 super().__init__(wires=wires, provider=p, backend=backend, shots=shots, **kwargs) def batch_execute(self, circuits): - super()(circuits) + super().batch_execute(circuits) if self.tracker.active: self._track_run() From 90fc6d5df7b5c25b10efef4c547f75ef8a942b66 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:45:16 +0100 Subject: [PATCH 14/16] final change --- pennylane_qiskit/ibmq.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pennylane_qiskit/ibmq.py b/pennylane_qiskit/ibmq.py index 4d74f6eaf..1d2f670fd 100644 --- a/pennylane_qiskit/ibmq.py +++ b/pennylane_qiskit/ibmq.py @@ -97,9 +97,10 @@ def __init__(self, wires, provider=None, backend="ibmq_qasm_simulator", shots=10 super().__init__(wires=wires, provider=p, backend=backend, shots=shots, **kwargs) def batch_execute(self, circuits): - super().batch_execute(circuits) + res = super().batch_execute(circuits) if self.tracker.active: self._track_run() + return res def _track_run(self): """Provide runtime information.""" From 2a6254236b925c99b184319c1e065e33d7472411 Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:53:22 +0100 Subject: [PATCH 15/16] Update test_ibmq.py --- tests/test_ibmq.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_ibmq.py b/tests/test_ibmq.py index c3a0bead1..497133d53 100644 --- a/tests/test_ibmq.py +++ b/tests/test_ibmq.py @@ -278,8 +278,8 @@ def circuit(): assert "job_time" in dev.tracker.history if "job_time" in dev.tracker.history: - assert "creating" in dev.tracker.history["job_time"] - assert "validating" in dev.tracker.history["job_time"] - assert "queued" in dev.tracker.history["job_time"] - assert "running" in dev.tracker.history["job_time"] - assert len(dev.tracker.history["job_time"]) == 4 + assert "creating" in dev.tracker.history["job_time"][0] + assert "validating" in dev.tracker.history["job_time"][0] + assert "queued" in dev.tracker.history["job_time"][0] + assert "running" in dev.tracker.history["job_time"][0] + assert len(dev.tracker.history["job_time"][0]) == 4 From c2223bcb6a5a6835a72133f042cfb0add6edf62f Mon Sep 17 00:00:00 2001 From: KetpuntoG <65235481+KetpuntoG@users.noreply.github.com> Date: Wed, 24 Nov 2021 19:45:46 +0100 Subject: [PATCH 16/16] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3bb8aa12..b9a442aac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ * Added support for the `qml.SX` operation to the Qiskit devices. [(#158)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/158) +* Added support for returning job execution times. [(#160)](https://github.com/PennyLaneAI/pennylane-qiskit/pull/160) + ### Documentation ### Bug fixes @@ -17,7 +19,7 @@ This release contains contributions from (in alphabetical order): -Antal Száva +Guillermo Alonso-Linaje, Antal Száva ---