class_docstr: Class for registering a tape transform that takes a tape, and outputs
  a batch of tapes to be independently executed on a quantum device.
  
  .. warning::
  
      Use of ``batch_transform`` to create a custom transform is deprecated. Instead
      switch to using the new :func:`transform` function. Follow the instructions
      `here <https://docs.pennylane.ai/en/stable/code/qml_transforms.html#custom-transforms>`_
      for further details
  
  Examples of such transforms include quantum gradient shift rules (such
  as finite-differences and the parameter-shift rule) and metrics such as
  the quantum Fisher information matrix.
  
  Args:
      transform_fn (function): The function to register as the batch tape transform.
          It can have an arbitrary number of arguments, but the first argument
          **must** be the input tape.
      expand_fn (function): An expansion function (if required) to be applied to the
          input tape before the transformation takes place.
          It **must** take the same input arguments as ``transform_fn``.
      differentiable (bool): Specifies whether the transform is differentiable or
          not. A transform may be non-differentiable for several reasons:
  
          - It does not use an autodiff framework for its tensor manipulations;
          - It returns a non-differentiable or non-numeric quantity, such as
            a boolean, string, or integer.
  
          In such a case, setting ``differentiable=False`` instructs the decorator
          to mark the output as 'constant', reducing potential overhead.
  
  **Example**
  
  A valid batch tape transform is a function that satisfies the following:
  
  - The first argument must be a tape.
  
  - Depending on the structure of this input tape, various quantum operations, functions,
    and templates may be called.
  
  - Any internal classical processing should use the ``qml.math`` module to ensure
    the transform is differentiable.
  
  - The transform should return a tuple containing:
  
    * Multiple transformed tapes to be executed on a device.
    * A classical processing function for post-processing the executed tape results.
      This processing function should have the signature ``f(list[tensor_like]) → Any``.
      If ``None``, no classical processing is applied to the results.
  
  For example:
  
  .. code-block:: python
  
      @qml.batch_transform
      def my_transform(tape, a, b):
          '''Generates two tapes, one with all RX replaced with RY,
          and the other with all RX replaced with RZ.'''
  
          ops1 = []
          ops2 = []
  
          # loop through all operations on the input tape
          for op in tape.operations:
              if op.name == "RX":
                  wires = op.wires
                  param = op.parameters[0]
  
                  ops1.append(qml.RY(a * qml.math.abs(param), wires=wires))
                  ops2.append(qml.RZ(b * qml.math.abs(param), wires=wires))
              else:
                  ops1.append(op)
                  ops2.append(op)
  
          tape1 = qml.tape.QuantumTape(ops1, tape.measurements)
          tape2 = qml.tape.QuantumTape(ops2, tape.measurements)
  
          def processing_fn(results):
              return qml.math.sum(qml.math.stack(results))
  
          return [tape1, tape2], processing_fn
  
  We can apply this transform to a quantum tape:
  
  >>> ops = [qml.Hadamard(wires=0), qml.RX(-0.5, wires=0)]
  >>> tape = qml.tape.QuantumTape(ops, [qml.expval(qml.PauliX(0))])
  >>> tapes, fn = my_transform(tape, 0.65, 2.5)
  >>> print(qml.drawer.tape_text(tapes[0], decimals=2))
  0: ──H──RY(0.33)─┤  <X>
  >>> print(qml.drawer.tape_text(tapes[1], decimals=2))
  0: ──H──RZ(1.25)─┤  <X>
  
  We can execute these tapes manually:
  
  >>> dev = qml.device("default.qubit", wires=1)
  >>> res = qml.execute(tapes, dev, interface="autograd", gradient_fn=qml.gradients.param_shift)
  >>> print(res)
  [0.9476507264148154, 0.31532236239526856]
  
  Applying the processing function, we retrieve the end result of the transform:
  
  >>> print(fn(res))
  1.2629730888100839
  
  Alternatively, we may also transform a QNode directly, using either
  decorator syntax:
  
  >>> @my_transform(0.65, 2.5)
  ... @qml.qnode(dev)
  ... def circuit(x):
  ...     qml.Hadamard(wires=0)
  ...     qml.RX(x, wires=0)
  ...     return qml.expval(qml.PauliX(0))
  >>> print(circuit(-0.5))
  1.2629730888100839
  
  or by transforming an existing QNode:
  
  >>> @qml.qnode(dev)
  ... def circuit(x):
  ...     qml.Hadamard(wires=0)
  ...     qml.RX(x, wires=0)
  ...     return qml.expval(qml.PauliX(0))
  >>> circuit = my_transform(circuit, 0.65, 2.5)
  >>> print(circuit(-0.5))
  1.2629730888100839
  
  Batch tape transforms are fully differentiable:
  
  >>> x = np.array(-0.5, requires_grad=True)
  >>> gradient = qml.grad(circuit)(x)
  >>> print(gradient)
  2.5800122591960153
  
  .. details::
      :title: Usage Details
  
      **Expansion functions**
  
      Tape expansion, decomposition, or manipulation may always be
      performed within the custom batch transform. However, by specifying
      a separate expansion function, PennyLane will be possible to access
      this separate expansion function where needed via
  
      >>> my_transform.expand_fn
  
      The provided ``expand_fn`` must have the same input arguments as
      ``transform_fn`` and return a ``tape``. Following the example above:
  
      .. code-block:: python
  
          def expand_fn(tape, a, b):
              stopping_crit = lambda obj: obj.name!="PhaseShift"
              return tape.expand(depth=10, stop_at=stopping_crit)
  
          my_transform = batch_transform(my_transform, expand_fn)
  
      Note that:
  
      - the transform arguments ``a`` and ``b`` must be passed to
        the expansion function, and
      - the expansion function must return a single tape.
class_docstr_tok: ["Class","for","registering","a","tape","transform","that","takes","a","tape",",","and","outputs","a","batch","of","tapes","to","be","independently","executed","on","a","quantum","device",".","..","warning",":",":","Use","of","``","batch_transform","``","to","create","a","custom","transform","is","deprecated",".","Instead","switch","to","using","the","new",":","func",":","`","transform","`","function",".","Follow","the","instructions","`","here","<","https",":","\/\/docs.pennylane.ai\/en\/stable\/code\/qml_transforms.html","#","custom-transforms",">","`","_","for","further","details","Examples","of","such","transforms","include","quantum","gradient","shift","rules","(","such","as","finite-differences","and","the","parameter-shift","rule",")","and","metrics","such","as","the","quantum","Fisher","information","matrix",".","Args",":","transform_fn","(","function",")",":","The","function","to","register","as","the","batch","tape","transform",".","It","can","have","an","arbitrary","number","of","arguments",",","but","the","first","argument","*","*","must","*","*","be","the","input","tape",".","expand_fn","(","function",")",":","An","expansion","function","(","if","required",")","to","be","applied","to","the","input","tape","before","the","transformation","takes","place",".","It","*","*","must","*","*","take","the","same","input","arguments","as","``","transform_fn","``",".","differentiable","(","bool",")",":","Specifies","whether","the","transform","is","differentiable","or","not",".","A","transform","may","be","non-differentiable","for","several","reasons",":","-","It","does","not","use","an","autodiff","framework","for","its","tensor","manipulations",";","-","It","returns","a","non-differentiable","or","non-numeric","quantity",",","such","as","a","boolean",",","string",",","or","integer",".","In","such","a","case",",","setting","``","differentiable=False","``","instructs","the","decorator","to","mark","the","output","as","'constant","'",",","reducing","potential","overhead",".","*","*","Example","*","*","A","valid","batch","tape","transform","is","a","function","that","satisfies","the","following",":","-","The","first","argument","must","be","a","tape",".","-","Depending","on","the","structure","of","this","input","tape",",","various","quantum","operations",",","functions",",","and","templates","may","be","called",".","-","Any","internal","classical","processing","should","use","the","``","qml.math","``","module","to","ensure","the","transform","is","differentiable",".","-","The","transform","should","return","a","tuple","containing",":","*","Multiple","transformed","tapes","to","be","executed","on","a","device",".","*","A","classical","processing","function","for","post-processing","the","executed","tape","results",".","This","processing","function","should","have","the","signature","``","f","(","list","[","tensor_like","]",")","\u2192","Any","``",".","If","``","None","``",",","no","classical","processing","is","applied","to","the","results",".","For","example",":","..","code-block",":",":","python","@","qml.batch_transform","def","my_transform","(","tape",",","a",",","b",")",":","``","'Generates","two","tapes",",","one","with","all","RX","replaced","with","RY",",","and","the","other","with","all","RX","replaced","with","RZ",".","''","'","ops1","=","[","]","ops2","=","[","]","#","loop","through","all","operations","on","the","input","tape","for","op","in","tape.operations",":","if","op.name","==","``","RX","''",":","wires","=","op.wires","param","=","op.parameters","[","0","]","ops1.append","(","qml.RY","(","a","*","qml.math.abs","(","param",")",",","wires=wires",")",")","ops2.append","(","qml.RZ","(","b","*","qml.math.abs","(","param",")",",","wires=wires",")",")","else",":","ops1.append","(","op",")","ops2.append","(","op",")","tape1","=","qml.tape.QuantumTape","(","ops1",",","tape.measurements",")","tape2","=","qml.tape.QuantumTape","(","ops2",",","tape.measurements",")","def","processing_fn","(","results",")",":","return","qml.math.sum","(","qml.math.stack","(","results",")",")","return","[","tape1",",","tape2","]",",","processing_fn","We","can","apply","this","transform","to","a","quantum","tape",":",">",">",">","ops","=","[","qml.Hadamard","(","wires=0",")",",","qml.RX","(","-0.5",",","wires=0",")","]",">",">",">","tape","=","qml.tape.QuantumTape","(","ops",",","[","qml.expval","(","qml.PauliX","(","0",")",")","]",")",">",">",">","tapes",",","fn","=","my_transform","(","tape",",","0.65",",","2.5",")",">",">",">","print","(","qml.drawer.tape_text","(","tapes","[","0","]",",","decimals=2",")",")","0",":","\u2500\u2500H\u2500\u2500RY","(","0.33",")","\u2500\u2524","<","X",">",">",">",">","print","(","qml.drawer.tape_text","(","tapes","[","1","]",",","decimals=2",")",")","0",":","\u2500\u2500H\u2500\u2500RZ","(","1.25",")","\u2500\u2524","<","X",">","We","can","execute","these","tapes","manually",":",">",">",">","dev","=","qml.device","(","``","default.qubit","''",",","wires=1",")",">",">",">","res","=","qml.execute","(","tapes",",","dev",",","interface=","''","autograd","''",",","gradient_fn=qml.gradients.param_shift",")",">",">",">","print","(","res",")","[","0.9476507264148154",",","0.31532236239526856","]","Applying","the","processing","function",",","we","retrieve","the","end","result","of","the","transform",":",">",">",">","print","(","fn","(","res",")",")","1.2629730888100839","Alternatively",",","we","may","also","transform","a","QNode","directly",",","using","either","decorator","syntax",":",">",">",">","@","my_transform","(","0.65",",","2.5",")","...","@","qml.qnode","(","dev",")","...","def","circuit","(","x",")",":","...","qml.Hadamard","(","wires=0",")","...","qml.RX","(","x",",","wires=0",")","...","return","qml.expval","(","qml.PauliX","(","0",")",")",">",">",">","print","(","circuit","(","-0.5",")",")","1.2629730888100839","or","by","transforming","an","existing","QNode",":",">",">",">","@","qml.qnode","(","dev",")","...","def","circuit","(","x",")",":","...","qml.Hadamard","(","wires=0",")","...","qml.RX","(","x",",","wires=0",")","...","return","qml.expval","(","qml.PauliX","(","0",")",")",">",">",">","circuit","=","my_transform","(","circuit",",","0.65",",","2.5",")",">",">",">","print","(","circuit","(","-0.5",")",")","1.2629730888100839","Batch","tape","transforms","are","fully","differentiable",":",">",">",">","x","=","np.array","(","-0.5",",","requires_grad=True",")",">",">",">","gradient","=","qml.grad","(","circuit",")","(","x",")",">",">",">","print","(","gradient",")","2.5800122591960153","..","details",":",":",":","title",":","Usage","Details","*","*","Expansion","functions","*","*","Tape","expansion",",","decomposition",",","or","manipulation","may","always","be","performed","within","the","custom","batch","transform",".","However",",","by","specifying","a","separate","expansion","function",",","PennyLane","will","be","possible","to","access","this","separate","expansion","function","where","needed","via",">",">",">","my_transform.expand_fn","The","provided","``","expand_fn","``","must","have","the","same","input","arguments","as","``","transform_fn","``","and","return","a","``","tape","``",".","Following","the","example","above",":","..","code-block",":",":","python","def","expand_fn","(","tape",",","a",",","b",")",":","stopping_crit","=","lambda","obj",":","obj.name","!","=","''","PhaseShift","''","return","tape.expand","(","depth=10",",","stop_at=stopping_crit",")","my_transform","=","batch_transform","(","my_transform",",","expand_fn",")","Note","that",":","-","the","transform","arguments","``","a","``","and","``","b","``","must","be","passed","to","the","expansion","function",",","and","-","the","expansion","function","must","return","a","single","tape","."]
docstr: Applies the batch tape transform to an input tape.
  
  Args:
      tape (.QuantumTape): the tape to be transformed
      *args: positional arguments to pass to the tape transform
      **kwargs: keyword arguments to pass to the tape transform
  
  Returns:
      tuple[list[tapes], callable]: list of transformed tapes
      to execute and a post-processing function.
docstr_tok: ["Applies","the","batch","tape","transform","to","an","input","tape",".","Args",":","tape","(",".QuantumTape",")",":","the","tape","to","be","transformed","*","args",":","positional","arguments","to","pass","to","the","tape","transform","*","*","kwargs",":","keyword","arguments","to","pass","to","the","tape","transform","Returns",":","tuple","[","list","[","tapes","]",",","callable","]",":","list","of","transformed","tapes","to","execute","and","a","post-processing","function","."]
code: def construct(self, tape, *targs, **tkwargs):
      """Applies the batch tape transform to an input tape.
  
      Args:
          tape (.QuantumTape): the tape to be transformed
          *args: positional arguments to pass to the tape transform
          **kwargs: keyword arguments to pass to the tape transform
  
      Returns:
          tuple[list[tapes], callable]: list of transformed tapes
          to execute and a post-processing function.
      """
      expand = tkwargs.pop("_expand", True)
      argnums = tkwargs.pop("argnums", None)
  
      if expand and self.expand_fn is not None:
          tape = self.expand_fn(tape, *targs, **tkwargs)
  
      if argnums is not None:
          tape.trainable_params = argnums  # pragma: no cover
      tapes, processing_fn = self.transform_fn(tape, *targs, **tkwargs)
  
      if processing_fn is None:
  
          def processing_fn(x):
              return x
  
      return tapes, processing_fn
  
file_path: pennylane/pennylane/transforms/batch_transform.py
imports: import copy
  import functools
  import inspect
  import os
  import types
  import warnings
  from typing import Callable, Tuple
  import pennylane
  from pennylane.typing import ResultBatch
label_desc: Use image node_id 6 for calling the batch_transform obj's underlying member method code with example usage: obj.construct(tape) and returns: tapes,  processing_fn, x