diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index 5e7b4c5c7cc..a213c021666 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -80,8 +80,10 @@ * `default.qubit` now tracks the number of equivalent qpu executions and total shots when the device is sampling. Note that `"simulations"` denotes the number of simulation passes, where as - `"executions"` denotes how many different computational bases need to be sampled in. + `"executions"` denotes how many different computational bases need to be sampled in. Additionally, the + new `default.qubit` also tracks the results of `device.execute`. [(#4628)](https://github.com/PennyLaneAI/pennylane/pull/4628) + [(#4649)](https://github.com/PennyLaneAI/pennylane/pull/4649) * The `JacobianProductCalculator` abstract base class and implementation `TransformJacobianProducts` have been added to `pennylane.interfaces.jacobian_products`. diff --git a/pennylane/devices/default_qubit.py b/pennylane/devices/default_qubit.py index 487a920f3f8..13f1c3d6d89 100644 --- a/pennylane/devices/default_qubit.py +++ b/pennylane/devices/default_qubit.py @@ -129,6 +129,7 @@ def f(x): * ``resources``: the :class:`~.resource.Resources` for the executed circuit. * ``simulations``: the number of simulations performed. One simulation can cover multiple QPU executions, such as for non-commuting measurements and batched parameters. * ``batches``: The number of times :meth:`~.execute` is called. + * ``results``: The results of each call of :meth:`~.execute` * ``derivative_batches``: How many times :meth:`~.compute_derivatives` is called. * ``execute_and_derivative_batches``: How many times :meth:`~.execute_and_compute_derivatives` is called * ``vjp_batches``: How many times :meth:`~.compute_vjp` is called @@ -298,24 +299,6 @@ def execute( is_single_circuit = True circuits = [circuits] - if self.tracker.active: - self.tracker.update(batches=1) - self.tracker.record() - for c in circuits: - qpu_executions, shots = get_num_shots_and_executions(c) - if c.shots: - self.tracker.update( - simulations=1, - executions=qpu_executions, - shots=shots, - resources=c.specs["resources"], - ) - else: - self.tracker.update( - simulations=1, executions=qpu_executions, resources=c.specs["resources"] - ) - self.tracker.record() - max_workers = execution_config.device_options.get("max_workers", self._max_workers) interface = ( execution_config.interface @@ -349,6 +332,29 @@ def execute( # reset _rng to mimic serial behavior self._rng = np.random.default_rng(self._rng.integers(2**31 - 1)) + if self.tracker.active: + self.tracker.update(batches=1) + self.tracker.record() + for i, c in enumerate(circuits): + qpu_executions, shots = get_num_shots_and_executions(c) + res = np.array(results[i]) if isinstance(results[i], Number) else results[i] + if c.shots: + self.tracker.update( + simulations=1, + executions=qpu_executions, + results=res, + shots=shots, + resources=c.specs["resources"], + ) + else: + self.tracker.update( + simulations=1, + executions=qpu_executions, + results=res, + resources=c.specs["resources"], + ) + self.tracker.record() + return results[0] if is_single_circuit else results def compute_derivatives( diff --git a/tests/devices/test_default_qubit_tracking.py b/tests/devices/test_default_qubit_tracking.py index 93c0981f95d..16e35f09adc 100644 --- a/tests/devices/test_default_qubit_tracking.py +++ b/tests/devices/test_default_qubit_tracking.py @@ -55,6 +55,7 @@ def test_tracking_batch(self): "batches": [1, 1], "executions": [1, 1, 1], "simulations": [1, 1, 1], + "results": [1.0, 1.0, 1.0], "resources": [Resources(num_wires=1), Resources(num_wires=1), Resources(num_wires=1)], "derivative_batches": [1], "derivatives": [1], @@ -69,6 +70,7 @@ def test_tracking_batch(self): assert tracker.latest == { "executions": 1, "simulations": 1, + "results": 1, "resources": Resources(num_wires=1), }