o
    Ih~                     @   s@   d dl Z d dlZd dlmZ d dlmZ dgZG dd dZdS )    N)wraps)BaseSparsifierBaseSchedulerc                   @   sZ   e Zd ZdddZdd Zdd Zd	d
 Zdd ZdddZdd Z	dddZ
dd ZdS )r   Fc                 C   sz   t |tstt|j d|| _dd |jD | _|| _dd }|| jj	| j_	d| j_
d| _
|| _d| _| 	  d S )Nz6 is not an instance of torch.ao.pruning.BaseSparsifierc                 S      g | ]}|d  qS sparsity_level .0groupr	   r	   ]/var/www/vscode/kcb/lib/python3.10/site-packages/torch/ao/pruning/scheduler/base_scheduler.py
<listcomp>       z*BaseScheduler.__init__.<locals>.<listcomp>c                    sN   t | ddr| S t| j| j j ~ t fdd}d|_|S )N_with_counterFc                     s.    }| j d7  _ | }|| i |S )N   )_step_count__get__)argskwargsinstancewrappedclsfuncinstance_refr	   r   wrapper+   s   z=BaseScheduler.__init__.<locals>.with_counter.<locals>.wrapperT)getattrweakrefref__self____func__	__class__r   r   )methodr   r	   r   r   with_counter   s   z,BaseScheduler.__init__.<locals>.with_counterr   F)
isinstancer   	TypeErrortype__name__
sparsifiergroupsbase_sl
last_epochstepr   verbose_get_sl_called_within_step)selfr)   r,   r.   r$   r	   r	   r   __init__   s   
zBaseScheduler.__init__c                 C   s   dd | j  D S )zReturns the state of the scheduler as a :class:`dict`.

        It contains an entry for every variable in self.__dict__ which
        is not the sparsifier.
        c                 S   s   i | ]\}}|d kr||qS )r)   r	   )r   keyvaluer	   r	   r   
<dictcomp>G   s    z,BaseScheduler.state_dict.<locals>.<dictcomp>)__dict__itemsr0   r	   r	   r   
state_dictA   s   zBaseScheduler.state_dictc                 C   s   | j | dS )zLoads the schedulers state.

        Args:
            state_dict (dict): scheduler state. Should be an object returned
                from a call to :meth:`state_dict`.
        N)r5   update)r0   r8   r	   r	   r   load_state_dictK   s   zBaseScheduler.load_state_dictc                 C   s   | j S )z9Return last computed sparsity level by current scheduler.)_last_slr7   r	   r	   r   get_last_slT   s   zBaseScheduler.get_last_slc                 C   s   | j std t)NzUTo get the last sparsity level computed by the scheduler, please use `get_last_sl()`.)r/   warningswarnNotImplementedErrorr7   r	   r	   r   get_slX   s
   zBaseScheduler.get_slNc                 C   sP   |r&|du rt d| d|dd dS t d|dd| d|dd dS dS )	z#Display the current sparsity level.Nz"Adjusting sparsity level of group z to z.4e.zEpoch 5dz$: adjusting sparsity level of group )print)r0   
is_verboser   slepochr	   r	   r   print_slc   s   zBaseScheduler.print_slc                 C   sD   | j jd }|d7 }|d| j d7 }|d| j d7 }|d7 }|S )Nz (
zSparsifier z    base_sl: ))r"   r(   r)   r+   )r0   format_stringr	   r	   r   __repr__m   s   zBaseScheduler.__repr__c                 C   s   | j dkrt| jjdstdt n| jj dk rtdt |  j d7  _ G dd d}||  |  jd7  _|  }W d    n1 sGw   Y  t	t
| jj|D ]\}}|\}}||d< | | j||| qUdd	 | jjD | _d
| j_d S )Nr   r   zSeems like `sparsifier.step()` has been overridden after sparsity scheduler initialization. Please, make sure to call `sparsifier.step()` before `scheduler.step()`.zDetected call of `scheduler.step()` before `sparsifier.step()`. You have to make sure you run the sparsifier.step() BEFORE any calls to the scheduler.step().c                   @   s$   e Zd Zdd Zdd Zdd ZdS )z/BaseScheduler.step.<locals>._enable_get_sl_callc                 S   s
   || _ d S N)o)r0   rM   r	   r	   r   r1      s   
z8BaseScheduler.step.<locals>._enable_get_sl_call.__init__c                 S   s   d| j _| S )NTrM   r/   r7   r	   r	   r   	__enter__   s   z9BaseScheduler.step.<locals>._enable_get_sl_call.__enter__c                 S   s   d| j _d S )NFrN   )r0   r'   r3   	tracebackr	   r	   r   __exit__   s   z8BaseScheduler.step.<locals>._enable_get_sl_call.__exit__N)r(   
__module____qualname__r1   rO   rQ   r	   r	   r	   r   _enable_get_sl_call   s    rT   r   c                 S   r   r   r	   r
   r	   r	   r   r      r   z&BaseScheduler.step.<locals>.<listcomp>T)r   hasattrr)   r-   r=   r>   UserWarningr,   r@   	enumeratezipr*   rG   r.   r;   enable_mask_update)r0   rF   rT   valuesidataparam_grouprE   r	   r	   r   r-   u   s.   


zBaseScheduler.stepc                 C   sP   t | jj}t|ttfs|g| S t ||kr$td| dt | t|S )zPUtility that extends it to the same length as the .groups, ensuring it is a listzExpected variable of length z
, but got )lenr)   r*   r%   listtuple
ValueError)r0   varnr	   r	   r   _make_sure_a_list   s   
zBaseScheduler._make_sure_a_list)r   FrL   )r(   rR   rS   r1   r8   r:   r<   r@   rG   rK   r-   rd   r	   r	   r	   r   r      s    
3
	


-)r=   r   	functoolsr   +torch.ao.pruning.sparsifier.base_sparsifierr   __all__r   r	   r	   r	   r   <module>   s   