o
    Ni                     @  sH   d dl mZ d dlZd dlmZ d dlZd dlmZ G dd deZdS )    )annotationsN)OrderedDict)Modulec                      s   e Zd ZdZd$d% fddZdd	 Zd
d Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Z  ZS )&
BufferDictaq  
    Holds buffers in a dictionary.

    BufferDict can be indexed like a regular Python dictionary, but buffers it contains are properly registered, and
    will be visible by all Module methods. `torch.nn.BufferDict` is an **ordered** dictionary that respects

    * the order of insertion, and
    * in `torch.nn.BufferDict.update`, the order of the merged `OrderedDict` or another `torch.nn.BufferDict` (the
      argument to `torch.nn.BufferDict.update`).

    Note that `torch.nn.BufferDict.update` with other unordered mapping types (e.g., Python's plain `dict`) does not
    preserve the order of the merged mapping.

    Args:
        buffers (iterable, optional):
            a mapping (dictionary) of (string : `torch.Tensor`) or an iterable of key-value pairs of type (string,
            `torch.Tensor`)

    ```python
    class MyModule(nn.Module):
        def __init__(self):
            super().__init__()
            self.buffers = nn.BufferDict({"left": torch.randn(5, 10), "right": torch.randn(5, 10)})

        def forward(self, x, choice):
            x = self.buffers[choice].mm(x)
            return x
    ```
    NF
persistentboolc                   s*   t    || _|dur| | dS dS )z
        Args:
            buffers (`dict`):
                A mapping (dictionary) from string to `torch.Tensor`, or an iterable of key-value pairs of type
                (string, `torch.Tensor`).
        N)super__init__r   update)selfbuffersr   	__class__ L/home/ubuntu/.local/lib/python3.10/site-packages/peft/tuners/_buffer_dict.pyr	   2   s
   
zBufferDict.__init__c                 C  s
   | j | S N_buffersr   keyr   r   r   __getitem__?      
zBufferDict.__getitem__c                 C  s   | j ||| jd d S )N)r   )register_bufferr   )r   r   bufferr   r   r   __setitem__B   s   zBufferDict.__setitem__c                 C  s   | j |= d S r   r   r   r   r   r   __delitem__E   s   zBufferDict.__delitem__c                 C  s
   t | jS r   )lenr   r   r   r   r   __len__H   r   zBufferDict.__len__c                 C  s   t | j S r   )iterr   keysr   r   r   r   __iter__K   s   zBufferDict.__iter__c                 C  s
   || j v S r   r   r   r   r   r   __contains__N   r   zBufferDict.__contains__c                 C  s   | j   dS )z%Remove all items from the BufferDict.N)r   clearr   r   r   r   r#   Q   s   zBufferDict.clearc                 C  s   | | }| |= |S )zRemove key from the BufferDict and return its buffer.

        Args:
            key (`str`):
                Key to pop from the BufferDict
        r   )r   r   vr   r   r   popU   s   zBufferDict.popc                 C  
   | j  S )z*Return an iterable of the BufferDict keys.)r   r    r   r   r   r   r    `      
zBufferDict.keysc                 C  r&   )z5Return an iterable of the BufferDict key/value pairs.)r   itemsr   r   r   r   r(   d   r'   zBufferDict.itemsc                 C  r&   )z,Return an iterable of the BufferDict values.)r   valuesr   r   r   r   r)   h   r'   zBufferDict.valuesc                 C  s   t |tjjstdt|j t |ttfr&|	 D ]\}}|| |< qd	S t |tjj
r>t|	 D ]\}}|| |< q3d	S t|D ]:\}}t |tjjs\tdt| d t|j t|dksttdt| d tt| d |d | |d < qBd	S )
a	  
        Update the `torch.nn.BufferDict` with the key-value pairs from a mapping or an iterable, overwriting existing
        keys.

        Note:
            If `buffers` is an `OrderedDict`, a `torch.nn.BufferDict`, or an iterable of key-value pairs, the order of
            new elements in it is preserved.

        Args:
            buffers (iterable):
                a mapping (dictionary) from string to `torch.Tensor`, or an iterable of key-value pairs of type
                (string, `torch.Tensor`).
        zQBuffersDict.update should be called with an iterable of key/value pairs, but got z$BufferDict update sequence element #z should be Iterable; is   z has length z; 2 is required   r   N)
isinstancecollectionsabcIterable	TypeErrortype__name__r   r   r(   Mappingsorted	enumeratestrr   
ValueError)r   r   r   r   jpr   r   r   r
   l   sB   


zBufferDict.updatec           	      C  s   g }| j  D ]@\}}ddd | D }|jj}|dkr!dnd|  d|  d}d	t	| d
| | d}|
d| d |  qd|}|S )Nxc                 s  s    | ]}t |V  qd S r   )r6   ).0sizer   r   r   	<genexpr>   s    z(BufferDict.extra_repr.<locals>.<genexpr>cpu z ( )zBuffer containing: [z	 of size ]z  (z): 
)r   r(   joinr<   devicer1   upper
get_devicetorchtypenameappend)	r   child_lineskr9   size_strdevice_type
device_strparastrtmpstrr   r   r   
extra_repr   s   &
zBufferDict.extra_reprc                 C  s   t d)Nz BufferDict should not be called.)RuntimeError)r   inputr   r   r   __call__   s   zBufferDict.__call__)NF)r   r   )r2   
__module____qualname____doc__r	   r   r   r   r   r!   r"   r#   r%   r    r(   r)   r
   rR   rU   __classcell__r   r   r   r   r      s"    'r   )
__future__r   r-   r   rH   torch.nnr   r   r   r   r   r   <module>   s   	