class_docstr: Test caching for device jacobians.
class_docstr_tok: ["Test","caching","for","device","jacobians","."]
docstr: Test that results and jacobians are cached on calls to execute.
docstr_tok: ["Test","that","results","and","jacobians","are","cached","on","calls","to","execute","."]
code: def test_execution_caching(self, jpc):
      """Test that results and jacobians are cached on calls to execute."""
      tape1 = qml.tape.QuantumScript(
          [qml.RX(0.1, wires=0)], [qml.expval(qml.PauliZ(0))]
      )
      batch = (tape1,)
  
      with jpc._device.tracker:
          results = jpc.execute_and_cache_jacobian(batch)
  
      assert qml.math.allclose(results[0], np.cos(0.1))
      assert (
          jpc._device.tracker.totals["execute_and_derivative_batches"]
          == 1
      )
      assert jpc._device.tracker.totals["derivatives"] == 1
  
      # extra execution since needs to do the forward pass again.
      if jpc._uses_new_device:
          expected_execs = (
              3
              if isinstance(jpc._device, ParamShiftDerivativesDevice)
              else 1
          )
      else:
          expected_execs = 2
      assert jpc._device.tracker.totals["executions"] == expected_execs
  
      # Test reuse with jacobian
      with jpc._device.tracker:
          jac = jpc.compute_jacobian(batch)
  
      assert qml.math.allclose(jac, -np.sin(0.1))
      assert jpc._device.tracker.totals.get("derivatives", 0) == 0
      assert jpc._device.tracker.totals.get("executions", 0) == 0
  
      # Test reuse with execute_and_compute_jvp
      with jpc._device.tracker:
          res2, jvp = jpc.execute_and_compute_jvp(batch, ((0.5,),))
  
      assert qml.math.allclose(res2, results)
      assert qml.math.allclose(jvp, 0.5 * -np.sin(0.1))
      assert jpc._device.tracker.totals.get("derivatives", 0) == 0
      assert jpc._device.tracker.totals.get("executions", 0) == 0
  
      # Test reuse with compute_vjp
      with jpc._device.tracker:
          vjp = jpc.compute_vjp(batch, ((1.5,),))
  
      assert qml.math.allclose(vjp, -1.5 * np.sin(0.1))
      assert jpc._device.tracker.totals.get("derivatives", 0) == 0
      assert jpc._device.tracker.totals.get("executions", 0) == 0
  
      # Test device called again if batch a new instance, even if identical
      tape2 = qml.tape.QuantumScript(
          [qml.RX(0.1, wires=0)], [qml.expval(qml.PauliZ(0))]
      )
      batch2 = (tape2,)
  
      with jpc._device.tracker:
          jac2 = jpc.compute_jacobian(batch2)
  
      assert qml.math.allclose(jac, jac2)
      assert jpc._device.tracker.totals["derivatives"] == 1
      if jpc._uses_new_device:
          expected_execs = (
              2
              if isinstance(jpc._device, ParamShiftDerivativesDevice)
              else 0
          )
      else:
          expected_execs = 1
      assert (
          jpc._device.tracker.totals.get("executions", 0)
          == expected_execs
      )
  
imports: import pytest
  from cachetools import LRUCache
  from param_shift_dev import ParamShiftDerivativesDevice
  import numpy
  import pennylane
  from pennylane.workflow.jacobian_products import JacobianProductCalculator, TransformJacobianProducts, DeviceDerivatives, DeviceJacobianProducts, LightningVJPs
label_desc: Use image node_id 1 for calling the TestCachingDeviceDerivatives obj's underlying member method code with example usage: obj.test_execution_caching(jpc) without return types