
    &`ihP                        d dl Z d dlmZmZmZmZ d dlZd dlmZm	Z	 d dl
mZ d dlmZm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ah dZd Ze G d d                      Zedededefd            Z ededee         fd            Z!ee	 	 	 	 	 d0deee"e#f                  de"de"dee"         dee"         deee"e"f                  defd                        Z$eededdfd                        Z%eede"defd                         Z&eed1dede'fd!                        Z(edee         fd"            Z)ded#eddfd$Z*	 	 	 	 d2deee"e#f                  de"dee"         dee"         deee"e"f                  defd%Z+deee"e#f                  fd&Z,deee"e"f                  fd'Z-d( Z.d) Z/	 d3d+ed#ed,ed-ed.e"deee"df         defd/Z0dS )4    N)DictListOptionalUnion)$PLACEMENT_GROUP_BUNDLE_RESOURCE_NAMEhex_to_binary)auto_init_ray)client_mode_should_convertclient_mode_wrap)validate_label_selector)get_ray_doc_version)PlacementGroupID)DeveloperAPI	PublicAPI) PlacementGroupSchedulingStrategy>   PACKSPREADSTRICT_PACKSTRICT_SPREADc                  X    t           rd S t          j        d          d             } | a d S )Nr   )num_cpusc                     | S N placement_groups    l/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/util/placement_group.pybundle_reservation_check_funczX_export_bundle_reservation_check_method_if_needed.<locals>.bundle_reservation_check_func"   s        )bundle_reservation_checkrayremote)r   s    r   1_export_bundle_reservation_check_method_if_neededr#      sD     Z    =r   c                       e Zd ZdZedd            Z	 ddddeee                  fdZ	e
d	             ZddZddeeef         defdZe
dee         fd            Ze
defd            ZddZd Zd ZdS )PlacementGroupzA handle to a placement group.returnc                  B    t          t          j                              S r   )r%   r   nilr   r   r   emptyzPlacementGroup.empty-   s    .244555r   Nidzray._raylet.PlacementGroupIDbundle_cachec                 "    || _         || _        d S r   )r*   r+   )selfr*   r+   s      r   __init__zPlacementGroup.__init__1   s    
 (r   c                 4    | j                                         S r   )r*   is_nilr-   s    r   is_emptyzPlacementGroup.is_empty9   s    w~~r   ray._raylet.ObjectRefc                 ,   |                                   t                       t          | j                  dk    sJ dt          | j                               t                              t          |                                         |           S )a  Returns an ObjectRef to check ready status.

        This API runs a small dummy task to wait for placement group creation.
        It is compatible to ray.get and ray.wait.

        Example:
            .. testcode::

                import ray

                pg = ray.util.placement_group([{"CPU": 1}])
                ray.get(pg.ready())

                pg = ray.util.placement_group([{"CPU": 1}])
                ray.wait([pg.ready()])

        r   zeready() cannot be called on placement group object with a bundle length == 0, current bundle length: r   )scheduling_strategy)_fill_bundle_cache_if_neededr#   lenr+   r    optionsr   r"   r1   s    r   readyzPlacementGroup.ready=   s    $ 	))+++9;;;4$%%***(4$%%( ( +** (// @QU V V V 0 
 

&,,	r      timeout_secondsc                 ,    t          | j        |          S )zWait for the placement group to be ready within the specified time.
        Args:
             timeout_seconds(float|int): Timeout in seconds.
        Return:
             True if the placement group is created. False otherwise.
        )_call_placement_group_readyr*   )r-   r;   s     r   waitzPlacementGroup.wait]   s     +47ODDDr   c                 8    |                                   | j        S )z=List[Dict]: Return bundles belonging to this placement group.)r6   r+   r1   s    r   bundle_specszPlacementGroup.bundle_specsf   s     	))+++  r   c                 R    |                                   t          | j                  S r   )r6   r7   r+   r1   s    r   bundle_countzPlacementGroup.bundle_countl   s%    ))+++4$%%%r   c                 J    | j         st          | j                  | _         d S d S r   )r+   _get_bundle_cacher*   r1   s    r   r6   z+PlacementGroup._fill_bundle_cache_if_neededq   s/      	; 1$' : :D	; 	;r   c                 P    t          |t                    sdS | j        |j        k    S )NF)
isinstancer%   r*   )r-   others     r   __eq__zPlacementGroup.__eq__u   s(    %00 	5w%(""r   c                 *    t          | j                  S r   )hashr*   r1   s    r   __hash__zPlacementGroup.__hash__z   s    DG}}r   )r&   r%   r   )r&   r3   )r:   )r&   N)__name__
__module____qualname____doc__staticmethodr)   r   r   r   r.   propertyr2   r9   r   floatintboolr>   r@   rB   r6   rH   rK   r   r   r   r%   r%   )   s\       ((6 6 6 \6 .2) )*) tDz*) ) ) )     X    @E EE%*$5 Et E E E E !d4j ! ! ! X!
 &c & & & X&; ; ; ;# # #
    r   r%   pg_idr;   r&   c                     t           j        j        j        }|                                 |j                            | |          S r   )r!   _privateworkerglobal_workercheck_connectedcore_workerwait_placement_group_ready)rU   r;   rX   s      r   r=   r=   ~   s:    \ .F
88PPPr   c                     t           j        j        j        }|                                 t          t           j        j        j                            |           d                                                   S )Nbundles)	r!   rW   rX   rY   rZ   liststateplacement_group_tablevalues)rU   rX   s     r   rD   rD      s]    \ .F
 66u==iHOOQQ  r   r    r^   strategynamelifetime_soft_target_node_idbundle_label_selectorc                     t           j        j        j        }|                                 t          | ||||           |g }|dk    rd}nd}|j                            || ||||          }t          |          S )aM  Asynchronously creates a PlacementGroup.

    Args:
        bundles: A list of bundles which
            represent the resources requirements.
        strategy: The strategy to create the placement group.

         - "PACK": Packs Bundles into as few nodes as possible.
         - "SPREAD": Places Bundles across distinct nodes as even as possible.
         - "STRICT_PACK": Packs Bundles into one node. The group is
           not allowed to span multiple nodes.
         - "STRICT_SPREAD": Packs Bundles across distinct nodes.

        name: The name of the placement group.
        lifetime: Either `None`, which defaults to the placement group
            will fate share with its creator and will be deleted once its
            creator is dead, or "detached", which means the placement group
            will live as a global object independent of the creator.
        _soft_target_node_id: (Private, Experimental) Soft hint where bundles of
            this placement group should be placed.
            The target node is specified by it's hex ID.
            If the target node has no available resources or died,
            bundles can be placed elsewhere.
            This currently only works with STRICT_PACK pg.
        bundle_label_selector: A list of label selectors to apply to a
            placement group on a per-bundle level.

    Raises:
        ValueError: if bundle type is not a list.
        ValueError: if empty bundle or empty resource bundles are given.
        ValueError: if the wrong lifetime arguments are given.

    Return:
        PlacementGroup: Placement group object.
    r^   rd   rf   rg   rh   NdetachedTF)	r!   rW   rX   rY   rZ   validate_placement_groupr[   create_placement_groupr%   )	r^   rd   re   rf   rg   rh   rX   rk   placement_group_ids	            r   r   r      s    Z \ .F
13    $ ":+BB  ,---r   r   c                     | J t           j        j        j        }|                                 |j                            | j                   dS )znAsynchronously remove placement group.

    Args:
        placement_group: The placement group to delete.
    N)r!   rW   rX   rY   rZ   r[   remove_placement_groupr*   )r   rX   s     r   rp   rp      sO     &&&\ .F

--o.@AAAAAr   placement_group_namec                 \   | st          d          t          j        j        j        }|                                 t          j        j        j                            | |j                  }|t          d|            t          t          t          |d                                       S )zGet a placement group object with a global name.

    Returns:
        None if can't find a placement group with the given name.
        The placement group object otherwise.
    z6Please supply a non-empty value to get_placement_groupNz-Failed to look up placement group with name: rn   )
ValueErrorr!   rW   rX   rY   rZ   r`   get_placement_group_by_name	namespacer%   r   r   )rq   rX   placement_group_infos      r   get_placement_grouprw      s       SQRRR\ .F
<-3OOf.  #R<PRR
 
 	
 ]+?@T+UVVWW
 
 	
r   c                     t           j        j        j        }|                                 | | j        nd}t           j        j        j                            |          S )zGet the state of the placement group from GCS.

    Args:
        placement_group: placement group to see
            states.
    N)r!   rW   rX   rY   rZ   r*   r`   ra   )r   rX   rn   s      r   ra   ra     sT     \ .F
0?0K++RV<#99:LMMMr   c                      t                       t                      rdS t          j        j        j        } |                                  | j        }|                                rdS t          |          S )a	  Get the current placement group which a task or actor is using.

    It returns None if there's no current placement group for the worker.
    For example, if you call this method in your driver, it returns None
    (because drivers never belong to any placement group).

    Examples:
        .. testcode::

            import ray
            from ray.util.placement_group import get_current_placement_group
            from ray.util.scheduling_strategies import PlacementGroupSchedulingStrategy

            @ray.remote
            def f():
                # This returns the placement group the task f belongs to.
                # It means this pg is identical to the pg created below.
                return get_current_placement_group()

            pg = ray.util.placement_group([{"CPU": 2}])
            assert ray.get(f.options(
                    scheduling_strategy=PlacementGroupSchedulingStrategy(
                        placement_group=pg)).remote()) == pg

            # Driver doesn't belong to any placement group,
            # so it returns None.
            assert get_current_placement_group() is None

    Return:
        PlacementGroup: Placement group object.
            None if the current task or actor wasn't
            created with any placement group.
    N)
r	   r
   r!   rW   rX   rY   rZ   rn   r0   r%   )rX   rU   s     r   get_current_placement_grouprz     sk    F OOO!## t\ .F
%E||~~ t%   r   bundle_indexc                     | J | j                                         r|dk    rt          d          d S || j        k    s|dk     rt          d| d| j                   d S )NzDIf placement group is not set, the value of bundle index must be -1.zplacement group bundle index z. is invalid. Valid placement group indexes: 0-)r*   r0   rs   rB   )r   r{   s     r   check_placement_group_indexr~   C  s     &&&  "" 
28   
 
5	5	59J9J0L 0 0 -0 0
 
 	
 :K9Jr   c                    |r|dk    rt          d|           |rCt          j                            |                                          rt          d|           t          |            |Bt          |           t          |          k    rt          d| d          t          |           |t          vrt          d| dt           d	          |d
vrt          d| d	          dS )zXValidates inputs for placement_group.

    Raises ValueError if inputs are invalid.
    r   zC_soft_target_node_id currently only works with STRICT_PACK but got z,Invalid hex ID of _soft_target_node_id, got NzInvalid bundle label selector zM. The length of `bundle_label_selector` should equal the length of `bundles`.z!Invalid placement group strategy z. Supported strategies are: .)Nrk   zMPlacement group `lifetime` argument must be either `None` or 'detached'. Got )	rs   r!   NodeIDfrom_hexr0   _validate_bundlesr7   _validate_bundle_label_selector VALID_PLACEMENT_GROUP_STRATEGIESrj   s        r   rl   rl   U  sz     
M 9 93(03 3
 
 	

  

 3 34H I I P P R R 
Q;OQQ
 
 	
 g(w<<345555_1F _ _ _   	((=>>>777M M M)IM M M
 
 	

 )))+'+ + +
 
 	
 *)r   c                    t          | t                    s t          dt          |            d          t	          |           dk    rt          d          | D ]}t          |t
                    rVt          d |                                D                       r+t          d |                                D                       st          d          t	          |          dk    s+t          d |                                D                       rt          d	|            d
|                                v r,t          j
        dt                       dt          d           dS )zGValidates each bundle and raises a ValueError if any bundle is invalid.z,Placement group bundles must be a list, got r   r   zBundles must be a non-empty list of resource dictionaries. For example: `[{"CPU": 1.0}, {"GPU": 1.0}]`. Got empty list instead.c              3   @   K   | ]}t          |t                    V  d S r   rF   str.0ks     r   	<genexpr>z$_validate_bundles.<locals>.<genexpr>  s,      AAaz!S))AAAAAAr   c              3   N   K   | ] }t          |t          t          f          V  !d S r   )rF   rS   rR   r   vs     r   r   z$_validate_bundles.<locals>.<genexpr>  s0      LLqz!c5\22LLLLLLr   zgBundles must be a non-empty list of resource dictionaries. For example: `[{"CPU": 1.0}, {"GPU": 1.0}]`.c              3   "   K   | ]
}|d k    V  dS )r   Nr   )r   resource_values     r   r   z$_validate_bundles.<locals>.<genexpr>  s8       #
 #
$2Na#
 #
 #
 #
 #
 #
r   zPBundles cannot be an empty dictionary or resources with only 0 values. Bundles: object_store_memoryzSetting 'object_store_memory' for bundles is deprecated since it doesn't actually reserve the required object store memory. Use object spilling that's enabled by default (https://docs.ray.io/en/zb/ray-core/objects/object-spilling.html) instead to bypass the object store memory size limitation.   )
stacklevelN)rF   r_   rs   typer7   dictallkeysrb   warningswarnr   DeprecationWarning)r^   bundles     r   r   r     s    gt$$ 
Nd7mmNNN
 
 	
 7||q&
 
 	
   64((		AA6;;==AAAAA		 LLFMMOOLLLLL		
 2   v;;!s #
 #
6<mmoo#
 #
 #
  
  
 D:AD D  
 !FKKMM11MM [nZoZoM M M
 #   + r   c                    t          | t                    s t          dt          |            d          t	          |           dk    rdS | D ]}t          |t
                    rVt          d |                                D                       r+t          d |                                D                       st          d          t          |          }|rt          d| d	          dS )
zWValidates each label selector and raises a ValueError if any label selector is invalid.z:Placement group bundle_label_selector must be a list, got r   r   Nc              3   @   K   | ]}t          |t                    V  d S r   r   r   s     r   r   z2_validate_bundle_label_selector.<locals>.<genexpr>  s,      IIaz!S))IIIIIIr   c              3   @   K   | ]}t          |t                    V  d S r   r   r   s     r   r   z2_validate_bundle_label_selector.<locals>.<genexpr>  s,      KKaz!S))KKKKKKr   zBundle label selector must be a list of string dictionary label selectors. For example: `[{ray.io/market_type": "spot"}, {"ray.io/accelerator-type": "A100"}]`.zPInvalid label selector provided in bundle_label_selector list. Detailed error: '')
rF   r_   rs   r   r7   r   r   r   rb   r   )rh   label_selectorerror_messages      r   r   r     sF    +T22 
2-..2 2 2
 
 	

  !!Q&&/  >400		II>3F3F3H3HIIIII		 KK>3H3H3J3JKKKKK		
 Z   0?? 	6%26 6 6  	 r   c                     |D ]M}d}|                                  D ]/\  }}|t          k    r|                    |d          |k     rd} n0|r dS NdS )zS
    If the resource shape cannot fit into every
    bundle spec, return False
    Tr   F)itemsr   get)	resourcesr@   r   fit_in_bundleresourcerequested_vals         r   _valid_resource_shaper     s    
   '0'8'8 	 	#Hm ???zz(A&&66 % 7  	44	 5r   c           	          | j         }t          ||          }t          ||          }|st          d| d| d| d          |s-t          d| d|                    dd           d| d	          d S )
NzCannot schedule z7 with the placement group because the resource request z6 cannot fit into any bundles for the placement group, r   z5 with the placement group because the actor requires CPUr   zO CPU for creation, but it cannot fit into any bundles for the placement group, z9. Consider creating a placement group with CPU resources.)r@   r   rs   r   )r   r   placement_resourcestask_or_actor_reprr^   resources_validplacement_resources_valids          r   _validate_resource_shaper     s     *G+Iw??O 56I7 S S 
/1 / // / %,/ / /
 
 	
 % 
 =1 = ="&&ua00= =
 = = =
 
 	
	
 
r   default#placement_group_capture_child_tasksr   r   r   c                 p   | J |J |dk    r|st                                           }n0|dk    r*| rt                      }nt                                           }|st                                           }t          |t                     sJ t	          ||           |j        st          ||||           |S )a  Configure the placement group based on the given context.

    Based on the given context, this API returns the placement group instance
    for task/actor scheduling.

    Params:
        placement_group_capture_child_tasks: Whether or not the
            placement group needs to be captured from the global
            context.
        bundle_index: The bundle index for tasks/actor scheduling.
        resources: The scheduling resources.
        placement_resources: The scheduling placement resources for
            actors.
        task_or_actor_repr: The repr of task or actor
            function/class descriptor.
        placement_group: The placement group instance.
            - "default": Default placement group argument. Currently,
                the default behavior is to capture the parent task'
                placement group if placement_group_capture_child_tasks
                is set.
            - None: means placement group is explicitly not configured.
            - Placement group instance: In this case, do nothing.

    Returns:
        Placement group instance based on the given context.

    Raises:
        ValueError: If the bundle index is invalid for the placement group
            or the requested resources shape doesn't fit to any
            bundles.
    Nr   )r%   r)   rz   rF   r~   r2   r   )r   r{   r   r   r   r   s         r   +_configure_placement_group_based_on_contextr     s    P /:::   
 )## 	5,2244O	I	%	%. 	59;;OO,2244O 1(..00o~66666  >>> # 
 Y(;=O	
 	
 	
 r   )r   rc   NNNr   )r   NNN)r   )1r   typingr   r   r   r   r!   ray._common.utilsr   r   ray._private.auto_init_hookr	   ray._private.client_mode_hookr
   r   ray._private.label_utilsr   ray._private.utilsr   ray._rayletr   ray.util.annotationsr   r   ray.util.scheduling_strategiesr   r    r   r#   r%   rS   rT   r=   rD   r   rR   r   rp   rw   r   ra   rz   r~   rl   r   r   r   r   r   r   r   r   <module>r      s    . . . . . . . . . . . . 



 Q Q Q Q Q Q Q Q 5 5 5 5 5 5 V V V V V V V V < < < < < < 2 2 2 2 2 2 ( ( ( ( ( ( 8 8 8 8 8 8 8 8 K K K K K K $ $ $  	= 	= 	= Q Q Q Q Q Q Q Qh Q'7 Q# QRV Q Q Q Q - $t*      "*.26G. G.$sEz"#G.G. G. sm	G.
 #3-G.  S#X/G. G. G. G.  G.T 
BN 
Bt 
B 
B 
B  
B 
c 
n 
 
 
  
0 
N 
N> 
NT 
N 
N 
N  
N +!Xn%= +! +! +! +!\
#
36
	
 
 
 
( "*.26*
 *
$sEz"#*
*
 sm*
 #3-	*

  S#X/*
 
*
 *
 *
 *
Z,tDe$45 , , , ,^4S#X;O    B  *
 
 
F 9BC C)-CC C 	C
 C >345C C C C C C Cr   