o
    rri                     @   s   d dl mZ d dlm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 d dlmZ dd Zde	jd	eje	jef fd
dZdeje defddZd$defddZd%dedefddZed&defddZd'dedefd d!ZG d"d# d#ZdS )(    )defaultdict)contextmanagerN)
functional)Subsetc                 C   s   | j ^ }}t|| }|d | | }t| d|| f} t|  }|d dks/J d|dd |dg }| g ||||S )zGiven input of size [*OT, T], output Tensor of size [*OT, F, K]
    with K the kernel size, by extracting frames with the given stride.

    This will pad the input so that `F = ceil(T / K)`.

    see https://github.com/pytorch/pytorch/issues/60466
       r   zdata should be contiguousN)shapemathceilFpadliststride
as_strided)akernel_sizer   r   lengthn_frames
tgt_lengthstrides r   @/home/ubuntu/.local/lib/python3.10/site-packages/demucs/utils.pyunfold   s   r   tensor	referencec                 C   sh   t |tjr|d}n|}| d| }|dk r!td| d|r2| d|d ||d   f } | S )z
    Center trim `tensor` with respect to `reference`, along the last dimension.
    `reference` can also be a number, representing the length to trim to.
    If the size difference != 0 mod 2, the extra sample is removed on the right side.
    r   r   z/tensor must be larger than reference. Delta is ..   )
isinstancetorchTensorsize
ValueError)r   r   ref_sizedeltar   r   r   center_trim%   s   r$   historynamec                 C   s8   g }| D ]}|}| dD ]}|| }q|| q|S )Nr   )splitappend)r%   r&   outmetricsmetricpartr   r   r   pull_metric8   s   
r-   r   betac                    s4   t tt tddtdtdtf fdd}|S )	a  
    Exponential Moving Average callback.
    Returns a single function that can be called to repeatidly update the EMA
    with a dict of metrics. The callback will return
    the new averaged dict of metrics.

    Note that for `beta=1`, this is just plain averaging.
    r   r*   weightreturnc                    sX   |   D ]\}}|   |t|  |< |   | |< qfdd  D S )Nc                    s   i | ]\}}|| |  qS r   r   ).0keytot)fixr   r   
<dictcomp>S   s    z(EMA.<locals>._update.<locals>.<dictcomp>)itemsfloat)r*   r/   r2   valuer.   r4   totalr   r   _updateN   s   zEMA.<locals>._updateNr   )r   r7   dict)r.   r;   r   r9   r   EMAB   s   	 r>   Bnumsuffixc                 C   s>   dD ]}t | dk rd| ||f   S | d } qd| d|f S )zk
    Given `num` bytes, return human readable size.
    Taken from https://stackoverflow.com/a/1094933
    ) KiMiGiTiPiEiZig      @z	%3.1f%s%sz%.1f%s%sYi)abs)r@   rA   unitr   r   r   
sizeof_fmtW   s
   
rM   Tcountc              
   c   sn    g }z%t | D ]}|tjddj q|V  W |r%|D ]	}t| qd S d S |r5|D ]}t| q-w w )NF)delete)ranger(   tempfileNamedTemporaryFiler&   osunlink)rN   rO   names_r&   r   r   r   temp_filenamesc   s    rW   *   max_samplesseedc                 C   sF   |t | kr| S t |}tjt | |d}t| |d |  S )N)	generator)lenr   	Generatormanual_seedrandpermr   tolist)datasetrY   rZ   r[   permr   r   r   random_subsetp   s
   rc   c                   @   s<   e Zd ZG dd dZdddZdd Zdd	 Zd
d ZdS )DummyPoolExecutorc                   @   s   e Zd Zdd Zdd ZdS )zDummyPoolExecutor.DummyResultc                 O   s   || _ || _|| _d S Nfuncargskwargsselfrg   rh   ri   r   r   r   __init__{   s   
z&DummyPoolExecutor.DummyResult.__init__c                 C   s   | j | ji | jS re   rf   rk   r   r   r   result   s   z$DummyPoolExecutor.DummyResult.resultN)__name__
__module____qualname__rl   rn   r   r   r   r   DummyResultz   s    rr   r   c                 C      d S re   r   )rk   workersr   r   r   rl         zDummyPoolExecutor.__init__c                 O   s   t j|g|R i |S re   )rd   rr   rj   r   r   r   submit   s   zDummyPoolExecutor.submitc                 C   s   | S re   r   rm   r   r   r   	__enter__   ru   zDummyPoolExecutor.__enter__c                 C   rs   re   r   )rk   exc_type	exc_valueexc_tbr   r   r   __exit__   ru   zDummyPoolExecutor.__exit__N)r   )ro   rp   rq   rr   rl   rv   rw   r{   r   r   r   r   rd   y   s    
	rd   r<   )r?   )T)rX   )collectionsr   
contextlibr   r	   rS   rQ   typingtpr   torch.nnr   r   torch.utils.datar   r   r   Unionintr$   Listr=   strr-   r7   r>   rM   rW   rc   rd   r   r   r   r   <module>   s$    
	