class_docstr: A PennyLane device written in Python and capable of backpropagation derivatives.
  
  Args:
      wires (int, Iterable[Number, str]): Number of wires present on the device, or iterable that
          contains unique labels for the wires as numbers (i.e., ``[-1, 0, 2]``) or strings
          (``['ancilla', 'q1', 'q2']``). Default ``None`` if not specified.
      shots (int, Sequence[int], Sequence[Union[int, Sequence[int]]]): The default number of shots
          to use in executions involving this device.
      seed (Union[str, None, int, array_like[int], SeedSequence, BitGenerator, Generator, jax.random.PRNGKey]): A
          seed-like parameter matching that of ``seed`` for ``numpy.random.default_rng``, or
          a request to seed from numpy's global random number generator.
          The default, ``seed="global"`` pulls a seed from NumPy's global generator. ``seed=None``
          will pull a seed from the OS entropy.
          If a ``jax.random.PRNGKey`` is passed as the seed, a JAX-specific sampling function using
          ``jax.random.choice`` and the ``PRNGKey`` will be used for sampling rather than
          ``numpy.random.default_rng``.
      max_workers (int): A ``ProcessPoolExecutor`` executes tapes asynchronously
          using a pool of at most ``max_workers`` processes. If ``max_workers`` is ``None``,
          only the current process executes tapes. If you experience any
          issue, say using JAX, TensorFlow, Torch, try setting ``max_workers`` to ``None``.
  
  **Example:**
  
  .. code-block:: python
  
      n_layers = 5
      n_wires = 10
      num_qscripts = 5
  
      shape = qml.StronglyEntanglingLayers.shape(n_layers=n_layers, n_wires=n_wires)
      rng = qml.numpy.random.default_rng(seed=42)
  
      qscripts = []
      for i in range(num_qscripts):
          params = rng.random(shape)
          op = qml.StronglyEntanglingLayers(params, wires=range(n_wires))
          qs = qml.tape.QuantumScript([op], [qml.expval(qml.PauliZ(0))])
          qscripts.append(qs)
  
  >>> dev = DefaultQubit()
  >>> program, execution_config = dev.preprocess()
  >>> new_batch, post_processing_fn = program(qscripts)
  >>> results = dev.execute(new_batch, execution_config=execution_config)
  >>> post_processing_fn(results)
  [-0.0006888975950537501,
  0.025576307134457577,
  -0.0038567269892757494,
  0.1339705146860149,
  -0.03780669772690448]
  
  This device currently supports backpropagation derivatives:
  
  >>> from pennylane.devices import ExecutionConfig
  >>> dev.supports_derivatives(ExecutionConfig(gradient_method="backprop"))
  True
  
  For example, we can use jax to jit computing the derivative:
  
  .. code-block:: python
  
      import jax
  
      @jax.jit
      def f(x):
          qs = qml.tape.QuantumScript([qml.RX(x, 0)], [qml.expval(qml.PauliZ(0))])
          program, execution_config = dev.preprocess()
          new_batch, post_processing_fn = program([qs])
          results = dev.execute(new_batch, execution_config=execution_config)
          return post_processing_fn(results)
  
  >>> f(jax.numpy.array(1.2))
  DeviceArray(0.36235774, dtype=float32)
  >>> jax.grad(f)(jax.numpy.array(1.2))
  DeviceArray(-0.93203914, dtype=float32, weak_type=True)
  
  .. details::
      :title: Tracking
  
      ``DefaultQubit`` tracks:
  
      * ``executions``: the number of unique circuits that would be required on quantum hardware
      * ``shots``: the number of shots
      * ``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
      * ``execute_and_vjp_batches``: How many times :meth:`~.execute_and_compute_vjp` is called
      * ``jvp_batches``: How many times :meth:`~.compute_jvp` is called
      * ``execute_and_jvp_batches``: How many times :meth:`~.execute_and_compute_jvp` is called
      * ``derivatives``: How many circuits are submitted to :meth:`~.compute_derivatives` or :meth:`~.execute_and_compute_derivatives`.
      * ``vjps``: How many circuits are submitted to :meth:`~.compute_vjp` or :meth:`~.execute_and_compute_vjp`
      * ``jvps``: How many circuits are submitted to :meth:`~.compute_jvp` or :meth:`~.execute_and_compute_jvp`
  
  
  .. details::
      :title: Accelerate calculations with multiprocessing
  
      Suppose one has a processor with 5 cores or more, these scripts can be executed in
      parallel as follows
  
      >>> dev = DefaultQubit(max_workers=5)
      >>> program, execution_config = dev.preprocess()
      >>> new_batch, post_processing_fn = program(qscripts)
      >>> results = dev.execute(new_batch, execution_config=execution_config)
      >>> post_processing_fn(results)
  
      If you monitor your CPU usage, you should see 5 new Python processes pop up to
      crunch through those ``QuantumScript``'s. Beware not oversubscribing your machine.
      This may happen if a single device already uses many cores, if NumPy uses a multi-
      threaded BLAS library like MKL or OpenBLAS for example. The number of threads per
      process times the number of processes should not exceed the number of cores on your
      machine. You can control the number of threads per process with the environment
      variables:
  
      * OMP_NUM_THREADS
      * MKL_NUM_THREADS
      * OPENBLAS_NUM_THREADS
  
      where the last two are specific to the MKL and OpenBLAS libraries specifically.
  
      .. warning::
  
          Multiprocessing may fail depending on your platform and environment (Python shell,
          script with a protected entry point, Jupyter notebook, etc.) This may be solved
          changing the so-called start method. The supported start methods are the following:
  
          * Windows (win32): spawn (default).
          * macOS (darwin): spawn (default), fork, forkserver.
          * Linux (unix): spawn, fork (default), forkserver.
  
          which can be changed with ``multiprocessing.set_start_method()``. For example,
          if multiprocessing fails on macOS in your Jupyter notebook environment, try
          restarting the session and adding the following at the beginning of the file:
  
          .. code-block:: python
  
              import multiprocessing
              multiprocessing.set_start_method("fork")
  
          Additional information can be found in the
          `multiprocessing doc <https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods>`_.
class_docstr_tok: ["A","PennyLane","device","written","in","Python","and","capable","of","backpropagation","derivatives",".","Args",":","wires","(","int",",","Iterable","[","Number",",","str","]",")",":","Number","of","wires","present","on","the","device",",","or","iterable","that","contains","unique","labels","for","the","wires","as","numbers","(","i.e.",",","``","[","-1",",","0",",","2","]","``",")","or","strings","(","``","[","'ancilla","'",",","'q1","'",",","'q2","'","]","``",")",".","Default","``","None","``","if","not","specified",".","shots","(","int",",","Sequence","[","int","]",",","Sequence","[","Union","[","int",",","Sequence","[","int","]","]","]",")",":","The","default","number","of","shots","to","use","in","executions","involving","this","device",".","seed","(","Union","[","str",",","None",",","int",",","array_like","[","int","]",",","SeedSequence",",","BitGenerator",",","Generator",",","jax.random.PRNGKey","]",")",":","A","seed-like","parameter","matching","that","of","``","seed","``","for","``","numpy.random.default_rng","``",",","or","a","request","to","seed","from","numpy","'s","global","random","number","generator",".","The","default",",","``","seed=","''","global","''","``","pulls","a","seed","from","NumPy","'s","global","generator",".","``","seed=None","``","will","pull","a","seed","from","the","OS","entropy",".","If","a","``","jax.random.PRNGKey","``","is","passed","as","the","seed",",","a","JAX-specific","sampling","function","using","``","jax.random.choice","``","and","the","``","PRNGKey","``","will","be","used","for","sampling","rather","than","``","numpy.random.default_rng","``",".","max_workers","(","int",")",":","A","``","ProcessPoolExecutor","``","executes","tapes","asynchronously","using","a","pool","of","at","most","``","max_workers","``","processes",".","If","``","max_workers","``","is","``","None","``",",","only","the","current","process","executes","tapes",".","If","you","experience","any","issue",",","say","using","JAX",",","TensorFlow",",","Torch",",","try","setting","``","max_workers","``","to","``","None","``",".","*","*","Example",":","*","*","..","code-block",":",":","python","n_layers","=","5","n_wires","=","10","num_qscripts","=","5","shape","=","qml.StronglyEntanglingLayers.shape","(","n_layers=n_layers",",","n_wires=n_wires",")","rng","=","qml.numpy.random.default_rng","(","seed=42",")","qscripts","=","[","]","for","i","in","range","(","num_qscripts",")",":","params","=","rng.random","(","shape",")","op","=","qml.StronglyEntanglingLayers","(","params",",","wires=range","(","n_wires",")",")","qs","=","qml.tape.QuantumScript","(","[","op","]",",","[","qml.expval","(","qml.PauliZ","(","0",")",")","]",")","qscripts.append","(","qs",")",">",">",">","dev","=","DefaultQubit","(",")",">",">",">","program",",","execution_config","=","dev.preprocess","(",")",">",">",">","new_batch",",","post_processing_fn","=","program","(","qscripts",")",">",">",">","results","=","dev.execute","(","new_batch",",","execution_config=execution_config",")",">",">",">","post_processing_fn","(","results",")","[","-0.0006888975950537501",",","0.025576307134457577",",","-0.0038567269892757494",",","0.1339705146860149",",","-0.03780669772690448","]","This","device","currently","supports","backpropagation","derivatives",":",">",">",">","from","pennylane.devices","import","ExecutionConfig",">",">",">","dev.supports_derivatives","(","ExecutionConfig","(","gradient_method=","''","backprop","''",")",")","True","For","example",",","we","can","use","jax","to","jit","computing","the","derivative",":","..","code-block",":",":","python","import","jax","@","jax.jit","def","f","(","x",")",":","qs","=","qml.tape.QuantumScript","(","[","qml.RX","(","x",",","0",")","]",",","[","qml.expval","(","qml.PauliZ","(","0",")",")","]",")","program",",","execution_config","=","dev.preprocess","(",")","new_batch",",","post_processing_fn","=","program","(","[","qs","]",")","results","=","dev.execute","(","new_batch",",","execution_config=execution_config",")","return","post_processing_fn","(","results",")",">",">",">","f","(","jax.numpy.array","(","1.2",")",")","DeviceArray","(","0.36235774",",","dtype=float32",")",">",">",">","jax.grad","(","f",")","(","jax.numpy.array","(","1.2",")",")","DeviceArray","(","-0.93203914",",","dtype=float32",",","weak_type=True",")","..","details",":",":",":","title",":","Tracking","``","DefaultQubit","``","tracks",":","*","``","executions","``",":","the","number","of","unique","circuits","that","would","be","required","on","quantum","hardware","*","``","shots","``",":","the","number","of","shots","*","``","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","*","``","execute_and_vjp_batches","``",":","How","many","times",":","meth",":","`","~.execute_and_compute_vjp","`","is","called","*","``","jvp_batches","``",":","How","many","times",":","meth",":","`","~.compute_jvp","`","is","called","*","``","execute_and_jvp_batches","``",":","How","many","times",":","meth",":","`","~.execute_and_compute_jvp","`","is","called","*","``","derivatives","``",":","How","many","circuits","are","submitted","to",":","meth",":","`","~.compute_derivatives","`","or",":","meth",":","`","~.execute_and_compute_derivatives","`",".","*","``","vjps","``",":","How","many","circuits","are","submitted","to",":","meth",":","`","~.compute_vjp","`","or",":","meth",":","`","~.execute_and_compute_vjp","`","*","``","jvps","``",":","How","many","circuits","are","submitted","to",":","meth",":","`","~.compute_jvp","`","or",":","meth",":","`","~.execute_and_compute_jvp","`","..","details",":",":",":","title",":","Accelerate","calculations","with","multiprocessing","Suppose","one","has","a","processor","with","5","cores","or","more",",","these","scripts","can","be","executed","in","parallel","as","follows",">",">",">","dev","=","DefaultQubit","(","max_workers=5",")",">",">",">","program",",","execution_config","=","dev.preprocess","(",")",">",">",">","new_batch",",","post_processing_fn","=","program","(","qscripts",")",">",">",">","results","=","dev.execute","(","new_batch",",","execution_config=execution_config",")",">",">",">","post_processing_fn","(","results",")","If","you","monitor","your","CPU","usage",",","you","should","see","5","new","Python","processes","pop","up","to","crunch","through","those","``","QuantumScript","``","'s",".","Beware","not","oversubscribing","your","machine",".","This","may","happen","if","a","single","device","already","uses","many","cores",",","if","NumPy","uses","a","multi-","threaded","BLAS","library","like","MKL","or","OpenBLAS","for","example",".","The","number","of","threads","per","process","times","the","number","of","processes","should","not","exceed","the","number","of","cores","on","your","machine",".","You","can","control","the","number","of","threads","per","process","with","the","environment","variables",":","*","OMP_NUM_THREADS","*","MKL_NUM_THREADS","*","OPENBLAS_NUM_THREADS","where","the","last","two","are","specific","to","the","MKL","and","OpenBLAS","libraries","specifically",".","..","warning",":",":","Multiprocessing","may","fail","depending","on","your","platform","and","environment","(","Python","shell",",","script","with","a","protected","entry","point",",","Jupyter","notebook",",","etc",".",")","This","may","be","solved","changing","the","so-called","start","method",".","The","supported","start","methods","are","the","following",":","*","Windows","(","win32",")",":","spawn","(","default",")",".","*","macOS","(","darwin",")",":","spawn","(","default",")",",","fork",",","forkserver",".","*","Linux","(","unix",")",":","spawn",",","fork","(","default",")",",","forkserver",".","which","can","be","changed","with","``","multiprocessing.set_start_method","(",")","``",".","For","example",",","if","multiprocessing","fails","on","macOS","in","your","Jupyter","notebook","environment",",","try","restarting","the","session","and","adding","the","following","at","the","beginning","of","the","file",":","..","code-block",":",":","python","import","multiprocessing","multiprocessing.set_start_method","(","``","fork","''",")","Additional","information","can","be","found","in","the","`","multiprocessing","doc","<","https",":","\/\/docs.python.org\/3\/library\/multiprocessing.html","#","contexts-and-start-methods",">","`","_","."]
code: def compute_derivatives(
      self,
      circuits: QuantumTape_or_Batch,
      execution_config: ExecutionConfig = DefaultExecutionConfig,
  ):
      is_single_circuit = False
      if isinstance(circuits, QuantumScript):
          is_single_circuit = True
          circuits = [circuits]
  
      if self.tracker.active:
          self.tracker.update(
              derivative_batches=1, derivatives=len(circuits)
          )
          self.tracker.record()
  
      max_workers = execution_config.device_options.get(
          "max_workers", self._max_workers
      )
      if max_workers is None:
          res = tuple(adjoint_jacobian(circuit) for circuit in circuits)
      else:
          vanilla_circuits = [
              convert_to_numpy_parameters(c) for c in circuits
          ]
          with concurrent.futures.ProcessPoolExecutor(
              max_workers=max_workers
          ) as executor:
              exec_map = executor.map(
                  adjoint_jacobian, vanilla_circuits
              )
              res = tuple(exec_map)
  
          # reset _rng to mimic serial behavior
          self._rng = np.random.default_rng(
              self._rng.integers(2**31 - 1)
          )
  
      return res[0] if is_single_circuit else res
  
imports: from dataclasses import replace
  from functools import partial
  from numbers import Number
  from typing import Union, Callable, Tuple, Optional, Sequence
  import concurrent.futures
  import inspect
  import logging
  import numpy
  import pennylane
  from pennylane.tape import QuantumTape, QuantumScript
  from pennylane.typing import Result, ResultBatch
  from pennylane.transforms import convert_to_numpy_parameters
  from pennylane.transforms.core import TransformProgram
  from .None import Device
  from .preprocess import decompose, validate_observables, validate_measurements, validate_multiprocessing_workers, validate_device_wires, validate_adjoint_trainable_params, no_sampling
  from .execution_config import ExecutionConfig, DefaultExecutionConfig
  from .qubit.simulate import simulate, get_final_state, measure_final_state
  from .qubit.sampling import get_num_shots_and_executions
  from .qubit.adjoint_jacobian import adjoint_jacobian, adjoint_vjp, adjoint_jvp
label_desc: Use image node_id 7 for calling the DefaultQubit obj's underlying member method code with example usage: obj.compute_derivatives(circuits, execution_config) and returns: unknown