o
    Ni-                     @   s  U d dl mZmZ d dlmZ d dlmZmZmZm	Z	m
Z
mZ d dlZd dlZd dlmZmZ ddlmZ G dd	 d	eZeejeeed
f  f Zeed< eeejf Zeed< eejeeed
f  f Zeed< G dd deZG dd deZde	eef defddZdej de!fddZ"dejdejdejfddZ#dedejfddZ$d ee% ddfd!d"Z&d#ejd$ej'dejfd%d&Z(d#ejd'ej dejfd(d)Z)ed*e*ej d+eejgejf de*ej fd,d-Z+ed*ed+eejgejf defd.d-Z+ed*ed+eejgejf defd/d-Z+d0d- Z+d*e	e*ej eef deej'ej f fd1d2Z,d ee% d3ee% dee*e% e*e% f fd4d5Z-d6ejd ee% dejfd7d8Z.d6ejd ee% dejfd9d:Z/d6ejd;e%deeje*e% f fd<d=Z0d6ejd>e*e% d;e%dejfd?d@Z1d[dBe%dCe!fdDdEZ2dBe%d>e*e% fdFdGZ3d6ejdBe%d>e*e% d e	ee%d
f e%f dejf
dHdIZ4de	eef dJe!dKej'dej def
dLdMZ5dNe%dOe%dPe%dQe%dee%e%f f
dRdSZ6dTejdUejdejfdVdWZ7	Xd\d*ede	eef d ee%e%f dejfdYdZZ8dS )]    )CallableSequence)partial)Any
NamedTupleProtocolUnioncastoverloadN)	TypeAliasUnpack   )Waveletc                   @   s,   e Zd ZU ejed< ejed< ejed< dS )WaveletDetailTuple2d
horizontalverticaldiagonalN)__name__
__module____qualname__torchTensor__annotations__ r   r   P/home/ubuntu/.local/lib/python3.10/site-packages/peft/tuners/waveft/waverec2d.pyr      s   
 

r   .WaveletCoeff2dWaveletDetailDictWaveletCoeffNdc                   @   s   e Zd ZU eed< ee ed< ee ed< ee ed< ee ed< eed< eed< eee ee ee ee f ed< d	efd
dZ	dS )r   namedec_lodec_hirec_lorec_hidec_lenrec_lenfilter_bankreturnc                 C   s
   t | jS N)lenr   )selfr   r   r   __len__,   s   
zWavelet.__len__N)
r   r   r   strr   r   floatinttupler*   r   r   r   r   r   "   s   
 $r   c                   @   sR   e Zd ZU ejed< ejed< ejed< ejed< ededejdd fdd	Z	d
S )WaveletTensorTupler   r    r!   r"   waveletdtyper&   c                 C   s>   | t j|j|dt j|j|dt j|j|dt j|j|dS )Nr1   )r   tensorr   r    r!   r"   )clsr0   r1   r   r   r   from_wavelet6   s   zWaveletTensorTuple.from_waveletN)
r   r   r   r   r   r   classmethodr   r1   r5   r   r   r   r   r/   0   s   
 



r/   r0   r&   c                 C   s   t | tr	t| S | S r'   )
isinstancer+   minimal_wavelet)r0   r   r   r   _as_wavelet@   s   
r9   r1   c                 C   s   | t jt jt jt jfv S r'   )r   float16bfloat16float32float64r2   r   r   r   _is_dtype_supportedG   s   r>   abc                 C   s@   t | dg}t |dg}t j|dd}t j|dd}|| S )N)dimr   )r   reshape	unsqueeze)r?   r@   a_flatb_flata_mulb_mulr   r   r   _outerK   s
   rI   arrayc                 C   s   t | tjs
td| S )NzEFirst element of coeffs must be the approximation coefficient tensor.)r7   r   r   
ValueError)rJ   r   r   r   _check_if_tensorS   s   rL   axesc                 C   s    t t| t | krtdd S )Nz#Cant transform the same axis twice.)r(   setrK   rM   r   r   r   _check_axes_argumentY   s   rP   r3   torch_devicec                 C      || j kr	td| S )Nz'coefficients must be on the same device)devicerK   )r3   rQ   r   r   r   _check_same_device^      
rT   torch_dtypec                 C   rR   )Nz%coefficients must have the same dtype)r1   rK   )r3   rV   r   r   r   _check_same_dtyped   rU   rW   coeffsfunctionc                 C      d S r'   r   rX   rY   r   r   r   _coeff_tree_mapj   s   r\   c                 C   rZ   r'   r   r[   r   r   r   r\   n      c                 C   rZ   r'   r   r[   r   r   r   r\   p   r]   c              	      s   | d }g }| dd  D ]I}t |tr+|t |d  |d  |d  qt |trA fdd| D }|| qt |tjrO| | qtdt	| |set | t
rb|gS |fS t |d tjrx|gtt
tj | S ttt
t t
t f |}|g|R S )Nr   r      c                    s   i | ]	\}}| |qS r   r   ).0keyvaluerY   r   r   
<dictcomp>y   s    z#_coeff_tree_map.<locals>.<dictcomp>zUnexpected input type )r7   r.   appendr   dictitemsr   r   rK   typelistr	   r   r   )rX   rY   approx
result_lstelementnew_dictcast_result_lstr   rb   r   r\   r   s"   
,
c                 C   sF   t | d }|j|j}}t| tt|d t| tt|d ||fS )Nr   )rQ   )rV   )rL   rS   r1   r\   r   rT   rW   )rX   crQ   rV   r   r   r   _check_same_device_dtype   s
   ro   
data_shapec                    s@   fdd D  t tt}t t fdd|}| fS )Nc                    s$   g | ]}|d k r|t   n|qS )r   )r(   )r_   r?   )rp   r   r   
<listcomp>   s   $ z(_get_transpose_order.<locals>.<listcomp>c                    s   |  vS r'   r   )r?   rO   r   r   <lambda>   s    z&_get_transpose_order.<locals>.<lambda>)rh   ranger(   filter)rM   rp   all_axesremove_transformedr   )rM   rp   r   _get_transpose_order   s   rw   datac                 C   s,   t | t|t| j\}}t| || S r'   )rP   rw   rh   shaper   permute)rx   rM   frontbackr   r   r   
_swap_axes   s   r}   c                 C   s@   t | t|t| j\}}tt||  }t| |S r'   )	rP   rw   rh   ry   r   argsortr3   tolistrz   )rx   rM   r{   r|   restore_sortedr   r   r   _undo_swap_axes   s   r   keep_noc              	   C   s>   t | j}t| tt|d |  g|| d   |fS r'   )rh   ry   r   rC   r-   npprod)rx   r   dshaper   r   r   
_fold_axes   s   
4r   dsc                 C   s*   t | |d |  t| j| d   S r'   )r   rC   rh   ry   )rx   r   r   r   r   r   _unfold_axes   s   *r   Fndimadd_channel_dimc                    s  t |tr|f}t| d j}t|std| d dkr#tdt|tt  dkrJt| kr?t  d  dt	t
|d}t| |} t| d j}t| k r_td  d	t| krmt| d
d } nt| d kr~t|  fdd} |rt| dd } | |fS )Nr   zInput dtype z not supported%Number of dimensions must be positiveD transforms work with  axes.rO   	At least  input dimensions required.c                 S   
   |  dS Nr   rD   xr   r   r   rr         
 z$_preprocess_coeffs.<locals>.<lambda>r   c                    s   t |  d S r   )r   )tr   r   r   rr      s    c                 S   r   )Nr   r   r   r   r   r   rr      r   )r7   r-   rL   r1   r>   rK   r.   rs   r(   r   r}   r\   rh   ry   )rX   r   rM   r   rV   swap_fnr   r   r   r   _preprocess_coeffs   s,   

r   c                 C   s   t |tr|f}|dkrtdt||k rtd| dt||kr,t| dd } nt||d kr@tt||d}t| |} t|tt| dkrgt||kr\t| d	| d
tt	|d}t| |} | S )Nr   r   r   r   c                 S   r   r   )squeezer   r   r   r   rr      r   z%_postprocess_coeffs.<locals>.<lambda>r   )r   r   r   r   rO   )
r7   r-   rK   r(   r\   r   r   r.   rs   r   )rX   r   r   rM   unfold_axes_fnundo_swap_fnr   r   r   _postprocess_coeffs   s"   


r   c                 C   s   t | g|||dd S )N)rX   r   r   rM   r   )r   )rx   r   r   rM   r   r   r   _postprocess_tensor   s   r   fliprS   c              	   C   s   t | } |r+ttj| j||dtj| j||dtj| j||dtj| j||d}|S tj| |d}t|j	||j	||j	||j	|}|S )N)rS   r1   r2   )
r9   r/   r   r3   r!   r"   r   r    r5   to)r0   r   rS   r1   filtersr   r   r   _get_filter_tensors   s"   



r   
tensor_len	coeff_lenpadrpadlc                 C   s@   d| |  dkr|d7 }||fS d| |  dkrt d||fS )Nr^   r   r   zincorrect padding)rK   )r   r   r   r   r   r   r   !_adjust_padding_at_reconstruction   s   r   lohic                 C   sJ   t | | }t || }t | |}t ||}t||||gd}|d}|S )Nr   r   )rI   r   stackrD   )r   r   lllhhlhhfiltr   r   r   _construct_2d_filt  s   




r   rA   c                 C   s  t | d|d\} }t| \}}t|d||d\}}}}|jd }	t||d}
| d }t| dd  D ]\}}t|trAt|d	krKt	d
t
| d|j}|D ]}|j|kr[t	dqP|\}}}t||||gd}tjjj||
ddd}d|	 d	 d }d|	 d	 d }d|	 d	 d }d|	 d	 d }|t| d k rt|jd | |d  d jd ||\}}t|jd | |d  d jd ||\}}|dkr|d|d d d f }|dkr|dd | d d f }|dkr|d|d f }|dkr|dd | f }q2t|d||d}|S )Nr^   )r   rM   F)r   rS   r1   rA   )r   r   r   r      z$Unexpected detail coefficient type: z. Must be a 3-tuple.z7All coefficients on each level must have the same shape)strider   .)r   r   rM   )r   ro   r   ry   r   	enumerater7   r.   r(   rK   rg   r   r   nn
functionalconv_transpose2dr   r   r   )rX   r0   rM   r   rQ   rV   _r!   r"   filt_lenrec_filtres_llc_poscoeff_tuple
curr_shapecoeffres_lhres_hlres_hhr   r   padtpadbr   r   r   	waverec2d  sN   


  
r   )F)r   )9collections.abcr   r   	functoolsr   typingr   r   r   r   r	   r
   numpyr   r   typing_extensionsr   r   r0   r   r8   r   r.   r   r   r   re   r+   r   r   r/   r9   r1   boolr>   rI   rL   r-   rP   rS   rT   rW   rh   r\   ro   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s    ""&&
.
&"


&

