class_docstr: Test the torch interface execute function
  integrates well for both forward and backward execution
class_docstr_tok: ["Test","the","torch","interface","execute","function","integrates","well","for","both","forward","and","backward","execution"]
docstr: Tests correct output shape and evaluation for a tape
  with prob outputs
code: def test_probability_differentiation(
      self, torch_device, execute_kwargs, tol
  ):
      """Tests correct output shape and evaluation for a tape
      with prob outputs"""
  
      if execute_kwargs["gradient_fn"] == "device":
          pytest.skip(
              "Adjoint differentiation does not yet support probabilities"
          )
  
      dev = qml.device("default.qubit.legacy", wires=2)
      x_val = 0.543
      y_val = -0.654
      x = torch.tensor(x_val, requires_grad=True, device=torch_device)
      y = torch.tensor(y_val, requires_grad=True, device=torch_device)
  
      def circuit(x, y):
          with qml.queuing.AnnotatedQueue() as q:
              qml.RX(x, wires=[0])
              qml.RY(y, wires=[1])
              qml.CNOT(wires=[0, 1])
              qml.probs(wires=[0])
              qml.probs(wires=[1])
  
          tape = qml.tape.QuantumScript.from_queue(q)
  
          return execute([tape], dev, **execute_kwargs)[0]
  
      res = circuit(x, y)
  
      expected_0 = torch.tensor(
          [np.cos(x_val / 2) ** 2, np.sin(x_val / 2) ** 2],
          dtype=res[0].dtype,
          device=torch_device,
      )
  
      expected_1 = torch.tensor(
          [
              (1 + np.cos(x_val) * np.cos(y_val)) / 2,
              (1 - np.cos(x_val) * np.cos(y_val)) / 2,
          ],
          dtype=res[0].dtype,
          device=torch_device,
      )
  
      assert torch.allclose(res[0], expected_0, atol=tol, rtol=0)
      assert torch.allclose(res[1], expected_1, atol=tol, rtol=0)
  
      jac = torch_functional.jacobian(circuit, (x, y))
      dtype_jac = jac[0][0].dtype
  
      res_0 = torch.tensor(
          [-np.sin(x_val) / 2, np.sin(x_val) / 2],
          dtype=dtype_jac,
          device=torch_device,
      )
      res_1 = torch.tensor(
          [0.0, 0.0], dtype=dtype_jac, device=torch_device
      )
      res_2 = torch.tensor(
          [
              -np.sin(x_val) * np.cos(y_val) / 2,
              np.cos(y_val) * np.sin(x_val) / 2,
          ],
          dtype=dtype_jac,
          device=torch_device,
      )
      res_3 = torch.tensor(
          [
              -np.cos(x_val) * np.sin(y_val) / 2,
              +np.cos(x_val) * np.sin(y_val) / 2,
          ],
          dtype=dtype_jac,
          device=torch_device,
      )
  
      assert torch.allclose(jac[0][0], res_0, atol=tol, rtol=0)
      assert torch.allclose(jac[0][1], res_1, atol=tol, rtol=0)
      assert torch.allclose(jac[1][0], res_2, atol=tol, rtol=0)
      assert torch.allclose(jac[1][1], res_3, atol=tol, rtol=0)
  
imports: import numpy
  import pytest
  import pennylane
  from pennylane.gradients import finite_diff, param_shift
  from pennylane import execute
label_desc: Use image node_id 10 for calling the TestTorchExecuteIntegration obj's underlying member method code with example usage: obj.test_probability_differentiation(torch_device, execute_kwargs, tol) and returns: execute