
    JTh-                        S SK r S SKrS SKJr  S SKJr  S SKJrJrJ	r	J
r
Jr  S SKrS SKJrJrJrJr  S SKJr  S SKJr  S SKJr  S S	KJrJr  S
S/rS\\\\R:                  4      SS4S jr\
" S\S9r " S S
\\\   5      r     SS\S\S\	\\\\R:                  4         S\	\\\R:                  4      S\S\	\   S\RB                  4S jjr"g)    N)Sequence)chain)AnyGenericOptionalTypeVarUnion)_get_all_device_indices_get_available_device_type_get_device_index_get_devices_properties)Module)parallel_apply)	replicate)gatherscatter_kwargsDataParalleldata_parallel
device_idsreturnc                    ^ ^^ SmT  Vs/ s H  n[        US5      PM     snm [        T 5      mUU U4S jnU" S 5      (       a  g U" S 5      (       a  g g s  snf )Na  
    There is an imbalance between your GPUs. You may want to exclude GPU {} which
    has less than 75% of the memory or cores of GPU {}. You can do so by setting
    the device_ids argument to DataParallel, or by setting the CUDA_VISIBLE_DEVICES
    environment variable.Tc                 L  > T Vs/ s H
  o" U5      PM     nn[        [        U5      [        R                  " S5      S9u  p4[	        [        U5      [        R                  " S5      S9u  pVXF-  S:  a-  [
        R                  " T	R                  TU   TU   5      5        ggs  snf )N   )keyg      ?TF)min	enumerateoperator
itemgettermaxwarningswarnformat)
get_proppropsvaluesmin_posmin_valmax_posmax_val	dev_propsr   imbalance_warns
          W/var/www/auris/envauris/lib/python3.13/site-packages/torch/nn/parallel/data_parallel.pywarn_imbalance&_check_balance.<locals>.warn_imbalance!   s    /89ye(5/y9y0h6I6I!6LMy0h6I6I!6LMt#MM%%j&9:g;NO  :s   B!c                     U R                   $ N)total_memoryr$   s    r,   <lambda> _check_balance.<locals>.<lambda>,   s
    E$6$6    c                     U R                   $ r0   )multi_processor_countr2   s    r,   r3   r4   .   s
    E$?$?r5   )r   r   )r   xr-   r*   r+   s   `  @@r,   _check_balancer9      sd    N
 7AAj#At,jAJ'
3I	 677?@@ A! Bs   AT)boundc                     ^  \ rS rSrSr   SS\S\\\\	\
R                  4         S\\\	\
R                  4      S\	SS4
U 4S	 jjjrS
\S\S\4S jrS\S\\\	\
R                  4      S\\   4S jrS
\\S4   S\\\\4      S\\\	\
R                  4      S\4S jrS\\   S
\\   S\S\\   4S jrS\S\\	\
R                  4   S\4S jrSrU =r$ )r   5   a  Implements data parallelism at the module level.

This container parallelizes the application of the given :attr:`module` by
splitting the input across the specified devices by chunking in the batch
dimension (other objects will be copied once per device). In the forward
pass, the module is replicated on each device, and each replica handles a
portion of the input. During the backwards pass, gradients from each replica
are summed into the original module.

The batch size should be larger than the number of GPUs used.

.. warning::
    It is recommended to use :class:`~torch.nn.parallel.DistributedDataParallel`,
    instead of this class, to do multi-GPU training, even if there is only a single
    node. See: :ref:`cuda-nn-ddp-instead` and :ref:`ddp`.

Arbitrary positional and keyword inputs are allowed to be passed into
DataParallel but some types are specially handled. tensors will be
**scattered** on dim specified (default 0). tuple, list and dict types will
be shallow copied. The other types will be shared among different threads
and can be corrupted if written to in the model's forward pass.

The parallelized :attr:`module` must have its parameters and buffers on
``device_ids[0]`` before running this :class:`~torch.nn.DataParallel`
module.

.. warning::
    In each forward, :attr:`module` is **replicated** on each device, so any
    updates to the running module in ``forward`` will be lost. For example,
    if :attr:`module` has a counter attribute that is incremented in each
    ``forward``, it will always stay at the initial value because the update
    is done on the replicas which are destroyed after ``forward``. However,
    :class:`~torch.nn.DataParallel` guarantees that the replica on
    ``device[0]`` will have its parameters and buffers sharing storage with
    the base parallelized :attr:`module`. So **in-place** updates to the
    parameters or buffers on ``device[0]`` will be recorded. E.g.,
    :class:`~torch.nn.BatchNorm2d` and :func:`~torch.nn.utils.spectral_norm`
    rely on this behavior to update the buffers.

.. warning::
    Forward and backward hooks defined on :attr:`module` and its submodules
    will be invoked ``len(device_ids)`` times, each with inputs located on
    a particular device. Particularly, the hooks are only guaranteed to be
    executed in correct order with respect to operations on corresponding
    devices. For example, it is not guaranteed that hooks set via
    :meth:`~torch.nn.Module.register_forward_pre_hook` be executed before
    `all` ``len(device_ids)`` :meth:`~torch.nn.Module.forward` calls, but
    that each such hook be executed before the corresponding
    :meth:`~torch.nn.Module.forward` call of that device.

.. warning::
    When :attr:`module` returns a scalar (i.e., 0-dimensional tensor) in
    :func:`forward`, this wrapper will return a vector of length equal to
    number of devices used in data parallelism, containing the result from
    each device.

.. note::
    There is a subtlety in using the
    ``pack sequence -> recurrent network -> unpack sequence`` pattern in a
    :class:`~torch.nn.Module` wrapped in :class:`~torch.nn.DataParallel`.
    See :ref:`pack-rnn-unpack-with-data-parallelism` section in FAQ for
    details.


Args:
    module (Module): module to be parallelized
    device_ids (list of int or torch.device): CUDA devices (default: all devices)
    output_device (int or torch.device): device location of output (default: device_ids[0])

Attributes:
    module (Module): the module to be parallelized

Example::

    >>> # xdoctest: +SKIP
    >>> net = torch.nn.DataParallel(model, device_ids=[0, 1, 2])
    >>> output = net(input_var)  # input_var can be on any device, including CPU
Nmoduler   output_devicedimr   c                 t  > [         TU ]  5         [        R                  R	                  S5        [        5       nUb  US:X  a  Xl        / U l        g Uc
  [        5       nUc  [        S5      eUc  US   nX@l
        Xl        U Vs/ s H  n[        US5      PM     snU l        [        US5      U l        [        R                  " XPR                  S   5      U l        US:X  a  [        U R                  5        [!        U R                  5      S:X  a&  U R                  R#                  U R                  5        g g s  snf )Nztorch.nn.parallel.DataParallelmpsno available devices were foundr   Tcudar   )super__init__torch_C_log_api_usage_oncer   r>   r   r
   RuntimeErrorr@   r   r?   devicesrc_device_objr9   lento)selfr>   r   r?   r@   device_typer8   	__class__s          r,   rF   DataParallel.__init__   s    	$$%EF02+"6 K DO02J@AA &qMM?IJz!,Q5zJ.}dC#ll;8JK& 4??+t1$KKNN4../ % Ks   D5inputskwargsc           	      z   [         R                  R                  R                  S5         U R                  (       d  U R
                  " U0 UD6sS S S 5        $ [        U R
                  R                  5       U R
                  R                  5       5       HB  nUR                  U R                  :w  d  M  [        SU R                   SUR                   35      e   U R                  XU R                  5      u  pU(       d  U(       d  Sn0 4n[        U R                  5      S:X  a!  U R
                  " US   0 US   D6sS S S 5        $ U R                  U R
                  U R                  S [        U5       5      nU R                  XQU5      nU R!                  X`R"                  5      sS S S 5        $ ! , (       d  f       g = f)NzDataParallel.forward6module must have its parameters and buffers on device 2 (device_ids[0]) but found one of them on device:  r   r   )rG   autogradprofilerrecord_functionr   r>   r   
parametersbuffersrK   rL   rJ   scatterrM   r   r   r   r?   )rO   rS   rT   tmodule_kwargsreplicasoutputss          r,   forwardDataParallel.forward   sc   ^^$$445KL??{{F5f5 ML 4;;113T[[5H5H5JK88t222&%%)%8%8$9 :++,88*6  L %)LL$Q!F -!#4??#q({{F1IBq1AB) ML* ~~dkk4??=S[3QRH))(MJG;;w(:(:;/ MLLs    #F,AF,2BF,AF,,
F:c                 J    [        X[        R                  " 5       (       + 5      $ r0   )r   rG   is_grad_enabled)rO   r>   r   s      r,   r   DataParallel.replicate   s     1F1F1H-HIIr5   .c                 *    [        XX0R                  S9$ N)r@   )r   r@   )rO   rS   rT   r   s       r,   r_   DataParallel.scatter   s     fjhhGGr5   rb   c           
      F    [        XX0R                  S [        U5       5      $ r0   )r   r   rM   )rO   rb   rS   rT   s       r,   r   DataParallel.parallel_apply   s%     foooH&F
 	
r5   rc   c                 *    [        XU R                  S9$ rj   )r   r@   )rO   rc   r?   s      r,   r   DataParallel.gather   s    g$((;;r5   )r   r@   r>   r?   rL   )NNr   )__name__
__module____qualname____firstlineno____doc__r:   r   r   r	   intrG   rK   rF   r   rd   listr   tupledictstrr_   r   r   __static_attributes____classcell__)rQ   s   @r,   r   r   5   s   Mh DH<@"0"0 XeC,=&>?@"0  c5<<&7 89	"0
 "0 
"0 "0H<s <c <c <4JJ%-eC4E.F%GJ	aJ
Hc3hH c3h(H U3#456	H
 
H
 
-5c]
DG
	c
<c <%U\\8I2J <s < <r5   r>   rS   r?   r@   ra   c                    [        U[        5      (       d  Ub  U4OSn[        5       nUc  [        S5      eUc
  [	        5       nUc  [        S5      eUc  US   nU Vs/ s H  n[        US5      PM     nn[        US5      n[        R                  " XbS   5      n[        U R                  5       U R                  5       5       H.  n	U	R                  U:w  d  M  [        SU SU	R                   35      e   [        XX$5      u  pU(       d  U(       d  S	n0 4nUc   e[        U5      S
:X  a  U " US   0 US   D6$ US[        U5       n
[        X
5      n[        XXZ5      n[        XU5      $ s  snf )a$  Evaluate module(input) in parallel across the GPUs given in device_ids.

This is the functional version of the DataParallel module.

Args:
    module (Module): the module to evaluate in parallel
    inputs (Tensor): inputs to the module
    device_ids (list of int or torch.device): GPU ids on which to replicate module
    output_device (list of int or torch.device): GPU location of the output  Use -1 to indicate the CPU.
        (default: device_ids[0])
Returns:
    a Tensor containing the result of module(input) located on
    output_device
NrY   z#device type could not be determinedrC   r   TrV   rW   rX   r   )
isinstancerw   r   rJ   r
   r   rG   rK   r   r]   r^   r   rM   r   r   r   )r>   rS   r   r?   r@   ra   rP   r8   rL   r`   used_device_idsrb   rc   s                r,   r   r      s   , fe$$$0&b,.K@AA,.
<=="16@Aj#At,jJA%mT:M\\+!}=N6$$&(8988~%+, -##$88*.  : +6*RF -$$$
:!vay5M!$455 3v;/O1HX}NG'#..5 Bs   E()NNr   N)#r   r    collections.abcr   	itertoolsr   typingr   r   r   r   r	   rG   torch._utilsr
   r   r   r   torch.nn.modulesr    torch.nn.parallel.parallel_applyr   torch.nn.parallel.replicater    torch.nn.parallel.scatter_gatherr   r   __all__ru   rK   r9   r:   r   Tensorr   rY   r5   r,   <module>r      s     $  9 9   $ ; 1 C ?
+xc5<<.?(@A d 4 Cve<671: e<V @D8<#'A/A/A/ %U\\(9":;<A/ E#u||"345	A/
 
A/ C=A/ \\A/r5   