o
    پi&                     @   s   d dl Z d dlmZ d dlmZmZmZ d dlmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ edd	G d
d dZG dd dZdS )    N)OrderedDict)	dataclassfieldfields)DictListOptionalUnion)uuid4)ConcurrentCounter)RWLockT)frozenc                   @   sn   e Zd ZU dZedd dZeed< dZe	e ed< dZ
e	e ed< dZe	e ed	< d
d ZdefddZdS )LoRARefa)  
    Reference record for a LoRA model.

    This object guarantees a unique ``lora_id`` and may include ``lora_name``, ``lora_path``, and ``pinned``.
    The ID eliminates conflicts from reused LoRA names or paths and can be used to generate deterministic cache
    keys (e.g., radix cache).
    c                   C   s   t  jS N)r
   hex r   r   Q/home/ubuntu/.local/lib/python3.10/site-packages/sglang/srt/lora/lora_registry.py<lambda>$   s    zLoRARef.<lambda>)default_factorylora_idN	lora_name	lora_pathpinnedc                 C   s   | j d u r	tdd S )Nzlora_id cannot be None)r   
ValueErrorselfr   r   r   __post_init__)   s   
zLoRARef.__post_init__returnc                    s2    fddt  D } jj dd| dS )Nc                    s0   g | ]}t  |j d ur|j d qS )N=)getattrname).0fr   valuer   r   
<listcomp>.   s
    z#LoRARef.__str__.<locals>.<listcomp>(z, ))r   	__class____name__join)r   partsr   r#   r   __str__-   s   zLoRARef.__str__)r)   
__module____qualname____doc__r   r   str__annotations__r   r   r   r   boolr   r,   r   r   r   r   r      s   
 r   c                   @   s   e Zd ZdZddeee  fddZdefddZd	e	d
e	fddZ
d	ee	ee	 f d
ee	ee	 f fddZdee	ee	 f fddZde	fddZd	ee	 fddZd ddZdefddZed
efddZd
ee	ef fddZdS )!LoRARegistrya  
    The central registry to keep track of available LoRA adapters and ongoing LoRA requests.

    The `LoRARegistry` resides in the tokenizer manager process and acts as the single source of truth for all
    available LoRA adapters. It supports concurrent inference and dynamic adapter updates through a two-phase
    update / eventual consistency model between the tokenizer manager process and the scheduler processes.
    N
lora_pathsc                 C   sX   |d u st dd |D sJ dt | _t | _i | _|r(|D ]	}| | q d S d S )Nc                 s   s    | ]}t |tV  qd S r   )
isinstancer   )r!   lorar   r   r   	<genexpr>@   s    

z(LoRARegistry.__init__.<locals>.<genexpr>zserver_args.lora_paths should have been normalized to LoRARef objects during server initialization. Please file an issue if you see this error.)allr   _registry_lockr   	_registry	_counters_register_adapter)r   r4   lora_refr   r   r   __init__?   s   

zLoRARegistry.__init__r=   c              	      sN   | j j4 I dH  | | W d  I dH  dS 1 I dH s w   Y  dS )z
        Register a new LoRARef object in the registry.

        Args:
            lora_ref (LoRARef): The LoRARef object to register.
        N)r9   writer_lockr<   r   r=   r   r   r   registerX   s   .zLoRARegistry.registerr   r   c              	      s   | j j4 I dH ) | j|d}|du r"td| d| j  | j|= W d  I dH  |jS 1 I dH s8w   Y  |jS )z
        Unregister a LoRARef object from the registry and returns the removed LoRA ID.

        Args:
            lora_name (str): The name of the LoRA model to unregister.
        NLoRA with name z does not exist. Loaded LoRAs: )r9   r?   r:   getr   keysr   )r   r   r=   r   r   r   
unregisterb   s   
zLoRARegistry.unregisterc              	      s  dt dt ffdd t|t rAjj4 I dH   |}W d  I dH  n1 I dH s.w   Y  j| jddI dH  |S t|tr~jj4 I dH   fdd	|D }W d  I dH  n1 I dH shw   Y  tjfd
d	|D  I dH  |S t	d)z
        Queries registry for LoRA IDs based on LoRA names and start tracking the usage of the corresponding LoRA adapters
        by incrementing its counter.
        r    r   c                    sP   | d u rd S  j | d }|d u rtd|  d j   d j |  |jS )Nz6The following requested LoRA adapters are not loaded: z
Loaded adapters: .)r:   rC   r   rD   move_to_endr   )r    r=   r   r   r   _lookupy   s   z%LoRARegistry.acquire.<locals>._lookupNF
notify_allc                    s   g | ]} |qS r   r   )r!   r    )rH   r   r   r%      s    z(LoRARegistry.acquire.<locals>.<listcomp>c                    s&   g | ]}|d ur j | jddqS )NFrI   )r;   	incrementr!   idr   r   r   r%      s
    z7lora_name must be either a string or a list of strings.)
r0   r5   r9   r?   r;   rK   listasynciogather	TypeError)r   r   r   lora_idsr   )rH   r   r   acquires   s&   

(
(

zLoRARegistry.acquirer   c              	      s    j j4 I dH 5 t|tr j|  I dH  nt|tr/tj fdd|D  I dH  nt	dW d  I dH  dS 1 I dH sDw   Y  dS )zj
        Decrements the usage counter for a LoRA adapter, indicating that it is no longer in use.
        Nc                    s"   g | ]}|d ur j |  qS r   )r;   	decrementrL   r   r   r   r%      s
    z(LoRARegistry.release.<locals>.<listcomp>z5lora_id must be either a string or a list of strings.)
r9   reader_lockr5   r0   r;   rT   rN   rO   rP   rQ   r   r   r   r   r   release   s   



.zLoRARegistry.releasec                    sF   || j vs
J d|| jv sJ d| j|  I dH  | j|= dS )at  
        Waits until the usage counter for a LoRA adapter reaches zero, indicating that it is no longer in use.
        This is useful for ensuring that a LoRA adapter can be safely unloaded.

        This method itself is not synchronized, which is safe because it should only be called during LoRA unloading,
        which itself is guaranteed to be sequential.
        zTwait_for_unload should only be called after the LoRA adapter has been unregistered. zIThe LoRA ID should still have a counter if it has been registered before.N)r:   r;   wait_for_zerorV   r   r   r   wait_for_unload   s   	zLoRARegistry.wait_for_unloadc              	      sv   | j j4 I dH % g }|D ]}|| jv r| j| q|| q|W  d  I dH  S 1 I dH s4w   Y  dS )z^
        Returns all LoRA adapters in lora_name that are not found in self._registry.
        N)r9   r?   r:   rG   append)r   r   unregistered_lorasr    r   r   r   get_unregistered_loras   s   
0z#LoRARegistry.get_unregistered_lorasFc              	      s   | j j4 I dH < |stt| jdW  d  I dH  S | j D ]\}}|js8|  W  d  I dH  S q#	 W d  I dH  dS 1 I dH sKw   Y  dS )z
        Returns the least recently used LoRA adapter.
        If exclude_pinned is True, then return the LRU LoRA adapter that isn't pinned.
        N)r9   rU   nextiterr:   itemsr   )r   exclude_pinnedr   r=   r   r   r   lru_lora_name   s   0zLoRARegistry.lru_lora_namec                 C   sF   |j | jv rtd|j  d| j  || j|j < t | j|j< |S )zD
        Internal helper method to register a LoRA adapter.
        rB   z already exists. Loaded LoRAs: )r   r:   r   rD   r   r;   r   r@   r   r   r   r<      s   zLoRARegistry._register_adapterc                 C   
   t | jS )zQ
        Returns the total number of LoRA adapters currently registered.
        )lenr:   r   r   r   r   num_registered_loras   s   
z!LoRARegistry.num_registered_lorasc                 C   rb   )z
        Returns a dictionary of all registered LoRA adapters.

        Returns:
            Dict[str, LoRARef]: A dictionary mapping LoRA names to LoRARef objects.
        )dictr:   r   r   r   r   get_all_adapters   s   
zLoRARegistry.get_all_adaptersr   )F)r)   r-   r.   r/   r   r   r   r>   rA   r0   rE   r	   rS   rW   rY   setr\   ra   r<   propertyintrd   r   rf   r   r   r   r   r3   6   s    
*)
r3   )rO   collectionsr   dataclassesr   r   r   typingr   r   r   r	   uuidr
   sglang.srt.utilsr   sglang.srt.utils.aio_rwlockr   r   r3   r   r   r   r   <module>   s   