
    &`im              	       Z   d 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mZ ddl	Z
ddlZddlmc mZ ddlmZ ddlmZmZ ddlmZ  ej        e          Z	 ddlmZ d	Zd
an# e$ r d
Zd	aY nw xY w	 ddlm Z  d	Z!n# e$ r d
Z!Y nw xY wd Z"d Z#d Z$dee%e&f         fdZ' G d de(          Z) e)            a* ej+                    a,d Z-ej.        j/        ddfde&de&de%de&fdZ0ej.        j/        ddfde&dee&         de%de&fdZ1dDde%ddfdZ2dDde%de&fdZ3dDde%de&fdZ4dej5        j6        fde%fd Z7dej5        j6        fd!e8de%fd"Z9dDde%fd#Z:ddej5        j6        fd$e&de%fd%Z;dddej5        j6        fd!e8d$e&d&e&de%fd'Z<dEd(e&de%fd)Z=	 dFd(e&d*e&de%fd+Z>dDd!e8de%fd,Z?	 dDd-e8d.e8de%fd/Z@dej5        j6        fd!e8de%fd0ZAdej5        j6        fde%fd1ZBdDd$e&de%fd2ZC	 	 dGd$e&d3e&de%d4e&fd5ZDdDd(e&de%fd6ZE	 	 dGd(e&d7e&de%d4e&fd8ZFd9e&fd:ZGdDde%fd;ZHd< ZId=ej.        fd>ZJd? ZKde&fd@ZLdA ZMdB ZNdC ZOdS )Hz5APIs exposed under the namespace ray.util.collective.    N)ListTuple   )types)find_free_portis_ipv6)get_master_address_metadata_key)	NCCLGroupTF)TorchGLOOGroupc                  |    t          j                    r#t          rt                              d           dat
          S )NzqNCCL seems unavailable. Please install Cupy following the guide at: https://docs.cupy.dev/en/stable/install.html.F)rayget_gpu_ids_LOG_NCCL_WARNINGloggerwarning_NCCL_AVAILABLE     r/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/util/collective/collective.pynccl_availabler   *   sC    
 ". "<	
 	
 	

 "r   c                      t           S N_TORCH_DISTRIBUTED_AVAILABLEr   r   r   gloo_availabler   6   s
     ('r   c                      t           S r   r   r   r   r   torch_distributed_availabler   <   s    ''r   returnc                      t           j                                        } t          t	          |           rt
          j        nt
          j                  }| |fS )z4Returns the IP address and a free port on this node.)r   utilget_node_ip_addressr   r   socketAF_INET6AF_INET)addrports     r   get_address_and_portr'   @   s?    8''))DWT]]N&//OOD:r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )GroupManagera  Use this class to manage the collective groups we created so far.

    Each process will have an instance of `GroupManager`. Each process
    could belong to multiple collective groups. The membership information
    and other metadata are stored in the global `_group_mgr` object.
    c                     i | _         d S r   _name_group_map)selfs    r   __init__zGroupManager.__init__O   s    !r   c                 V   t          j        |          }|t           j        j        k    rt          |          }|dk    r,t	                      \  }}t          j        || d|            ntt          j                    |r|dz  ndz   }		 t          j        |          }
|
n?t          j                    |	k    rt          d| d          t          j
        d	           Vt                              d
                    |                     t          ||||          }nu|t           j        j        k    rNt!          |           t                              d                    |                     t#          |||          }nt%          d|           || j        |<   | j        |         S )zThe entry to create new collective groups in the manager.

        Put the registration and the group information into the manager
        metadata as well.
        r   :g     @@g      >@TNz:Timed out waiting for GLOO rendezvous metadata for group 'z'.g?z.Creating torch.distributed GLOO group: '{}'...zCreating NCCL group: '{}'...zUnexpected backend: )r   BackendGLOO_get_master_addr_keyr'   _internal_kv_internal_kv_puttime_internal_kv_getTimeoutErrorsleepr   debugformatr   NCCL_check_backend_availabilityr
   RuntimeErrorr,   )r-   backend
world_sizerank
group_namegloo_timeoutmetadata_keyr%   r&   
deadline_smetags               r   create_collective_groupz$GroupManager.create_collective_groupR   s    -((em(((/
;;Lqyy133
d-lt<L<Ld<L<LMMMM "Y[[-9CL6))t
%'8FFD'y{{Z//*gYcggg   Jt$$$% LL@GG
SS   z4\JJAA***'000LL7>>zJJKKK*dJ77AA?g??@@@+,Z(#J//r   c                     || j         v S r   r+   r-   rB   s     r   is_group_existzGroupManager.is_group_exist~   s    T111r   c                     |                      |          s/t                              d                    |                     dS | j        |         S )z,Get the collective group handle by its name.z"The group '{}' is not initialized.N)rK   r   r   r;   r,   rJ   s     r   get_group_by_namezGroupManager.get_group_by_name   sL    "":.. 	NN?FFzRRSSS4#J//r   c                 ^   |                      |          s/t                              d                    |                     dS | j        |         }| j        |= |                                 d|z   }	 t          j        |          }t          j        |           dS # t          $ r Y dS w xY w)zGroup destructor.zThe group '{}' does not exist.Ninfo_)
rK   r   r   r;   r,   destroy_groupr   	get_actorkill
ValueError)r-   rB   rG   namestores        r   destroy_collective_groupz%GroupManager.destroy_collective_group   s    "":.. 	NN;BB:NNOOOF  , ,	 #	M$''EHUOOOOO 	 	 	DD	s   4(B 
B,+B,N)	__name__
__module____qualname____doc__r.   rH   rK   rM   rV   r   r   r   r)   r)   G   sj         " " "*0 *0 *0X2 2 20 0 0    r   r)   c                 x    t           5  t                              |           cddd           S # 1 swxY w Y   dS )zDCheck if the group is initialized in this process by the group name.N)_group_mgr_lock
_group_mgrrK   rB   s    r   is_group_initializedr_      s     
 5 5((445 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s   /33default0u  r@   rA   rB   rC   c                    t                       t          j        |          }t          |           |s"t	          d                    |                    t          5  t                              |          rt          d          | dk    sJ |dk    sJ || k     sJ t          
                    || |||           ddd           dS # 1 swxY w Y   dS )a=  Initialize a collective group inside an actor process.

    Args:
        world_size: the total number of processes in the group.
        rank: the rank of the current process.
        backend: the CCL backend to use, NCCL or GLOO.
        group_name: the name of the collective group.

    Returns:
        None
    z%group_name '{}' needs to be a string.#Trying to initialize a group twice.r   N)_check_inside_actorr   r1   r=   rS   r;   r\   r]   rK   r>   rH   )r@   rA   r?   rB   rC   s        r   init_collective_groupre      s3   $ mG$$G(((
  U@GG
SSTTT	 	
 	
$$Z00 	FDEEEA~~~~qyyyyj    **Zz<	
 	
 	
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
s   A C

CCranksc           	      @   t          j        |          }t          |           d|z   }	 t          j        |           t          d          # t          $ r Y nw xY wt          |          t          |           k    r=t          d                    t          |          t          |                               t          |          t          t          t          |                              k    rMt          d                    t          |          d                    d |D                                           |dk    r"t          d                    |                    t          |          dk    st          d	          t          |          |k     st          d
          ddlm} d|z   }d | D             }|                    |d                                          }	t          j        |	j                            |||||          g           dS )a  Declare a list of actors as a collective group.

    Note: This function should be called in a driver process.

    Args:
        actors: a list of actors to be set in a collective group.
        world_size: the total number of processes in the group.
        ranks (List[int]): the rank of each actor.
        backend: the CCL backend to use, NCCL or GLOO.
        group_name: the name of the collective group.

    Returns:
        None
    rO   rc   zHEach actor should correspond to one rank. Got '{}' ranks but '{}' actorsz5Ranks must be a permutation from 0 to '{}'. Got '{}'. c                 ,    g | ]}t          |          S r   )str).0rs     r   
<listcomp>z+create_collective_group.<locals>.<listcomp>   s    $;$;$;SVV$;$;$;r   r   z/World size must be greater than zero. Got '{}'.zRanks must be non-negative.z(Ranks cannot be greater than world_size.)Infoc                     g | ]	}|j         
S r   )_ray_actor_id)rk   as     r   rm   z+create_collective_group.<locals>.<listcomp>  s    111Q111r   detached)rT   lifetimeN)r   r1   r=   r   rQ   r>   rS   lenr;   setrangejoinallray.util.collective.utilrn   optionsremotegetset_info)
actorsr@   rf   r?   rB   rC   rT   rn   	actors_idinfos
             r   rH   rH      s!   , mG$$G(((ZDd@AAA    5zzS[[  $$*F3u::s6{{$C$C
 
 	

 5zzSs5zz**++++CJJE

BGG$;$;U$;$;$;<< 
 
 	
 Q=DDZPP
 
 	
 u::??8999u::
""EFFF .----- ZD11&111I<<TJ<77>>@@DGT]!!)ZVVWXXXXXs   #A 
AAc                     t                       t          5  t                              |            ddd           dS # 1 swxY w Y   dS )z0Destroy a collective group given its group name.N)rd   r\   r]   rV   r^   s    r   rV   rV     s     
 8 8++J7778 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8s   >AAc                     t                       t          5  t                              |           s	 ddd           dS t                              |           }|j        cddd           S # 1 swxY w Y   dS )a  Return the rank of this process in the given group.

    Args:
        group_name: the name of the group to query

    Returns:
        the rank of this process in the named group,
        -1 if the group does not exist or the process does
        not belong to the group.
    N)rd   r\   r]   rK   rM   rA   rB   rG   s     r   get_rankr     s      
  ((44 	        ((44v	                    A, A,,A03A0c                     t                       t          5  t                              |           s	 ddd           dS t                              |           }|j        cddd           S # 1 swxY w Y   dS )a  Return the size of the collective group with the given name.

    Args:
        group_name: the name of the group to query

    Returns:
        The world size of the collective group, -1 if the group does
            not exist or the process does not belong to the group.
    Nr   )rd   r\   r]   rK   rM   r@   r   s     r   get_collective_group_sizer   4  s      
  ((44 	        ((44|	                 r   c                     t          |            t          |          }t          j        }||_        |                    | g|           dS )a   Collective allreduce the tensor across the group.

    Args:
        tensor: the tensor to be all-reduced on this process.
        group_name: the collective group name to perform allreduce.
        op: The reduce operation.

    Returns:
        None
    N)_check_single_tensor_inputget_group_handler   AllReduceOptionsreduceOp	allreduce)tensorrB   oprG   optss        r   r   r   H  sJ     v&&&$$A!DDMKK$r   tensor_listc                     t          j                    st          d          t          |            t	          |          }t           j        }||_        |                    | |           dS )a  Collective allreduce a list of tensors across the group.

    Args:
        tensor_list (List[tensor]): list of tensors to be allreduced,
            each on a GPU.
        group_name: the collective group name to perform allreduce.

    Returns:
        None
    &Multigpu calls requires NCCL and Cupy.N)r   cupy_availabler>   _check_tensor_list_inputr   r   r   r   )r   rB   r   rG   r   s        r   allreduce_multigpur   Z  si     !! ECDDD[)))$$A!DDMKKT"""""r   c                 L    t          |           }|                                 dS )zBarrier all processes in the collective group.

    Args:
        group_name: the name of the group to barrier.

    Returns:
        None
    N)r   barrierr   s     r   r   r   p  s"     	$$AIIKKKKKr   dst_rankc                     t          |            t          |          }t          ||           t          j                    }||_        ||_        d|_        |                    | g|           dS )a:  Reduce the tensor across the group to the destination rank.

    Args:
        tensor: the tensor to be reduced on this process.
        dst_rank: the rank of the destination process.
        group_name: the collective group name to perform reduce.
        op: The reduce operation.

    Returns:
        None
    r   N)	r   r   _check_rank_validr   ReduceOptionsr   	root_rankroot_tensorreduce)r   r   rB   r   rG   r   s         r   r   r   }  sq     v&&&$$A a"""  DDMDNDHHfXtr   
dst_tensorc                 \   t          j                    st          d          t          |            t	          |          }t          ||           t          t          |           |           t          j                    }||_	        ||_
        ||_        |                    | |           dS )a  Reduce the tensor across the group to the destination rank
    and destination tensor.

    Args:
        tensor_list: the list of tensors to be reduced on this process;
            each tensor located on a GPU.
        dst_rank: the rank of the destination process.
        dst_tensor: the index of GPU at the destination.
        group_name: the collective group name to perform reduce.
        op: The reduce operation.

    Returns:
        None
    r   N)r   r   r>   r   r   r   _check_root_tensor_validrt   r   r   r   r   r   )r   r   r   rB   r   rG   r   s          r   reduce_multigpur     s    * !! ECDDD[)))$$A a"""S--z:::  DDMDN!DHH[$r   src_rankc                     t          |            t          |          }t          ||           t          j                    }||_        d|_        |                    | g|           dS )a(  Broadcast the tensor from a source process to all others.

    Args:
        tensor: the tensor to be broadcasted (src) or received (destination).
        src_rank: the rank of the source process.
        group_name: the collective group name to perform broadcast.

    Returns:
        None
    r   N)r   r   r   r   BroadcastOptionsr   r   	broadcastr   r   rB   rG   r   s        r   r   r     sj     v&&&$$A a"""!##DDNDKK$r   
src_tensorc                 N   t          j                    st          d          t          |            t	          |          }t          ||           t          t          |           |           t          j                    }||_	        ||_
        |                    | |           dS )ag  Broadcast the tensor from a source GPU to all other GPUs.

    Args:
        tensor_list: the tensors to broadcast (src) or receive (dst).
        src_rank: the rank of the source process.
        src_tensor: the index of the source GPU on the source process.
        group_name: the collective group name to perform broadcast.

    Returns:
        None
    r   N)r   r   r>   r   r   r   r   rt   r   r   r   r   )r   r   r   rB   rG   r   s         r   broadcast_multigpur     s     !! ECDDD[)))$$A a"""S--z:::!##DDN!DKKT"""""r   c                    t          |           t          |            t          |          }t          |           |j        k    rt          d          t          j                    }|                    | g|g|           dS )a   Allgather tensors from each process of the group into a list.

    Args:
        tensor_list: the results, stored as a list of tensors.
        tensor: the tensor (to be gathered) in the current process
        group_name: the name of the collective group.

    Returns:
        None
    zPThe length of the tensor list operands to allgather must be equal to world_size.N)	r   r   r   rt   r@   r>   r   AllGatherOptions	allgather)r   r   rB   rG   r   s        r   r   r     s     v&&&[)))$$A
;1<'' +
 
 	
 !##DKKx.....r   output_tensor_listsinput_tensor_listc                     t          j                    st          d          t          |            t	          |           t          |          }t          j                    }|                    | ||           dS )a  Allgather tensors from each gpus of the group into lists.

    Args:
        output_tensor_lists (List[List[tensor]]): gathered results, with shape
            must be num_gpus * world_size * shape(tensor).
        input_tensor_list: (List[tensor]): a list of tensors, with shape
            num_gpus * shape(tensor).
        group_name: the name of the collective group.

    Returns:
        None
    r   N)r   r   r>   _check_tensor_lists_inputr   r   r   r   )r   r   rB   rG   r   s        r   allgather_multigpur     s|     !! ECDDD1222.///$$A!##DKK#%6=====r   c                    t          |            t          |           t          |          }t          j                    }||_        t          |          |j        k    rt          d          |	                    | g|g|           dS )a  Reducescatter a list of tensors across the group.

    Reduce the list of the tensors across each process in the group, then
    scatter the reduced list of tensors -- one tensor for each process.

    Args:
        tensor: the resulted tensor on this process.
        tensor_list: The list of tensors to be reduced and scattered.
        group_name: the name of the collective group.
        op: The reduce operation.

    Returns:
        None
    zXThe length of the tensor list operands to reducescatter must not be equal to world_size.N)
r   r   r   r   ReduceScatterOptionsr   rt   r@   r>   reducescatter)r   r   rB   r   rG   r   s         r   r   r     s    " v&&&[)))$$A%''DDM
;1<''/
 
 	
 OOVH{mT22222r   c                    t          j                    st          d          t          |           t	          |            t          |          }t          j                    }||_        |                    | ||           dS )a  Reducescatter a list of tensors across all GPUs.

    Args:
        output_tensor_list: the resulted list of tensors, with
            shape: num_gpus * shape(tensor).
        input_tensor_lists: the original tensors, with shape:
            num_gpus * world_size * shape(tensor).
        group_name: the name of the collective group.
        op: The reduce operation.

    Returns:
        None.
    r   N)	r   r   r>   r   r   r   r   r   r   )output_tensor_listinput_tensor_listsrB   r   rG   r   s         r   reducescatter_multigpur   <  s    & !! ECDDD0111/000$$A%''DDMOO&(:DAAAAAr   c                    t          |            t          |          }t          ||           ||j        k    r"t	          d                    |                    t          j                    }||_        |	                    | g|           dS )zSend a tensor to a remote process synchronously.

    Args:
        tensor: the tensor to send.
        dst_rank: the rank of the destination process.
        group_name: the name of the collective group.

    Returns:
        None
    "The destination rank '{}' is self.N)
r   r   r   rA   r>   r;   r   SendOptionsr   send)r   r   rB   rG   r   s        r   r   r   Y       v&&&$$Aa"""16?FFxPPQQQDDMFFF8Tr   dst_gpu_index
n_elementsc                    t          j                    st          d          t          |            t	          |          }t          ||           ||j        k    r"t          d                    |                    |dk     r"t          d                    |                    t          j                    }||_	        ||_
        ||_        |                    | g|           dS )a  Send a tensor to a remote GPU synchronously.

    The function assumes each process owns >1 GPUs, and the sender
    process and receiver process has equal number of GPUs.

    Args:
        tensor: the tensor to send, located on a GPU.
        dst_rank: the rank of the destination process.
        dst_gpu_index: the destination gpu index.
        group_name: the name of the collective group.
        n_elements: if specified, send the next n elements
            from the starting address of tensor.

    Returns:
        None
    z!send_multigpu call requires NCCL.GThe dst_rank '{}' is self. Considering doing GPU to GPU memcpy instead?r   z The n_elements '{}' should >= 0.N)r   r   r>   r   r   r   rA   r;   r   r   r   r   r   )r   r   r   rB   r   rG   r   s          r   send_multigpur   n  s    . !! @>???v&&&$$Aa"""16//5vh/?/?
 
 	
 A~~=DDZPPQQQDDM&D DOFFF8Tr   c                    t          |            t          |          }t          ||           ||j        k    r"t	          d                    |                    t          j                    }||_        |	                    | g|           dS )zReceive a tensor from a remote process synchronously.

    Args:
        tensor: the received tensor.
        src_rank: the rank of the source process.
        group_name: the name of the collective group.

    Returns:
        None
    r   N)
r   r   r   rA   r>   r;   r   RecvOptionsr   recvr   s        r   r   r     r   r   src_gpu_indexc                    t          j                    st          d          t          |            t	          |          }t          ||           ||j        k    r"t          d                    |                    |dk     r"t          d                    |                    t          j                    }||_	        ||_
        ||_        |                    | g|           dS )a  Receive a tensor from a remote GPU synchronously.

    The function asssume each process owns >1 GPUs, and the sender
    process and receiver process has equal nubmer of GPUs.

    Args:
        tensor: The received tensor, located on a GPU.
        src_rank: The rank of the source process.
        src_gpu_index: The index of the source GPU on the src process.
        group_name: The name of the collective group.

    Returns:
        None
    z!recv_multigpu call requires NCCL.r   r   z#The n_elements '{}' should be >= 0.N)r   r   r>   r   r   r   rA   r;   r   r   r   r   r   )r   r   r   rB   r   rG   r   s          r   recv_multigpur     s    * !! @>???v&&&$$Aa"""16//5vh/?/?
 
 	
 A~~@GG
SSTTTDDM&D DOFFF8Tr   gpu_idc                     t          j                    st          d          ddl}|j                            |                                            dS )zSynchronize the current process to a give device.

    Args:
        gpu_id: the GPU device id to synchronize.

    Returns:
        None
    z(synchronize call requires CUDA and NCCL.r   N)r   r   r>   cupycudaDevicesynchronize)r   cps     r   r   r     sW     !! GEFFFGNN6&&(((((r   c           	         t                       t          5  t                              |           s	 d| z   }t	          j        |          }t	          j        |j                                                  \  }}}}}t          j	        j
        j        }|j                                        }	||                    |	                   }
t                              |||
| |           n# t           $ r}dt"          j        v rt"          j        d         | k    rt'          t"          j        d                   }t'          t"          j        d                   }t"          j        d         }t#          j        dd          }t                              |||| |           n#t+          d	                    |                     |Y d
}~nd
}~ww xY wt                              |           }|cd
d
d
           S # 1 swxY w Y   d
S )zCheck if the group is initialized and return the group handle.

    Args:
        group_name: the name of the collective group.

    Returns:
        The collective group handle.
    rO   )rT   collective_group_namecollective_rankcollective_world_sizecollective_backendcollective_gloo_timeoutra   z<The collective group '{}' is not initialized in the process.N)rd   r\   r]   rK   r   rQ   r|   get_infor{   _privateworkerglobal_workercore_workerget_actor_idindexrH   rS   osenvironintgetenvr>   r;   rM   )rB   rT   mgridsr@   rA   r?   rC   r   id_rl   excrG   s                r   r   r     sT     
 $ $((44 !	 +m...?BwL''))@ @<Zw ,:(55773(22ZJ        ,rz99
#:;zIIrz*;<==D!$RZ0G%H!I!IJ j)=>G#%9-F#N#NL66T:|    '66<fZ6H6H  	    $ ((44I$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $s<   G1B3C'&G1'
G1CG<G1GG11G58G5c                 h   t          | t          j                  rdS t          j                    r!t          | t          j        j                  rdS t          j                    r!t          | t          j        j                  rdS t          d
                    t          |                               )z-Check if the tensor is with a supported type.Nz[Unrecognized tensor type '{}'. Supported types are: np.ndarray, torch.Tensor, cupy.ndarray.)
isinstancenpndarrayr   r   r   torch_availablethTensorr>   r;   type)r   s    r   r   r     s    &"*%%  feh.// 	F feho.. 	F
	228&f2F2F  r   r?   c                     | t           j        j        k    rt                      st	          d          dS | t           j        j        k    rt                      st	          d          dS dS )z'Check whether the backend is available.z#torch.distributed is not available.zNCCL is not available.N)r   r1   r2   r   r>   r<   r   )r?   s    r   r=   r=   (  s{    %-$$$*,, 	FDEEE	F 	F	EM&	&	& 	97888 
'	&	9 	9r   c                  z    t           j        j        j        } | j        t           j        k    rdS t          d          )z1Check if currently it is inside a Ray actor/task.NzBThe collective APIs shall be only used inside a Ray actor or task.)r   r   r   r   modeWORKER_MODEr>   )r   s    r   rd   rd   3  s8    \ .F{co%%P
 
 	
r   c                     |dk     r"t          d                    |                    || j        k    r(t          d                    || j                            dS )z'Check the rank: 0 <= rank < world_size.r   zrank '{}' is negative.z+rank '{}' must be less than world size '{}'N)rS   r;   r@   )rG   rA   s     r   r   r   >  sd    axx188>>???q|9@@q|TT
 
 	
 r   c                     t          | t                    s/t          d                    t	          |                               | st          d          | D ]}t          |           dS )z7Check if the input is a list of supported tensor types.z.The input must be a list of tensors. Got '{}'.zGot an empty list of tensors.N)r   listr>   r;   r   r   )r   ts     r   r   r   H  s    k4(( 
tK0011
 
 	
  <:;;; & &"1%%%%& &r   c                     t          | t                    s/t          d                    t	          |                               | st          d|            | D ]}t          |           dS )z@Check if the input is a list of lists of supported tensor types.z7The input must be a list of lists of tensors. Got '{}'.zDid not receive tensors. Got: N)r   r   r>   r;   r   r   )tensor_listsr   s     r   r   r   U  s    lD)) 
tL1122
 
 	
  LJLJJKKK $ $ ####$ $r   c                     |dk     r"t          d                    |                    || k    r#t          d                    ||                     dS )z9Check the root_tensor device is 0 <= root_tensor < lengthr   zroot_tensor '{}' is negative.z9root_tensor '{}' is greater than the number of GPUs: '{}'N)rS   r;   )lengthr   s     r   r   r   b  sa    Q8??LLMMMf6+v..
 
 	
 r   )r`   )r   r`   )r   r   r`   )r`   r   )PrZ   loggingr   r"   	threadingr6   typingr   r   numpyr   r   ray.experimental.internal_kvexperimentalinternal_kvr4   rh   r   ray._common.network_utilsr   r   @ray.util.collective.collective_group.torch_gloo_collective_groupr	   r3   	getLoggerrW   r   :ray.util.collective.collective_group.nccl_collective_groupr
   r   r   ImportErrorr   r   r   r   r   rj   r   r'   objectr)   r]   Lockr\   r_   r1   r<   re   rH   rV   r   r   ReduceOpSUMr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r=   rd   r   r   r   r   r   r   r   <module>r     s-   ; ;  				                   



 3 3 3 3 3 3 3 3 3       = = = = = = = =      
	8	$	$TTTTTTO   O
)      $(   ) ) )#(   )	 	 	( ( (( ( (eCHo    T T T T T6 T T Tn \^^
 ).""5 5 5 M%
 %
%

%
 	%

 %
 %
 %
 %
X M>Y >Y>Y 9>Y
 >Y >Y >Y >Y >YD8 8 8T 8 8 8 8  S    , # c    ( )2en6H    #        & *3u~7I# ###&# # # #,
 
 
 
 
 
 u~?Q +.   8 ~!  ! ! !  !  	!  !  !  ! H     S        . LU# ##03#EH# # # #8/ /4 /S / / / /4 KT> >>26>DG> > > >2 2;u~?Q3 33+.3 3 3 3B  ~	B B B B B B: 3 C    2  ' '' ' 	'
 ' ' ' 'T 3 C    2  % %% % 	%
 % % % %P) ) ) ) ) 0 0 0 0 0 0f   9 9 9 9 9
 
 

s 
 
 
 

& 
& 
&
$ 
$ 
$
 
 
 
 
s$   
A   	A,+A,0A9 9BB