o
    h                     @   sf   d Z ddlZddlZddlZddlZddlmZmZ dd Zde	de
fd	d
ZddedefddZdS )z
A collection of utilities for ensuring that training can always occur. Heavily influenced by the
[toma](https://github.com/BlackHC/toma) library.
    N   )is_npu_availableis_xpu_availablec                  G   sj   t | ts	t| } tt| D ]}d| |< qt  t r$tj	  | S t
 r.tj	  | S tj	  | S )aN  
    Releases memory from `objects` by setting them to `None` and calls `gc.collect()` and `torch.cuda.empty_cache()`.
    Returned objects should be reassigned to the same variables.

    Args:
        objects (`Iterable`):
            An iterable of objects
    Returns:
        A list of `None` objects to replace `objects`

    Example:

        ```python
        >>> import torch
        >>> from accelerate.utils import release_memory

        >>> a = torch.ones(1000, 1000).cuda()
        >>> b = torch.ones(1000, 1000).cuda()
        >>> a, b = release_memory(a, b)
        ```
    N)
isinstancelistrangelengccollectr   torchxpuempty_cacher   npucuda)objectsi r   M/var/www/html/ai/venv/lib/python3.10/site-packages/accelerate/utils/memory.pyrelease_memory   s   




r   	exceptionreturnc                    s:   g d}t  trt jdkrt fdd|D S dS )z
    Checks if `exception` relates to CUDA out-of-memory, CUDNN not supported, or CPU out-of-memory

    Args:
        exception (`Exception`):
            An exception
    )zCUDA out of memory.z(cuDNN error: CUDNN_STATUS_NOT_SUPPORTED.z*DefaultCPUAllocator: can't allocate memoryr   c                 3   s    | ]
}| j d  v V  qdS )r   N)args).0errr   r   r   	<genexpr>O   s    z+should_reduce_batch_size.<locals>.<genexpr>F)r   RuntimeErrorr   r   any)r   _statementsr   r   r   should_reduce_batch_sizeA   s   r      functionstarting_batch_sizec                    s,   du rt jt|dS |  fdd}|S )a  
    A basic decorator that will try to execute `function`. If it fails from exceptions related to out-of-memory or
    CUDNN, the batch size is cut in half and passed to `function`

    `function` must take in a `batch_size` parameter as its first argument.

    Args:
        function (`callable`, *optional*):
            A function to wrap
        starting_batch_size (`int`, *optional*):
            The batch size to try and fit into memory

    Example:

    ```python
    >>> from accelerate.utils import find_executable_batch_size


    >>> @find_executable_batch_size(starting_batch_size=128)
    ... def train(batch_size, model, optimizer):
    ...     ...


    >>> train(model, optimizer)
    ```
    N)r"   c               
      sD  t   t rtj  nt rtj  ntj  t	t
j }t|t| d k rTddd t|dd  | dd  D }tdj dj d| d	  d
kr]tdz g| R i |W S  ty } z+t|rt   t rtj  nt rtj  ntj   d  n W Y d }~nd }~ww qU)Nr   z, c                 S   s   g | ]\}}| d | qS )=r   )r   argvaluer   r   r   
<listcomp>   s    zAfind_executable_batch_size.<locals>.decorator.<locals>.<listcomp>zBatch size was passed into `zS` as the first argument when called.Remove this as the decorator already does so: `(z)`Tr   z-No executable batch size found, reached zero.   )r	   r
   r   r   r   r   r   r   r   r   inspect	signature
parameterskeysr   joinzip	TypeError__name__r   	Exceptionr   )r   kwargsparamsarg_stre
batch_sizer!   r   r   	decorators   sF   
*


z-find_executable_batch_size.<locals>.decorator)	functoolspartialfind_executable_batch_size)r!   r"   r8   r   r6   r   r;   S   s
   #r;   )Nr    )__doc__r9   r	   r)   r   importsr   r   r   r1   boolr   callableintr;   r   r   r   r   <module>   s   $