o
    0iu                     @   sr  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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Zddl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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZC d
d ZDeD \ZEZFZGdeHfddZIeIeFddZJdddZKeKdddZLdd ZMdd ZNdd ZOdd ZPdd ZQd d! ZRd"d# ZSd$d% ZTd&d' ZUd(d) ZVd*d+ ZWd,d- ZXd.d/ ZYd0d1 ZZd2d3 Z[d4d5 Z\d6d7 Z]d8d9 Z^d:d; Z_d<d= Z`d>d? Zad@dA ZbdBdC ZcdDdE ZddFdG ZedHdI ZfdJdK ZgdLdM ZhdNdO ZidPdQ ZjdRdS ZkdTdU ZldVdW ZmdXdY ZndZd[ Zod\d] Zpdd^d_Zqd`da Zrdbdc Zsddde Ztdfdg Zudhdi Zvdjdk Zwdldm Zxdndo Zydpdq Zzdrds Z{dtdu Z|dvdw Z}dxdy Z~dzd{ Zd|d} Zd~d ZeeA e5 e< e4 goe  Zdd Zdd Zdd ZG dd de	jZG dd de	jZG dd de	jZdd ZG dd dZdd ZddefddZddeHdefddZdd Zdd ZG dd deZddeHe fddZdedefddZeddedee defddZdd ZdS )    N)contextmanager)partial)Path)OptionalUnion)mock   )AcceleratorState)+check_cuda_fp8_capabilitycompare_versionsgatheris_aim_availableis_bnb_availableis_clearml_availableis_comet_ml_availableis_cuda_availableis_datasets_availableis_deepspeed_availableis_dvclive_availableis_fp8_availableis_fp16_availableis_habana_gaudi1is_hpu_availableis_import_timer_availableis_matplotlib_availableis_mlflow_availableis_mlu_availableis_mps_availableis_musa_availableis_npu_availableis_pandas_availableis_pippy_availableis_pytest_availableis_schedulefree_availableis_sdaa_availableis_swanlab_availableis_tensorboard_availableis_timm_availableis_torch_versionis_torch_xla_availableis_torchao_available*is_torchdata_stateful_dataloader_availableis_torchvision_availableis_trackio_availableis_transformer_engine_available%is_transformer_engine_mxfp8_availableis_transformers_availableis_triton_availableis_wandb_availableis_xpu_availablestr_to_boolc                   C   s
  t  rdtj tjjfS t rdtj tjjfS tddr&ddtjjfS t r0dddd fS t	 r=d	tj
 tj
jfS t rJd
tj tjjfS t rWdtj tjjfS t rddtj tjjfS t rqdtj tjjfS t r~dtj tjjfS dddd fS )Nxlacudaz2.0)min_versionmps   c                   S      dS Nr    r<   r<   r<   _/sda-disk/www/egybert/egybert_env/lib/python3.10/site-packages/accelerate/test_utils/testing.py<lambda>[       zget_backend.<locals>.<lambda>mlusdaamusanpuxpuhpucpuc                   S   r:   r;   r<   r<   r<   r<   r=   r>   i   r?   )r)   torchr6   device_countmemory_allocatedr   r   r8   current_allocated_memoryr   r@   r$   rA   r   rB   r   rC   r3   rD   r   rE   r<   r<   r<   r=   get_backendS   s*   
rK   returnc                  K   s\   ddg}|   D ]#\}}t|tr|r|d|  q|dur+|d| d|  q|S )z
    Wraps around `kwargs` to help simplify launching from `subprocess`.

    Example:
    ```python
    # returns ['accelerate', 'launch', '--num_processes=2', '--device_count=2']
    get_launch_command(num_processes=2, device_count=2)
    ```
    
acceleratelaunchz--N=)items
isinstanceboolappend)kwargscommandkvr<   r<   r=   get_launch_commando   s   
rX   g?)num_processesmonitor_intervalFc                 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KeyErrorr4   
ValueError)keydefaultvalue_valuer<   r<   r=   parse_flag_from_env   s   
rc   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=   rf      s   rf   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)re   
skipUnless_run_slow_testsrg   r<   r<   r=   slow   s   rl   c                 C   s   t tdkd| S )zu
    Decorator marking a test that must be only ran on the CPU. These tests are skipped when a GPU is available.
    rF   ztest requires only a CPUre   rj   torch_devicerg   r<   r<   r=   require_cpu      ro   c                 C      t tdkd| S )z
    Decorator marking a test that requires a hardware accelerator backend. These tests are skipped when there are no
    hardware accelerator available.
    rF   test requires a GPUrm   rg   r<   r<   r=   require_non_cpu      rs   c                 C      t t ot  d| S )z
    Decorator marking a test that requires CUDA. These tests are skipped when there are no GPU available or when
    TorchXLA is available.
    rr   )re   rj   r   r)   rg   r<   r<   r=   require_cuda      rv   c                 C   s    t t r	t  pt d| S )z
    Decorator marking a test that requires CUDA or HPU. These tests are skipped when there are no GPU available or when
    TorchXLA is available.
    ztest requires a GPU or HPU)re   rj   r   r)   r   rg   r<   r<   r=   require_cuda_or_hpu   
   rx   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)re   rj   r3   rg   r<   r<   r=   require_xpu      r|   c                 C   s(   t  ot  }t }t|p|d| S )z
    Decorator marking a test that requires CUDA or XPU. These tests are skipped when there are no GPU available or when
    TorchXLA is available.
    ztest requires a CUDA GPU or XPU)r   r)   r3   re   rj   )rh   cuda_conditionxpu_conditionr<   r<   r=   require_cuda_or_xpu   s   r   c                 C   rq   )zB
    Decorator marking a test that should be skipped for XPU.
    rD   ztest requires a non-XPUrm   rg   r<   r<   r=   require_non_xpu   rp   r   c                 C   rq   )zB
    Decorator marking a test that should be skipped for HPU.
    rE   ztest requires a non-HPUrm   rg   r<   r<   r=   require_non_hpu   rp   r   c                 C   rz   )zj
    Decorator marking a test that requires FP16. These tests are skipped when FP16 is not supported.
    ztest requires FP16 support)re   rj   r   rg   r<   r<   r=   require_fp16      r   c                 C   s:   t  }tj rt sd}t rt rd}t|d| S )zh
    Decorator marking a test that requires FP8. These tests are skipped when FP8 is not supported.
    Fztest requires FP8 support)	r   rG   r6   is_availabler
   r   r   re   rj   )rh   fp8_is_availabler<   r<   r=   require_fp8   s   r   c                 C   s   t tddd| S )N>=z2.5.0z$test requires FSDP2 (torch >= 2.5.0))re   rj   r(   rg   r<   r<   r=   require_fsdp2   s   r   c                 C   rz   )zn
    Decorator marking a test that requires MLU. These tests are skipped when there are no MLU available.
    ztest require a MLU)re   rj   r   rg   r<   r<   r=   require_mlu  r}   r   c                 C   rz   )zp
    Decorator marking a test that requires SDAA. These tests are skipped when there are no SDAA available.
    ztest require a SDAA)re   rj   r$   rg   r<   r<   r=   require_sdaa
  r}   r   c                 C   rz   )zp
    Decorator marking a test that requires MUSA. These tests are skipped when there are no MUSA available.
    ztest require a MUSA)re   rj   r   rg   r<   r<   r=   require_musa  r}   r   c                 C   rz   )zn
    Decorator marking a test that requires NPU. These tests are skipped when there are no NPU available.
    ztest require a NPU)re   rj   r   rg   r<   r<   r=   require_npu  r}   r   c                 C   rz   )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`)re   rj   r   rg   r<   r<   r=   require_mps  r   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)re   rj   r0   r   rg   r<   r<   r=   require_huggingface_suite'  s   
r   c                 C   rz   )zi
    Decorator marking a test that requires transformers. These tests are skipped when they are not.
    z&test requires the transformers library)re   rj   r0   rg   r<   r<   r=   require_transformers1  r}   r   c                 C   rz   )za
    Decorator marking a test that requires timm. These tests are skipped when they are not.
    ztest requires the timm library)re   rj   r'   rg   r<   r<   r=   require_timm8  r}   r   c                 C   rz   )zh
    Decorator marking a test that requires torchvision. These tests are skipped when they are not.
    z%test requires the torchvision library)re   rj   r,   rg   r<   r<   r=   require_torchvision?  r}   r   c                 C   rz   )zc
    Decorator marking a test that requires triton. These tests are skipped when they are not.
    z test requires the triton library)re   rj   r1   rg   r<   r<   r=   require_tritonF  r}   r   c                 C   rz   )zi
    Decorator marking a test that requires schedulefree. These tests are skipped when they are not.
    z&test requires the schedulefree library)re   rj   r#   rg   r<   r<   r=   require_schedulefreeM  r}   r   c                 C   rz   )zi
    Decorator marking a test that requires bitsandbytes. These tests are skipped when they are not.
    z&test requires the bitsandbytes library)re   rj   r   rg   r<   r<   r=   require_bnbT  r}   r   c                 C   s   t tddd| S )zp
    Decorator marking a test that requires TPUs. These tests are skipped when there are no TPUs available.
    T)check_is_tpuztest requires TPUre   rj   r)   rg   r<   r<   r=   require_tpu[  s   r   c                 C   s   t t  d| S )z
    Decorator marking a test as requiring an environment without TorchXLA. These tests are skipped when TorchXLA is
    available.
    z%test requires an env without TorchXLAr   rg   r<   r<   r=   require_non_torch_xlab  rt   r   c                 C   s   t tdko	tdkd| S )z
    Decorator marking a test that requires a single device. These tests are skipped when there is no hardware
    accelerator available or number of devices is more than one.
    rF   r9   z)test requires a single device accelerator)re   rj   rn   rH   rg   r<   r<   r=   require_single_devicej  s
   r   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.
    r9   rr   re   rj   rG   r6   rH   rg   r<   r<   r=   require_single_gput  rw   r   c                 C   r   )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.
    r9   r{   re   rj   rG   rD   rH   rg   r<   r<   r=   require_single_xpu|  rw   r   c                 C   s   t tdkd| S )z
    Decorator marking a test that requires a multi-device setup. These tests are skipped on a machine without multiple
    devices.
    r9   z,test requires multiple hardware accelerators)re   rj   rH   rg   r<   r<   r=   require_multi_device  rt   r   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.
    r9   ztest requires multiple GPUsr   rg   r<   r<   r=   require_multi_gpu  rw   r   c                 C   r   )z
    Decorator marking a test that requires a multi-XPU setup. These tests are skipped on a machine without multiple
    XPUs.
    r9   ztest requires multiple XPUsr   rg   r<   r<   r=   require_multi_xpu  rw   r   c                 C   s    t t st ot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 or XPUs.
    r9   z#test requires multiple GPUs or XPUs)re   rj   r   r3   rH   rg   r<   r<   r=   require_multi_gpu_or_xpu  ry   r   c                 C   rz   )z|
    Decorator marking a test that requires DeepSpeed installed. These tests are skipped when DeepSpeed isn't installed
    ztest requires DeepSpeed)re   rj   r   rg   r<   r<   r=   require_deepspeed  r}   r   c                 C   s"   t tddotdddd| S )zn
    Decorator marking a test that requires TP installed. These tests are skipped when TP isn't installed
    r   z2.3.0transformersz4.52.0zGtest requires torch version >= 2.3.0 and transformers version >= 4.52.0)re   rj   r(   r   rg   r<   r<   r=   
require_tp  s   r   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)versionr   ztest requires torch version >= )r   require_torch_min_versionre   rj   r(   )rh   r   r<   r<   r=   r     s   r   c                 C   rz   )z
    Decorator marking a test that requires tensorboard installed. These tests are skipped when tensorboard isn't
    installed
    ztest requires Tensorboard)re   rj   r&   rg   r<   r<   r=   require_tensorboard  r   r   c                 C   rz   )zt
    Decorator marking a test that requires wandb installed. These tests are skipped when wandb isn't installed
    ztest requires wandb)re   rj   r2   rg   r<   r<   r=   require_wandb  r}   r   c                 C   rz   )zx
    Decorator marking a test that requires trackio installed. These tests are skipped when trackio isn't installed
    ztest requires trackio)re   rj   r-   rg   r<   r<   r=   require_trackio  r}   r   c                 C   rz   )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)re   rj   r   rg   r<   r<   r=   require_comet_ml  r}   r   c                 C   rz   )zp
    Decorator marking a test that requires aim installed. These tests are skipped when aim isn't installed
    ztest requires aim)re   rj   r   rg   r<   r<   r=   require_aim  r}   r   c                 C   rz   )zx
    Decorator marking a test that requires clearml installed. These tests are skipped when clearml isn't installed
    ztest requires clearml)re   rj   r   rg   r<   r<   r=   require_clearml  r}   r   c                 C   rz   )zx
    Decorator marking a test that requires dvclive installed. These tests are skipped when dvclive isn't installed
    ztest requires dvclive)re   rj   r   rg   r<   r<   r=   require_dvclive  r}   r   c                 C   rz   )zx
    Decorator marking a test that requires swanlab installed. These tests are skipped when swanlab isn't installed
    ztest requires swanlab)re   rj   r%   rg   r<   r<   r=   require_swanlab  r}   r   c                 C   rz   )zv
    Decorator marking a test that requires pandas installed. These tests are skipped when pandas isn't installed
    ztest requires pandas)re   rj   r    rg   r<   r<   r=   require_pandas  r}   r   c                 C   rz   )zv
    Decorator marking a test that requires mlflow installed. These tests are skipped when mlflow isn't installed
    ztest requires mlflow)re   rj   r   rg   r<   r<   r=   require_mlflow  r}   r   c                 C   ru   )z
    Decorator marking a test that requires pippy installed. These tests are skipped when pippy isn't installed It is
    also checked if the test is running on a Gaudi1 device which doesn't support pippy.
    ztest requires pippy)re   rj   r!   r   rg   r<   r<   r=   require_pippy  rw   r   c                 C   rz   )z
    Decorator marking a test that requires tuna interpreter installed. These tests are skipped when tuna isn't
    installed
    ztest requires tuna interpreter)re   rj   r   rg   r<   r<   r=   require_import_timer  r   r   c                 C   rz   )z
    Decorator marking a test that requires transformers engine installed. These tests are skipped when transformers
    engine isn't installed
    z!test requires transformers engine)re   rj   r.   rg   r<   r<   r=   require_transformer_engine  r   r   c                 C   rz   )z
    Decorator marking a test that requires transformers engine MXFP8 block scaling available. These tests are skipped
    when transformers engine MXFP8 block scaling isn't available
    z5test requires transformers engine MXFP8 block scaling)re   rj   r/   rg   r<   r<   r=    require_transformer_engine_mxfp8   s
   r   c                 C   rz   )zx
    Decorator marking a test that requires torchao installed. These tests are skipped when torchao isn't installed
    ztest requires torchao)re   rj   r*   rg   r<   r<   r=   require_torchao*  r}   r   c                 C   rz   )z
    Decorator marking a test that requires matplotlib installed. These tests are skipped when matplotlib isn't
    installed
    ztest requires matplotlib)re   rj   r   rg   r<   r<   r=   require_matplotlib1  r   r   c                 C   ri   )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)re   rj   _atleast_one_tracker_availablerg   r<   r<   r=   require_trackers?  s   r   c                 C   rz   )z
    Decorator marking a test that requires torchdata.stateful_dataloader.

    These tests are skipped when torchdata with stateful_dataloader module isn't installed.

    z+test requires torchdata.stateful_dataloader)re   rj   r+   rg   r<   r<   r=   %require_torchdata_stateful_dataloaderJ  s
   r   c                 C   s"   t  rddl}|jd| S | S )a  
    Decorator marking a test with order(1). When pytest-order plugin is installed, tests marked with this decorator are
    guaranteed to run first.

    This is especially useful in some test settings like on a Gaudi instance where a Gaudi device can only be used by a
    single process at a time. So we make sure all tests that run in a subprocess are launched first, to avoid device
    allocation conflicts.

    If pytest is not installed, test will be returned as is.
    r   Nr9   )r"   pytestmarkorder)rh   r   r<   r<   r=   	run_firstV  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 destroys 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 t | _dS )zECreates a `tempfile.TemporaryDirectory` and stores it in `cls.tmpdir`N)r   tempfilemkdtemptmpdirclsr<   r<   r=   
setUpClassu  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rmtreer   r<   r<   r=   tearDownClassz  s   zTempDirTestCase.tearDownClassc                 C   sD   | j r| 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   globis_fileunlinkis_dirr   r   )selfr   r<   r<   r=   setUp  s   

zTempDirTestCase.setUpN)	__name__
__module____qualname____doc__r   classmethodr   r   r   r<   r<   r<   r=   r   i  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d d S )NT)supertearDownr	   _reset_state)r   	__class__r<   r=   r     s   
zAccelerateTestCase.tearDown)r   r   r   r   r   __classcell__r<   r<   r   r=   r     s    r   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)rQ   tuplelistr   start
addCleanupstop)r   r   mr<   r<   r=   	add_mocks  s
   	
zMockingTestCase.add_mocksN)	r   r   r   r   r   r   Mockr   r   r<   r<   r<   r=   r     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   rF   rangeshaperG   equal)tensorstatetensorsir<   r<   r=   are_the_same_tensors  s   r   c                   @   s   e Zd Zdd ZdS )
_RunOutputc                 C   s   || _ || _|| _d S N)
returncodestdoutstderr)r   r   r   r   r<   r<   r=   __init__  s   
z_RunOutput.__init__N)r   r   r   r   r<   r<   r<   r=   r     s    r   c                    s&   	 |   I d H }|r|| nd S qr   )readline)streamcallbackliner<   r<   r=   _read_stream  s   
r   c              	      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   r9   )stdinr   r   env c                    s2   |  d } ||   st|| |d d S d S )Nutf-8)file)decoderstriprS   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=   r>         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_subprocess  s.   
r!     Tr  c              
   C   s   t | D ]\}}t|trt|| |< qt }|t| |||||d}	d| }
|	j	dkrCd|	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:
)	enumeraterQ   r   strr  get_event_looprun_until_completer!  r  r   r   RuntimeError)r  r  r  r  r  r  r   cloopresultcmd_strr   r<   r<   r=   execute_subprocess_async  s"   


r.  c                  C   s*   t jdd} tdd| dtj} t| S )z
    Returns an int value of worker's numerical id under `pytest-xdist`'s concurrent workers `pytest -n N` regime, or 0
    if `-n 1` or `pytest-xdist` isn't being used.
    PYTEST_XDIST_WORKERgw0z^gwr  r   )r[   r\   getresubMint)workerr<   r<   r=   pytest_xdist_worker_id  s   r7  c                  C   s   d} t  }| | S )z
    Returns a port number that can be fed to `torch.distributed.launch`'s `--master_port` argument.

    Under `pytest-xdist` it adds a delta number based on a worker id so that concurrent tests don't try to use the same
    port at once.
    i<s  )r7  )port
uniq_deltar<   r<   r=   get_torch_dist_unique_port  s   r:  c                   @   s   e Zd ZdS )SubprocessCallExceptionN)r   r   r   r<   r<   r<   r=   r;  '  s    r;  rU   c              
   C   s   t | D ]\}}t|trt|| |< q|du rtj }ztj| tj	|d}|r6t
|dr3|d}|W S W dS  tjyV } 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 occurred while running `command`
    N)r   r  r  r  z	Command `r   z$` failed with the following error:

)r%  rQ   r   r&  r[   r\   copyr  check_outputSTDOUThasattrr  CalledProcessErrorr;  r  output)rU   return_stdoutr  r   r*  rA  er<   r<   r=   run_command+  s*   



rD  
componentsc                  G   s   t ttj}|j|  S )z
    Get a path within the `accelerate` package's directory.

    Args:
        *components: Components of the path to join after the package directory.

    Returns:
        `Path`: The path to the requested file or directory.
    )r   inspectgetfilerM   parentjoinpath)rE  accelerate_package_dirr<   r<   r=   path_in_accelerate_packageB  s   
rK  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.)	ExceptionrQ   typer&  AssertionError)rL  rM  was_ranrC  r<   r<   r=   assert_exceptionQ  s   "&rR  c              
   O   s^   t  }tj}z#z|t_| |i | W n ty" } z|d}~ww W |t_| S |t_w )z`
    Takes in a `func` with `args` and `kwargs` and returns the captured stdout as a string
    N)ioStringIOr  r   rN  getvalue)funcargsrT   captured_outputoriginal_stdoutrC  r<   r<   r=   capture_call_outputd  s   rZ  )F)NN)NNNFF)NNr"  FT)FNr   )r  rF  rS  r[   r2  r   r  r  r   re   
contextlibr   	functoolsr   pathlibr   typingr   r   r   rG   rM   r   r	   utilsr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   rK   rn   rH   memory_allocated_funcr   rX   DEFAULT_LAUNCH_COMMANDrc   rk   rf   rl   ro   rs   rv   rx   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   anyr   r   r   r   TestCaser   r   r   r   r   r   r!  r.  r7  r:  rN  r;  r&  rD  rK  rR   rR  rZ  r<   r<   r<   r=   <module>   s   /









	!!	)
