shrinath-suresh/blogs-docs-splitted huggingface dataset:
operation, "self" is updated as:
  self[index[i][j][k]][j][k] *= src[i][j][k]  # if dim == 0
  self[i][index[i][j][k]][k] *= src[i][j][k]  # if dim == 1
  self[i][j][index[i][j][k]] *= src[i][j][k]  # if dim == 2

Reducing with the addition operation is the same as using
   "scatter_add_()".
Parameters:
      * dim (int) -- the axis along which to index
  * **index** (*LongTensor*) -- the indices of elements to
    scatter, can be either empty or of the same dimensionality as
    "src". When empty, the operation returns "self" unchanged.

  * **src** (*Tensor** or **float*) -- the source element(s) to
    scatter.

  * **reduce** (*str**, **optional*) -- reduction operation to
    apply, can be either "'add'" or "'multiply'".

Example:
  >>> src = torch.arange(1, 11).reshape((2, 5))
  >>> src
  tensor([[ 1,  2,  3,  4,  5],
          [ 6,  7,  8,  9, 10]])
  >>> index = torch.tensor([[0, 1, 2, 0]])
index = torch.tensor([[0, 1, 2, 0]])
      >>> torch.zeros(3, 5, dtype=src.dtype).scatter_(0, index, src)
      tensor([[1, 0, 0, 4, 0],
              [0, 2, 0, 0, 0],
              [0, 0, 3, 0, 0]])
      >>> index = torch.tensor([[0, 1, 2], [0, 1, 4]])
      >>> torch.zeros(3, 5, dtype=src.dtype).scatter_(1, index, src)
      tensor([[1, 2, 3, 0, 0],
              [6, 7, 0, 0, 8],
              [0, 0, 0, 0, 0]])



  >>> torch.full((2, 4), 2.).scatter_(1, torch.tensor([[2], [3]]),
  ...            1.23, reduce='multiply')
  tensor([[2.0000, 2.0000, 2.4600, 2.0000],
          [2.0000, 2.0000, 2.0000, 2.4600]])
  >>> torch.full((2, 4), 2.).scatter_(1, torch.tensor([[2], [3]]),
  ...            1.23, reduce='add')
  tensor([[2.0000, 2.0000, 3.2300, 2.0000],
          [2.0000, 2.0000, 2.0000, 3.2300]])
torch.ceil
torch.ceil(input, *, out=None) -> Tensor
Returns a new tensor with the ceil of the elements of "input", the
   smallest integer greater than or equal to each element.
For integer inputs, follows the array-api convention of returning a
   copy of the input tensor.
  \text{out}_{i} = \left\lceil \text{input}_{i} \right\rceil

Parameters:
      input (Tensor) -- the input tensor.
Keyword Arguments:
      out (Tensor, optional) -- the output tensor.
Example:
  >>> a = torch.randn(4)
  >>> a
  tensor([-0.6341, -1.4208, -1.0900,  0.5826])
  >>> torch.ceil(a)
  tensor([-0., -1., -1.,  1.])
torch.real
torch.real(input) -> Tensor
Returns a new tensor containing real values of the "self" tensor.
   The returned tensor and "self" share the same underlying storage.
Parameters:
      input (Tensor) -- the input tensor.
Example:
  >>> x=torch.randn(4, dtype=torch.cfloat)
  >>> x
  tensor([(0.3100+0.3553j), (-0.5445-0.7896j), (-1.6492-0.0633j), (-0.0638-0.8119j)])
  >>> x.real
  tensor([ 0.3100, -0.5445, -1.6492, -0.0638])
torch.jit.isinstance
torch.jit.isinstance(obj, target_type)
This function provides for container type refinement in
   TorchScript. It can refine parameterized containers of the List,
   Dict, Tuple, and Optional types. E.g. "List[str]", "Dict[str,
   List[torch.Tensor]]", "Optional[Tuple[int,str,int]]". It can also
   refine basic types such as bools and ints that are available in
   TorchScript.
Parameters:
      * obj -- object to refine the type of
  * **target_type** -- type to try to refine obj to

Returns:
      True if obj was successfully refined to the type of target_type,
         False otherwise with no new type refinement
Return type:
      "bool"
Example (using "torch.jit.isinstance" for type refinement): ..
   testcode:
  import torch
  from typing import Any, Dict, List

  class MyModule(torch.nn.Module):
      def __init__(self):
          super(MyModule, self).__init__()
super(MyModule, self).init()
      def forward(self, input: Any): # note the Any type
          if torch.jit.isinstance(input, List[torch.Tensor]):
              for t in input:
                  y = t.clamp(0, 0.5)
          elif torch.jit.isinstance(input, Dict[str, str]):
              for val in input.values():
                  print(val)

  m = torch.jit.script(MyModule())
  x = [torch.rand(3,3), torch.rand(4,3)]
  m(x)
  y = {"key1":"val1","key2":"val2"}
  m(y)
torch.Tensor.index_fill_
Tensor.index_fill_(dim, index, value) -> Tensor
Fills the elements of the "self" tensor with value "value" by
   selecting the indices in the order given in "index".
Parameters:
      * dim (int) -- dimension along which to index
  * **index** (*LongTensor*) -- indices of "self" tensor to fill
    in

  * **value** (*float*) -- the value to fill with

Example::
      >>> x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float)
      >>> index = torch.tensor([0, 2])
      >>> x.index_fill_(1, index, -1)
      tensor([[-1.,  2., -1.],
              [-1.,  5., -1.],
              [-1.,  8., -1.]])
LPPool1d
class torch.nn.LPPool1d(norm_type, kernel_size, stride=None, ceil_mode=False)
Applies a 1D power-average pooling over an input signal composed of
   several input planes.
On each window, the function computed is:
  f(X) = \sqrt[p]{\sum_{x \in X} x^{p}}



At p = \infty, one gets Max Pooling


At p = 1, one gets Sum Pooling (which is proportional to Average
     Pooling)


Note:
 If the sum to the power of *p* is zero, the gradient of this
 function is not defined. This implementation will set the
 gradient to zero in this case.

Parameters:
      * kernel_size (Union[int, Tuple[int]]) --
        a single int, the size of the window
  * **stride** (*Union**[**int**, **Tuple**[**int**]**]*) -- a
    single int, the stride of the window. Default value is
    "kernel_size"

  * **ceil_mode** (*bool*) -- when True, will use *ceil* instead
    of *floor* to compute the output shape

Shape:
Shape:
      * Input: (N, C, L_{in}) or (C, L_{in}).
  * Output: (N, C, L_{out}) or (C, L_{out}), where

       L_{out} = \left\lfloor\frac{L_{in} -
       \text{kernel\_size}}{\text{stride}} + 1\right\rfloor

Examples::
      >>> # power-2 pool of window of length 3, with stride 2.
      >>> m = nn.LPPool1d(2, 3, stride=2)
      >>> input = torch.randn(20, 16, 50)
      >>> output = m(input)
Embedding
class torch.ao.nn.quantized.Embedding(num_embeddings, embedding_dim, padding_idx=None, max_norm=None, norm_type=2.0, scale_grad_by_freq=False, sparse=False, _weight=None, dtype=torch.quint8)
A quantized Embedding module with quantized packed weights as
   inputs. We adopt the same interface as torch.nn.Embedding, please
   see https://pytorch.org/docs/stable/nn.html#torch.nn.Embedding for
   documentation.
Similar to "Embedding", attributes will be randomly initialized at
   module creation time and will be overwritten later
Variables:
      weight (Tensor) -- the non-learnable quantized weights of
      the module of shape (\text{num_embeddings},
      \text{embedding_dim}).
Examples::
      >>> m = nn.quantized.Embedding(num_embeddings=10, embedding_dim=12)
      >>> indices = torch.tensor([9, 6, 5, 7, 8, 8, 9, 2, 8])
      >>> output = m(indices)
      >>> print(output.size())
      torch.Size([9, 12])
classmethod from_float(mod)
AlphaDropout
class torch.nn.AlphaDropout(p=0.5, inplace=False)
Applies Alpha Dropout over the input.
Alpha Dropout is a type of Dropout that maintains the self-
   normalizing property. For an input with zero mean and unit standard
   deviation, the output of Alpha Dropout maintains the original mean
   and standard deviation of the input. Alpha Dropout goes hand-in-
   hand with SELU activation function, which ensures that the outputs
   have zero mean and unit standard deviation.
During training, it randomly masks some of the elements of the
   input tensor with probability p using samples from a bernoulli
   distribution. The elements to masked are randomized on every
   forward call, and scaled and shifted to maintain zero mean and unit
   standard deviation.
During evaluation the module simply computes an identity function.
More details can be found in the paper Self-Normalizing Neural
   Networks .
Parameters:
Networks .
Parameters:
      * p (float) -- probability of an element to be dropped.
        Default: 0.5
  * **inplace** (*bool**, **optional*) -- If set to "True", will
    do this operation in-place

Shape:
      * Input: (*). Input can be of any shape
  * Output: (*). Output is of the same shape as input

Examples:
  >>> m = nn.AlphaDropout(p=0.2)
  >>> input = torch.randn(20, 16)
  >>> output = m(input)
torch.logdet
torch.logdet(input) -> Tensor
Calculates log determinant of a square matrix or batches of square
   matrices.
It returns "-inf" if the input has a determinant of zero, and "NaN"
   if it has a negative determinant.
Note:
 Backward through "logdet()" internally uses SVD results when
 "input" is not invertible. In this case, double backward through
 "logdet()" will be unstable in when "input" doesn't have distinct
 singular values. See "torch.linalg.svd()" for details.

See also:
 "torch.linalg.slogdet()" computes the sign (resp. angle) and
 natural logarithm of the absolute value of the determinant of
 real-valued (resp. complex) square matrices.

Parameters:
      input (Tensor) -- the input tensor of size "(, n, n)"
      where "" is zero or more batch dimensions.
Example:
  >>> A = torch.randn(3, 3)
  >>> torch.det(A)
  tensor(0.2611)
  >>> torch.logdet(A)
  tensor(-1.3430)
  >>> A
tensor(-1.3430)
      >>> A
      tensor([[[ 0.9254, -0.6213],
               [-0.5787,  1.6843]],
          [[ 0.3242, -0.9665],
           [ 0.4539, -0.0887]],

          [[ 1.1336, -0.4025],
           [-0.7089,  0.9032]]])
  >>> A.det()
  tensor([1.1990, 0.4099, 0.7386])
  >>> A.det().log()
  tensor([ 0.1815, -0.8917, -0.3031])
torch.abs
torch.abs(input, *, out=None) -> Tensor
Computes the absolute value of each element in "input".
  \text{out}_{i} = |\text{input}_{i}|

Parameters:
      input (Tensor) -- the input tensor.
Keyword Arguments:
      out (Tensor, optional) -- the output tensor.
Example:
  >>> torch.abs(torch.tensor([-1, -2, 3]))
  tensor([ 1,  2,  3])
torch.positive
torch.positive(input) -> Tensor
Returns "input". Throws a runtime error if "input" is a bool
   tensor.
Parameters:
      input (Tensor) -- the input tensor.
Example:
  >>> t = torch.randn(5)
  >>> t
  tensor([ 0.0090, -0.2262, -0.0682, -0.2866,  0.3940])
  >>> torch.positive(t)
  tensor([ 0.0090, -0.2262, -0.0682, -0.2866,  0.3940])
prepare_fx
class torch.quantization.quantize_fx.prepare_fx(model, qconfig_mapping, example_inputs, prepare_custom_config=None, _equalization_config=None, backend_config=None)
Prepare a model for post training static quantization
Parameters:
      * model (***) -- torch.nn.Module model
  * **qconfig_mapping** (***) -- QConfigMapping object to
    configure how a model is quantized, see "QConfigMapping" for
    more details

  * **example_inputs** (***) -- Example inputs for forward
    function of the model, Tuple of positional args (keyword args
    can be passed as positional args as well)

  * **prepare_custom_config** (***) -- customization configuration
    for quantization tool. See "PrepareCustomConfig" for more
    details

  * **_equalization_config** (***) -- config for specifying how to
    perform equalization on the model

  * **backend_config** (***) -- config that specifies how
operators are quantized in a backend, this includes how the
        operators are observed, supported fusion patterns, how
        quantize/dequantize ops are inserted, supported dtypes etc.
        See "BackendConfig" for more details
Returns:
      A GraphModule with observer (configured by qconfig_mapping),
      ready for calibration
Return type:
      ObservedGraphModule
Example:
  import torch
  from torch.ao.quantization import get_default_qconfig_mapping
  from torch.ao.quantization import prepare_fx

  class Submodule(torch.nn.Module):
      def __init__(self):
          super().__init__()
          self.linear = torch.nn.Linear(5, 5)
      def forward(self, x):
          x = self.linear(x)
          return x

  class M(torch.nn.Module):
      def __init__(self):
          super().__init__()
          self.linear = torch.nn.Linear(5, 5)
          self.sub = Submodule()

      def forward(self, x):
def forward(self, x):
              x = self.linear(x)
              x = self.sub(x) + x
              return x
  # initialize a floating point model
  float_model = M().eval()

  # define calibration function
  def calibrate(model, data_loader):
      model.eval()
      with torch.no_grad():
          for image, target in data_loader:
              model(image)

  # qconfig is the configuration for how we insert observers for a particular
  # operator
  # qconfig = get_default_qconfig("fbgemm")
  # Example of customizing qconfig:
  # qconfig = torch.ao.quantization.QConfig(
  #    activation=MinMaxObserver.with_args(dtype=torch.qint8),
  #    weight=MinMaxObserver.with_args(dtype=torch.qint8))
  # `activation` and `weight` are constructors of observer module

  # qconfig_mapping is a collection of quantization configurations, user can
  # set the qconfig for each operator (torch op calls, functional calls, module calls)
in the model through qconfig_mapping
  # the following call will get the qconfig_mapping that works best for models
  # that target "fbgemm" backend
  qconfig_mapping = get_default_qconfig_mapping("fbgemm")

  # We can customize qconfig_mapping in different ways.
  # e.g. set the global qconfig, which means we will use the same qconfig for
  # all operators in the model, this can be overwritten by other settings
  # qconfig_mapping = QConfigMapping().set_global(qconfig)
  # e.g. quantize the linear submodule with a specific qconfig
  # qconfig_mapping = QConfigMapping().set_module_name("linear", qconfig)
  # e.g. quantize all nn.Linear modules with a specific qconfig
  # qconfig_mapping = QConfigMapping().set_object_type(torch.nn.Linear, qconfig)
  # for a more complete list, please see the docstring for :class:`torch.ao.quantization.QConfigMapping`
  # argument

  # example_inputs is a tuple of inputs, that is used to infer the type of the
outputs in the model
  # currently it's not used, but please make sure model(*example_inputs) runs
  example_inputs = (torch.randn(1, 3, 224, 224),)

  # TODO: add backend_config after we split the backend_config for fbgemm and qnnpack
  # e.g. backend_config = get_default_backend_config("fbgemm")
  # `prepare_fx` inserts observers in the model based on qconfig_mapping and
  # backend_config. If the configuration for an operator in qconfig_mapping
  # is supported in the backend_config (meaning it's supported by the target
  # hardware), we'll insert observer modules according to the qconfig_mapping
  # otherwise the configuration in qconfig_mapping will be ignored
  #
  # Example:
  # in qconfig_mapping, user sets linear module to be quantized with quint8 for
  # activation and qint8 for weight:
  # qconfig = torch.ao.quantization.QConfig(
  #     observer=MinMaxObserver.with_args(dtype=torch.quint8),
weight=MinMaxObserver.with-args(dtype=torch.qint8))
  # Note: current qconfig api does not support setting output observer, but
  # we may extend this to support these more fine grained control in the
  # future
  #
  # qconfig_mapping = QConfigMapping().set_object_type(torch.nn.Linear, qconfig)
  # in backend config, linear module also supports in this configuration:
  # weighted_int8_dtype_config = DTypeConfig(
  #   input_dtype=torch.quint8,
  #   output_dtype=torch.quint8,
  #   weight_dtype=torch.qint8,
  #   bias_type=torch.float)

  # linear_pattern_config = BackendPatternConfig(torch.nn.Linear) \
  #    .set_observation_type(ObservationType.OUTPUT_USE_DIFFERENT_OBSERVER_AS_INPUT) \
  #    .add_dtype_config(weighted_int8_dtype_config) \
  #    ...

  # backend_config = BackendConfig().set_backend_pattern_config(linear_pattern_config)
  # `prepare_fx` will check that the setting requested by suer in qconfig_mapping
ExponentialLR
class torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=- 1, verbose=False)
Decays the learning rate of each parameter group by gamma every
   epoch. When last_epoch=-1, sets initial lr as lr.
Parameters:
      * optimizer (Optimizer) -- Wrapped optimizer.
  * **gamma** (*float*) -- Multiplicative factor of learning rate
    decay.

  * **last_epoch** (*int*) -- The index of last epoch. Default:
    -1.

  * **verbose** (*bool*) -- If "True", prints a message to stdout
    for each update. Default: "False".

get_last_lr()
  Return last computed learning rate by current scheduler.

load_state_dict(state_dict)
  Loads the schedulers state.

  Parameters:
     **state_dict** (*dict*) -- scheduler state. Should be an
     object returned from a call to "state_dict()".

print_lr(is_verbose, group, lr, epoch=None)
  Display the current learning rate.

state_dict()
torch.dsplit
torch.dsplit(input, indices_or_sections) -> List of Tensors
Splits "input", a tensor with three or more dimensions, into
   multiple tensors depthwise according to "indices_or_sections". Each
   split is a view of "input".
This is equivalent to calling torch.tensor_split(input,
   indices_or_sections, dim=2) (the split dimension is 2), except that
   if "indices_or_sections" is an integer it must evenly divide the
   split dimension or a runtime error will be thrown.
This function is based on NumPy's "numpy.dsplit()".
Parameters:
      * input (Tensor) -- tensor to split.
  * **indices_or_sections** (*int** or **list** or **tuple of
    ints*) -- See argument in "torch.tensor_split()".

Example::
      >>> t = torch.arange(16.0).reshape(2, 2, 4)
      >>> t
      tensor([[[ 0.,  1.,  2.,  3.],
               [ 4.,  5.,  6.,  7.]],
              [[ 8.,  9., 10., 11.],
               [12., 13., 14., 15.]]])
      >>> torch.dsplit(t, 2)
torch.dsplit(t, 2)
      (tensor([[[ 0.,  1.],
              [ 4.,  5.]],
             [[ 8.,  9.],
              [12., 13.]]]),
       tensor([[[ 2.,  3.],
                [ 6.,  7.]],
               [[10., 11.],
                [14., 15.]]]))



  >>> torch.dsplit(t, [3, 6])
  (tensor([[[ 0.,  1.,  2.],
            [ 4.,  5.,  6.]],
           [[ 8.,  9., 10.],
            [12., 13., 14.]]]),
   tensor([[[ 3.],
            [ 7.]],
           [[11.],
            [15.]]]),
   tensor([], size=(2, 2, 0)))
torch.linalg.matrix_rank
torch.linalg.matrix_rank(A, *, atol=None, rtol=None, hermitian=False, out=None) -> Tensor
Computes the numerical rank of a matrix.
The matrix rank is computed as the number of singular values (or
   eigenvalues in absolute value when "hermitian"= True) that are
   greater than \max(\text{atol}, \sigma_1 * \text{rtol}) threshold,
   where \sigma_1 is the largest singular value (or eigenvalue).
Supports input of float, double, cfloat and cdouble dtypes. Also
   supports batches of matrices, and if "A" is a batch of matrices
   then the output has the same batch dimensions.
If "hermitian"= True, "A" is assumed to be Hermitian if complex
   or symmetric if real, but this is not checked internally. Instead,
   just the lower triangular part of the matrix is used in the
   computations.
If "rtol" is not specified and "A" is a matrix of dimensions (m,
   n), the relative tolerance is set to be \text{rtol} = \max(m, n)
\varepsilon and \varepsilon is the epsilon value for the dtype of
   "A" (see "finfo"). If "rtol" is not specified and "atol" is
   specified to be larger than zero then "rtol" is set to zero.
If "atol" or "rtol" is a "torch.Tensor", its shape must be
   broadcastable to that of the singular values of "A" as returned by
   "torch.linalg.svdvals()".
Note:
 This function has NumPy compatible variant *linalg.matrix_rank(A,
 tol, hermitian=False)*. However, use of the positional argument
 "tol" is deprecated in favor of "atol" and "rtol".

Note:
 The matrix rank is computed using a singular value decomposition
 "torch.linalg.svdvals()" if "hermitian"*= False* (default) and
 the eigenvalue decomposition "torch.linalg.eigvalsh()" when
 "hermitian"*= True*. When inputs are on a CUDA device, this
 function synchronizes that device with the CPU.

Parameters:
      * A (Tensor) -- tensor of shape (, m, n)* where *** is
        zero or more batch dimensions.
zero or more batch dimensions.
  * **tol** (*float**, **Tensor**, **optional*) -- [NumPy Compat]
    Alias for "atol". Default: *None*.

Keyword Arguments:
      * atol (float, Tensor, optional) -- the absolute
        tolerance value. When None it's considered to be zero.
        Default: None.
  * **rtol** (*float**, **Tensor**, **optional*) -- the relative
    tolerance value. See above for the value it takes when *None*.
    Default: *None*.

  * **hermitian** (*bool*) -- indicates whether "A" is Hermitian
    if complex or symmetric if real. Default: *False*.

  * **out** (*Tensor**, **optional*) -- output tensor. Ignored if
    *None*. Default: *None*.

Examples:
  >>> A = torch.eye(10)
  >>> torch.linalg.matrix_rank(A)
  tensor(10)
  >>> B = torch.eye(10)
  >>> B[0, 0] = 0
  >>> torch.linalg.matrix_rank(B)
  tensor(9)

  >>> A = torch.randn(4, 3, 2)
  >>> torch.linalg.matrix_rank(A)
torch.linalg.matrix_rank(A)
      tensor([2, 2, 2, 2])



  >>> A = torch.randn(2, 4, 2, 3)
  >>> torch.linalg.matrix_rank(A)
  tensor([[2, 2, 2, 2],
          [2, 2, 2, 2]])

  >>> A = torch.randn(2, 4, 3, 3, dtype=torch.complex64)
  >>> torch.linalg.matrix_rank(A)
  tensor([[3, 3, 3, 3],
          [3, 3, 3, 3]])
  >>> torch.linalg.matrix_rank(A, hermitian=True)
  tensor([[3, 3, 3, 3],
          [3, 3, 3, 3]])
  >>> torch.linalg.matrix_rank(A, atol=1.0, rtol=0.0)
  tensor([[3, 2, 2, 2],
          [1, 2, 1, 2]])
  >>> torch.linalg.matrix_rank(A, atol=1.0, rtol=0.0, hermitian=True)
  tensor([[2, 2, 2, 1],
          [1, 2, 2, 2]])
torch.from_numpy
torch.from_numpy(ndarray) -> Tensor
Creates a "Tensor" from a "numpy.ndarray".
The returned tensor and "ndarray" share the same memory.
   Modifications to the tensor will be reflected in the "ndarray" and
   vice versa. The returned tensor is not resizable.
It currently accepts "ndarray" with dtypes of "numpy.float64",
   "numpy.float32", "numpy.float16", "numpy.complex64",
   "numpy.complex128", "numpy.int64", "numpy.int32", "numpy.int16",
   "numpy.int8", "numpy.uint8", and "numpy.bool".
Warning:
 Writing to a tensor created from a read-only NumPy array is not
 supported and will result in undefined behavior.

Example:
  >>> a = numpy.array([1, 2, 3])
  >>> t = torch.from_numpy(a)
  >>> t
  tensor([ 1,  2,  3])
  >>> t[0] = -1
  >>> a
  array([-1,  2,  3])
torch.diag_embed
torch.diag_embed(input, offset=0, dim1=- 2, dim2=- 1) -> Tensor
Creates a tensor whose diagonals of certain 2D planes (specified by
   "dim1" and "dim2") are filled by "input". To facilitate creating
   batched diagonal matrices, the 2D planes formed by the last two
   dimensions of the returned tensor are chosen by default.
The argument "offset" controls which diagonal to consider:


If "offset" = 0, it is the main diagonal.


If "offset" > 0, it is above the main diagonal.


If "offset" < 0, it is below the main diagonal.


The size of the new matrix will be calculated to make the specified
   diagonal of the size of the last input dimension. Note that for
   "offset" other than 0, the order of "dim1" and "dim2" matters.
   Exchanging them is equivalent to changing the sign of "offset".
Applying "torch.diagonal()" to the output of this function with the
   same arguments yields a matrix identical to input. However,
"torch.diagonal()" has different default dimensions, so those need
   to be explicitly specified.
Parameters:
      * input (Tensor) -- the input tensor. Must be at least
        1-dimensional.
  * **offset** (*int**, **optional*) -- which diagonal to
    consider. Default: 0 (main diagonal).

  * **dim1** (*int**, **optional*) -- first dimension with respect
    to which to take diagonal. Default: -2.

  * **dim2** (*int**, **optional*) -- second dimension with
    respect to which to take diagonal. Default: -1.

Example:
  >>> a = torch.randn(2, 3)
  >>> torch.diag_embed(a)
  tensor([[[ 1.5410,  0.0000,  0.0000],
           [ 0.0000, -0.2934,  0.0000],
           [ 0.0000,  0.0000, -2.1788]],

          [[ 0.5684,  0.0000,  0.0000],
           [ 0.0000, -1.0845,  0.0000],
           [ 0.0000,  0.0000, -1.3986]]])

  >>> torch.diag_embed(a, offset=1, dim1=0, dim2=2)
  tensor([[[ 0.0000,  1.5410,  0.0000,  0.0000],