class_docstr: Simulator plugin based on ``"default.qubit.legacy"``, written using PyTorch.
  
  **Short name:** ``default.qubit.torch``
  
  This device provides a pure-state qubit simulator written using PyTorch.
  As a result, it supports classical backpropagation as a means to compute the Jacobian. This can
  be faster than the parameter-shift rule for analytic quantum gradients
  when the number of parameters to be optimized is large.
  
  To use this device, you will need to install PyTorch:
  
  .. code-block:: console
  
      pip install torch>=1.8.0
  
  **Example**
  
  The ``default.qubit.torch`` is designed to be used with end-to-end classical backpropagation
  (``diff_method="backprop"``) and the PyTorch interface. This is the default method
  of differentiation when creating a QNode with this device.
  
  Using this method, the created QNode is a 'white-box', and is
  tightly integrated with your PyTorch computation:
  
  .. code-block:: python
  
      dev = qml.device("default.qubit.torch", wires=1)
  
      @qml.qnode(dev, interface="torch", diff_method="backprop")
      def circuit(x):
          qml.RX(x[1], wires=0)
          qml.Rot(x[0], x[1], x[2], wires=0)
          return qml.expval(qml.PauliZ(0))
  
  >>> weights = torch.tensor([0.2, 0.5, 0.1], requires_grad=True)
  >>> res = circuit(weights)
  >>> res.backward()
  >>> print(weights.grad)
  tensor([-2.2527e-01, -1.0086e+00,  1.3878e-17])
  
  Autograd mode will also work when using classical backpropagation:
  
  >>> def cost(weights):
  ...    return torch.sum(circuit(weights)**3) - 1
  >>> res = circuit(weights)
  >>> res.backward()
  >>> print(weights.grad)
  tensor([-4.5053e-01, -2.0173e+00,  5.9837e-17])
  
  Executing the pipeline in PyTorch will allow the whole computation to be run on the GPU,
  and therefore providing an acceleration. Your parameters need to be instantiated on the same
  device as the backend device.
  
  .. code-block:: python
  
      dev = qml.device("default.qubit.torch", wires=1, torch_device='cuda')
  
      @qml.qnode(dev, interface="torch", diff_method="backprop")
      def circuit(x):
          qml.RX(x[1], wires=0)
          qml.Rot(x[0], x[1], x[2], wires=0)
          return qml.expval(qml.PauliZ(0))
  
  >>> weights = torch.tensor([0.2, 0.5, 0.1], requires_grad=True, device='cuda')
  >>> res = circuit(weights)
  >>> res.backward()
  >>> print(weights.grad)
  tensor([-2.2527e-01, -1.0086e+00,  2.9919e-17], device='cuda:0')
  
  
  There are a couple of things to keep in mind when using the ``"backprop"``
  differentiation method for QNodes:
  
  * You must use the ``"torch"`` interface for classical backpropagation, as PyTorch is
    used as the device backend.
  
  * Only exact expectation values, variances, and probabilities are differentiable.
    When instantiating the device with ``shots!=None``, differentiating QNode
    outputs will result in an error.
  
  If you wish to use a different machine-learning interface, or prefer to calculate quantum
  gradients using the ``parameter-shift`` or ``finite-diff`` differentiation methods,
  consider using the ``default.qubit`` device instead.
  
  Args:
      wires (int, Iterable): Number of subsystems represented by the device,
          or iterable that contains unique labels for the subsystems. Default 1 if not specified.
      shots (None, int): How many times the circuit should be evaluated (or sampled) to estimate
          the expectation values. Defaults to ``None`` if not specified, which means
          that the device returns analytical results.
          If ``shots > 0`` is used, the ``diff_method="backprop"``
          QNode differentiation method is not supported and it is recommended to consider
          switching device to ``default.qubit`` and using ``diff_method="parameter-shift"``.
      torch_device='cpu' (str): the device on which the computation will be
      run, e.g., ``'cpu'`` or ``'cuda'``
class_docstr_tok: ["Simulator","plugin","based","on","``","``","default.qubit.legacy","''","``",",","written","using","PyTorch",".","*","*","Short","name",":","*","*","``","default.qubit.torch","``","This","device","provides","a","pure-state","qubit","simulator","written","using","PyTorch",".","As","a","result",",","it","supports","classical","backpropagation","as","a","means","to","compute","the","Jacobian",".","This","can","be","faster","than","the","parameter-shift","rule","for","analytic","quantum","gradients","when","the","number","of","parameters","to","be","optimized","is","large",".","To","use","this","device",",","you","will","need","to","install","PyTorch",":","..","code-block",":",":","console","pip","install","torch",">","=1.8.0","*","*","Example","*","*","The","``","default.qubit.torch","``","is","designed","to","be","used","with","end-to-end","classical","backpropagation","(","``","diff_method=","''","backprop","''","``",")","and","the","PyTorch","interface",".","This","is","the","default","method","of","differentiation","when","creating","a","QNode","with","this","device",".","Using","this","method",",","the","created","QNode","is","a","'white-box","'",",","and","is","tightly","integrated","with","your","PyTorch","computation",":","..","code-block",":",":","python","dev","=","qml.device","(","``","default.qubit.torch","''",",","wires=1",")","@","qml.qnode","(","dev",",","interface=","''","torch","''",",","diff_method=","''","backprop","''",")","def","circuit","(","x",")",":","qml.RX","(","x","[","1","]",",","wires=0",")","qml.Rot","(","x","[","0","]",",","x","[","1","]",",","x","[","2","]",",","wires=0",")","return","qml.expval","(","qml.PauliZ","(","0",")",")",">",">",">","weights","=","torch.tensor","(","[","0.2",",","0.5",",","0.1","]",",","requires_grad=True",")",">",">",">","res","=","circuit","(","weights",")",">",">",">","res.backward","(",")",">",">",">","print","(","weights.grad",")","tensor","(","[","-2.2527e-01",",","-1.0086e+00",",","1.3878e-17","]",")","Autograd","mode","will","also","work","when","using","classical","backpropagation",":",">",">",">","def","cost","(","weights",")",":","...","return","torch.sum","(","circuit","(","weights",")","*","*","3",")","-","1",">",">",">","res","=","circuit","(","weights",")",">",">",">","res.backward","(",")",">",">",">","print","(","weights.grad",")","tensor","(","[","-4.5053e-01",",","-2.0173e+00",",","5.9837e-17","]",")","Executing","the","pipeline","in","PyTorch","will","allow","the","whole","computation","to","be","run","on","the","GPU",",","and","therefore","providing","an","acceleration",".","Your","parameters","need","to","be","instantiated","on","the","same","device","as","the","backend","device",".","..","code-block",":",":","python","dev","=","qml.device","(","``","default.qubit.torch","''",",","wires=1",",","torch_device='cuda","'",")","@","qml.qnode","(","dev",",","interface=","''","torch","''",",","diff_method=","''","backprop","''",")","def","circuit","(","x",")",":","qml.RX","(","x","[","1","]",",","wires=0",")","qml.Rot","(","x","[","0","]",",","x","[","1","]",",","x","[","2","]",",","wires=0",")","return","qml.expval","(","qml.PauliZ","(","0",")",")",">",">",">","weights","=","torch.tensor","(","[","0.2",",","0.5",",","0.1","]",",","requires_grad=True",",","device='cuda","'",")",">",">",">","res","=","circuit","(","weights",")",">",">",">","res.backward","(",")",">",">",">","print","(","weights.grad",")","tensor","(","[","-2.2527e-01",",","-1.0086e+00",",","2.9919e-17","]",",","device='cuda:0","'",")","There","are","a","couple","of","things","to","keep","in","mind","when","using","the","``","``","backprop","''","``","differentiation","method","for","QNodes",":","*","You","must","use","the","``","``","torch","''","``","interface","for","classical","backpropagation",",","as","PyTorch","is","used","as","the","device","backend",".","*","Only","exact","expectation","values",",","variances",",","and","probabilities","are","differentiable",".","When","instantiating","the","device","with","``","shots","!","=None","``",",","differentiating","QNode","outputs","will","result","in","an","error",".","If","you","wish","to","use","a","different","machine-learning","interface",",","or","prefer","to","calculate","quantum","gradients","using","the","``","parameter-shift","``","or","``","finite-diff","``","differentiation","methods",",","consider","using","the","``","default.qubit","``","device","instead",".","Args",":","wires","(","int",",","Iterable",")",":","Number","of","subsystems","represented","by","the","device",",","or","iterable","that","contains","unique","labels","for","the","subsystems",".","Default","1","if","not","specified",".","shots","(","None",",","int",")",":","How","many","times","the","circuit","should","be","evaluated","(","or","sampled",")","to","estimate","the","expectation","values",".","Defaults","to","``","None","``","if","not","specified",",","which","means","that","the","device","returns","analytical","results",".","If","``","shots",">","0","``","is","used",",","the","``","diff_method=","''","backprop","''","``","QNode","differentiation","method","is","not","supported","and","it","is","recommended","to","consider","switching","device","to","``","default.qubit","``","and","using","``","diff_method=","''","parameter-shift","''","``",".","torch_device='cpu","'","(","str",")",":","the","device","on","which","the","computation","will","be","run",",","e.g.",",","``","'cpu","'","``","or","``","'cuda","'","``"]
docstr: An auxiliary function to determine the Torch device specified for
  the gate parameters of the input operations.
  
  Returns the first CUDA Torch device found (if any) using a string
  format. Does not handle tensors put on multiple CUDA Torch devices.
  Such a case raises an error with Torch.
  
  If CUDA is not used with any of the parameters, then specifies the CPU
  if the parameters are on the CPU or None if there were no parametric
  operations.
  
  Args:
      ops (list[Operator]): list of operations to check
  
  Returns:
      str or None: The string of the Torch device determined or None if
      there is no data for any operations.
docstr_tok: ["An","auxiliary","function","to","determine","the","Torch","device","specified","for","the","gate","parameters","of","the","input","operations",".","Returns","the","first","CUDA","Torch","device","found","(","if","any",")","using","a","string","format",".","Does","not","handle","tensors","put","on","multiple","CUDA","Torch","devices",".","Such","a","case","raises","an","error","with","Torch",".","If","CUDA","is","not","used","with","any","of","the","parameters",",","then","specifies","the","CPU","if","the","parameters","are","on","the","CPU","or","None","if","there","were","no","parametric","operations",".","Args",":","ops","(","list","[","Operator","]",")",":","list","of","operations","to","check","Returns",":","str","or","None",":","The","string","of","the","Torch","device","determined","or","None","if","there","is","no","data","for","any","operations","."]
code: def _get_parameter_torch_device(ops):
      """An auxiliary function to determine the Torch device specified for
      the gate parameters of the input operations.
  
      Returns the first CUDA Torch device found (if any) using a string
      format. Does not handle tensors put on multiple CUDA Torch devices.
      Such a case raises an error with Torch.
  
      If CUDA is not used with any of the parameters, then specifies the CPU
      if the parameters are on the CPU or None if there were no parametric
      operations.
  
      Args:
          ops (list[Operator]): list of operations to check
  
      Returns:
          str or None: The string of the Torch device determined or None if
          there is no data for any operations.
      """
      par_torch_device = None
      for op in ops:
          for data in op.data:
              # Using hasattr in case we don't have a Torch tensor as input
              if hasattr(data, "is_cuda"):
                  if data.is_cuda:  # pragma: no cover
                      return ":".join(
                          [data.device.type, str(data.device.index)]
                      )
  
                  par_torch_device = "cpu"
  
      return par_torch_device
  
file_path: pennylane/pennylane/devices/default_qubit_torch.py
imports: import warnings
  import inspect
  import logging
  import semantic_version
  import numpy
  from pennylane.ops.qubit.attributes import diagonal_in_z_basis
  from .None import DefaultQubitLegacy
label_desc: Use image node_id 2 for calling the DefaultQubitTorch obj's underlying member method code with example usage: obj._get_parameter_torch_device(ops) and returns: par_torch_device, str