o
    h>                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d dlZddlmZmZ dd	lmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& d]ddZ'e'dd
dZ(dd Z)dd Z*dd Z+dd Z,dd Z-dd Z.dd Z/dd Z0dd  Z1d!d" Z2d#d$ Z3d%d& Z4d'd( Z5d)d* Z6d+d, Z7d-d. Z8d/d0 Z9d^d1d2Z:d3d4 Z;d5d6 Z<d7d8 Z=d9d: Z>d;d< Z?d=d> Z@eAe$ e goe  ZBd?d@ ZCG dAdB dBejDZEG dCdD dDejDZFG dEdF dFejDZGdGdH ZHG dIdJ dJZIdKdL ZJd_dMeIfdNdOZKd`dMeIfdRdSZLG dTdU dUeMZNdadVeeO fdWdXZPedbdYeMdZeOdMeQfd[d\ZRdS )c    N)contextmanager)partial)Path)ListUnion)mock   )AcceleratorStatePartialState)gatheris_bnb_availableis_clearml_availableis_comet_ml_availableis_datasets_availableis_deepspeed_availableis_dvclive_availableis_mps_availableis_pandas_availableis_tensorboard_availableis_timm_availableis_torch_versionis_tpu_availableis_transformers_availableis_wandb_availableis_xpu_availablestr_to_boolFc                 C   sV   zt j|  }W n ty   |}Y |S w zt|}W |S  ty*   td|  dw )NzIf set, z must be yes or no.)osenvironKeyErrorr   
ValueError)keydefaultvalue_value r$   S/var/www/html/ai/venv/lib/python3.10/site-packages/accelerate/test_utils/testing.pyparse_flag_from_env4   s   
r&   RUN_SLOW)r!   c                 C   s   t d| S )z+Decorator that skips a test unconditionallyzTest was skipped)unittestskip	test_caser$   r$   r%   r)   G   s   r)   c                 C      t td| S )z
    Decorator marking a test as slow. Slow tests are skipped by default. Set the RUN_SLOW environment variable to a
    truthy value to run them.
    ztest is slow)r(   
skipUnless_run_slow_testsr*   r$   r$   r%   slowL   s   r/   c                 C   s   t tj  d| S )zu
    Decorator marking a test that must be only ran on the CPU. These tests are skipped when a GPU is available.
    ztest requires only a CPUr(   r-   torchcudais_availabler*   r$   r$   r%   require_cpuT   s   r4   c                 C   s   t tj d| S )zo
    Decorator marking a test that requires CUDA. These tests are skipped when there are no GPU available.
    test requires a GPUr0   r*   r$   r$   r%   require_cuda[      r6   c                 C      t t d| S )zn
    Decorator marking a test that requires XPU. These tests are skipped when there are no XPU available.
    test requires a XPU)r(   r-   r   r*   r$   r$   r%   require_xpub      r:   c                 C   r8   )z
    Decorator marking a test that requires MPS backend. These tests are skipped when torch doesn't support `mps`
    backend.
    z0test requires a `mps` backend support in `torch`)r(   r-   r   r*   r$   r$   r%   require_mpsi      r<   c                 C   s   t t ot d| S )zv
    Decorator marking a test that requires transformers and datasets. These tests are skipped when they are not.
    z$test requires the Hugging Face suite)r(   r-   r   r   r*   r$   r$   r%   require_huggingface_suiteq   s
   r>   c                 C   r8   )i
    Decorator marking a test that requires transformers. These tests are skipped when they are not.
    z&test requires the transformers library)r(   r-   r   r*   r$   r$   r%   require_transformersz   r;   r@   c                 C   r8   )r?   ztest requires the timm library)r(   r-   r   r*   r$   r$   r%   require_timm   r;   rA   c                 C   r8   )zi
    Decorator marking a test that requires bitsandbytes. These tests are skipped when they are not.
    z&test requires the bitsandbytes library)r(   r-   r   r*   r$   r$   r%   require_bnb   r;   rB   c                 C   r8   )zp
    Decorator marking a test that requires TPUs. These tests are skipped when there are no TPUs available.
    ztest requires TPU)r(   r-   r   r*   r$   r$   r%   require_tpu   r;   rC   c                 C      t tj dkd| S )z
    Decorator marking a test that requires CUDA on a single GPU. These tests are skipped when there are no GPU
    available or number of GPUs is more than one.
       r5   r(   r-   r1   r2   device_countr*   r$   r$   r%   require_single_gpu      rH   c                 C   rD   )z
    Decorator marking a test that requires CUDA on a single XPU. These tests are skipped when there are no XPU
    available or number of xPUs is more than one.
    rE   r9   r(   r-   r1   xpurG   r*   r$   r$   r%   require_single_xpu   rI   rL   c                 C      t tj dkd| S )z
    Decorator marking a test that requires a multi-GPU setup. These tests are skipped on a machine without multiple
    GPUs.
    rE   ztest requires multiple GPUsrF   r*   r$   r$   r%   require_multi_gpu   rI   rN   c                 C   rM   )z
    Decorator marking a test that requires a multi-XPU setup. These tests are skipped on a machine without multiple
    XPUs.
    rE   ztest requires multiple XPUsrJ   r*   r$   r$   r%   require_multi_xpu   rI   rO   c                 C   r8   )z|
    Decorator marking a test that requires DeepSpeed installed. These tests are skipped when DeepSpeed isn't installed
    ztest requires DeepSpeed)r(   r-   r   r*   r$   r$   r%   require_deepspeed   r;   rP   c                 C   s   t tddd| S )zr
    Decorator marking a test that requires FSDP installed. These tests are skipped when FSDP isn't installed
    >=z1.12.0z%test requires torch version >= 1.12.0)r(   r-   r   r*   r$   r$   r%   require_fsdp   r7   rR   c                 C   s0   | du r
t t|dS ttd|d| | S )z
    Decorator marking that a test requires a particular torch version to be tested. These tests are skipped when an
    installed torch version is less than the required one.
    N)versionrQ   ztest requires torch version >= )r   require_torch_min_versionr(   r-   r   )r+   rS   r$   r$   r%   rT      s   rT   c                 C   r8   )z
    Decorator marking a test that requires tensorboard installed. These tests are skipped when tensorboard isn't
    installed
    ztest requires Tensorboard)r(   r-   r   r*   r$   r$   r%   require_tensorboard   r=   rU   c                 C   r8   )zt
    Decorator marking a test that requires wandb installed. These tests are skipped when wandb isn't installed
    ztest requires wandb)r(   r-   r   r*   r$   r$   r%   require_wandb   r;   rV   c                 C   r8   )zz
    Decorator marking a test that requires comet_ml installed. These tests are skipped when comet_ml isn't installed
    ztest requires comet_ml)r(   r-   r   r*   r$   r$   r%   require_comet_ml   r;   rW   c                 C   r8   )zx
    Decorator marking a test that requires clearml installed. These tests are skipped when clearml isn't installed
    ztest requires clearml)r(   r-   r   r*   r$   r$   r%   require_clearml   r;   rX   c                 C   r8   )zx
    Decorator marking a test that requires dvclive installed. These tests are skipped when dvclive isn't installed
    ztest requires dvclive)r(   r-   r   r*   r$   r$   r%   require_dvclive   r;   rY   c                 C   r8   )zv
    Decorator marking a test that requires pandas installed. These tests are skipped when pandas isn't installed
    ztest requires pandas)r(   r-   r   r*   r$   r$   r%   require_pandas   r;   rZ   c                 C   r,   )z
    Decorator marking that a test requires at least one tracking library installed. These tests are skipped when none
    are installed
    zYtest requires at least one tracker to be available and for `comet_ml` to not be installed)r(   r-   _atleast_one_tracker_availabler*   r$   r$   r%   require_trackers   s   r\   c                   @   s4   e Zd ZdZdZedd Zedd Zdd Zd	S )
TempDirTestCasea  
    A TestCase class that keeps a single `tempfile.TemporaryDirectory` open for the duration of the class, wipes its
    data at the start of a test, and then destroyes it at the end of the TestCase.

    Useful for when a class or API requires a single constant folder throughout it's use, such as Weights and Biases

    The temporary directory location will be stored in `self.tmpdir`
    Tc                 C   s   t  | _dS )zECreates a `tempfile.TemporaryDirectory` and stores it in `cls.tmpdir`N)tempfilemkdtemptmpdirclsr$   r$   r%   
setUpClass  s   zTempDirTestCase.setUpClassc                 C   s"   t j| jrt| j dS dS )z1Remove `cls.tmpdir` after test suite has finishedN)r   pathexistsr`   shutilrmtreera   r$   r$   r%   tearDownClass  s   zTempDirTestCase.tearDownClassc                 C   sH   | j r t| jdD ]}| r|  q| rt| qdS dS )z<Destroy all contents in `self.tmpdir`, but not `self.tmpdir`z**/*N)	clear_on_setupr   r`   globis_fileunlinkis_dirrf   rg   )selfrd   r$   r$   r%   setUp   s   

zTempDirTestCase.setUpN)	__name__
__module____qualname____doc__ri   classmethodrc   rh   ro   r$   r$   r$   r%   r]   	  s    	

r]   c                       s    e Zd ZdZ fddZ  ZS )AccelerateTestCasez
    A TestCase class that will reset the accelerator state at the end of every test. Every test that checks or utilizes
    the `AcceleratorState` class should inherit from this to avoid silent failures due to state being shared between
    tests.
    c                    s   t    t  t  d S N)supertearDownr	   _reset_stater
   )rn   	__class__r$   r%   rx   1  s   
zAccelerateTestCase.tearDown)rp   rq   rr   rs   rx   __classcell__r$   r$   rz   r%   ru   *  s    ru   c                   @   s.   e Zd ZdZdeejeej f fddZdS )MockingTestCasea  
    A TestCase class designed to dynamically add various mockers that should be used in every test, mimicking the
    behavior of a class-wide mock when defining one normally will not do.

    Useful when a mock requires specific information available only initialized after `TestCase.setUpClass`, such as
    setting an environment variable with that information.

    The `add_mocks` function should be ran at the end of a `TestCase`'s `setUp` function, after a call to
    `super().setUp()` such as:
    ```python
    def setUp(self):
        super().setUp()
        mocks = mock.patch.dict(os.environ, {"SOME_ENV_VAR", "SOME_VALUE"})
        self.add_mocks(mocks)
    ```
    mocksc                 C   s>   t |ttfr	|n|g| _| jD ]}|  | |j qdS )aQ  
        Add custom mocks for tests that should be repeated on each test. Should be called during
        `MockingTestCase.setUp`, after `super().setUp()`.

        Args:
            mocks (`mock.Mock` or list of `mock.Mock`):
                Mocks that should be added to the `TestCase` after `TestCase.setUpClass` has been run
        N)
isinstancetuplelistr~   start
addCleanupstop)rn   r~   mr$   r$   r%   	add_mocksJ  s
   	
zMockingTestCase.add_mocksN)	rp   rq   rr   rs   r   r   Mockr   r   r$   r$   r$   r%   r}   8  s    "r}   c                 C   s`   t  }| d   |j} t|  }| d  } t|jd D ]}t	|| | s- dS q dS )Nr   FT)
r	   clonetodevicer   cpurangeshaper1   equal)tensorstatetensorsir$   r$   r%   are_the_same_tensorsY  s   r   c                   @   s   e Zd Zdd ZdS )
_RunOutputc                 C   s   || _ || _|| _d S rv   )
returncodestdoutstderr)rn   r   r   r   r$   r$   r%   __init__e  s   
z_RunOutput.__init__N)rp   rq   rr   r   r$   r$   r$   r%   r   d  s    r   c                    s&   	 |   I d H }|r|| nd S qrv   )readline)streamcallbackliner$   r$   r%   _read_streamk  s   
r   returnc              	      s   |rt dd|  tj| d g| dd  R |tjjtjj|dI d H }g g  dfdd	tjtt|j	fd	d
tt|j
 fdd
g|dI d H  t| I d H  S )Nz

Running:  r   rE   )stdinr   r   env c                    s2   |  d } ||   st|| |d d S d S )Nutf-8)file)decoderstripappendprint)r   sinkpipelabel)quietr$   r%   tee  s
   
z_stream_subprocess.<locals>.teec                       |  t jddS )Nzstdout:r   )sysr   l)outr   r$   r%   <lambda>      z$_stream_subprocess.<locals>.<lambda>c                    r   )Nzstderr:r   )r   r   r   )errr   r$   r%   r     r   )timeout)r   )r   joinasynciocreate_subprocess_exec
subprocessPIPEwaitcreate_taskr   r   r   r   )cmdr   r   r   r   echopr$   )r   r   r   r   r%   _stream_subprocesst  s.   
r      Tc           
   
   C   sb   t  }|t| |||||d}d| }|jdkr/d|j}	td| d|j d|	 |S )N)r   r   r   r   r   r   r   
'z' failed with returncode z,

The combined stderr from workers follows:
)r   get_event_looprun_until_completer   r   r   r   RuntimeError)
r   r   r   r   r   r   loopresultcmd_strr   r$   r$   r%   execute_subprocess_async  s   

r   c                   @   s   e Zd ZdS )SubprocessCallExceptionN)rp   rq   rr   r$   r$   r$   r%   r     s    r   commandc              
   C   s   |du r	t j }ztj| tj|d}|r"t|dr|d}|W S W dS  tjyB } zt	dd
|  d|j  |d}~ww )z
    Runs `command` with `subprocess.check_output` and will potentially return the `stdout`. Will also properly capture
    if an error occured while running `command`
    N)r   r   r   r   z	Command `r   z$` failed with the following error:

)r   r   copyr   check_outputSTDOUThasattrr   CalledProcessErrorr   r   output)r   return_stdoutr   r   er$   r$   r%   run_command  s"   


r   exception_classmsgc              
   c   s    d}zdV  d}W n: t yD } z.t|| s#J d|  dt| |dur:|t|v s:J d| dt| dW Y d}~nd}~ww |rOtd|  d	dS )
z
    Context manager to assert that the right `Exception` class was raised.

    If `msg` is provided, will check that the message is contained in the raised exception.
    FNTzExpected exception of type z	 but got zExpected message 'z' to be in exception but got 'r   z but ran without issue.)	Exceptionr   typestrAssertionError)r   r   was_ranr   r$   r$   r%   assert_exception  s   "&r   )F)NN)NNNFF)NNr   FT)FNrv   )Sr   r   rf   r   r   r^   r(   
contextlibr   	functoolsr   pathlibr   typingr   r   r   r1   r   r	   r
   utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r&   r.   r)   r/   r4   r6   r:   r<   r>   r@   rA   rB   rC   rH   rL   rN   rO   rP   rR   rT   rU   rV   rW   rX   rY   rZ   anyr[   r\   TestCaser]   ru   r}   r   r   r   r   r   r   r   r   r   boolr   r$   r$   r$   r%   <module>   sp   L
	

!!	)