U
    yh                     @   s@   d dl mZ d dlmZ d dlZd dlZdgZG dd dZdS )    )BaseSparsifier)wrapsN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   s   g | ]}|d  qS sparsity_level .0groupr   r   [/var/www/html/venv/lib/python3.8/site-packages/torch/ao/pruning/scheduler/base_scheduler.py
<listcomp>   s     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  _ | }|| |S )N   )_step_count__get__)argskwargsinstancewrappedclsfuncZ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>E   s       z,BaseScheduler.state_dict.<locals>.<dictcomp>)__dict__itemsr-   r   r   r   
state_dict?   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)r2   update)r-   r5   r   r   r   load_state_dictG   s    zBaseScheduler.load_state_dictc                 C   s   | j S )zC Return last computed sparsity level by current scheduler.
        )_last_slr4   r   r   r   get_last_slP   s    zBaseScheduler.get_last_slc                 C   s   | j std td S )NzUTo get the last sparsity level computed by the scheduler, please use `get_last_sl()`.)r,   warningswarnNotImplementedErrorr4   r   r   r   get_slU   s
    zBaseScheduler.get_slNc                 C   sJ   |rF|dkr&t d| d|dd n t d|dd| d|dd dS )	z,Display the current sparsity level.
        Nz"Adjusting sparsity level of group z to z.4e.zEpoch Z5dz$: adjusting sparsity level of group )print)r-   Z
is_verboser   slepochr   r   r   print_sl_   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(   )r-   format_stringr   r   r   __repr__h   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 5 Q R X t	t
| jj|D ]*\}}|\}}||d< | | j||| qd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)r-   rG   r   r   r   r.      s    z8BaseScheduler.step.<locals>._enable_get_sl_call.__init__c                 S   s   d| j _| S )NTrG   r,   r4   r   r   r   	__enter__   s    z9BaseScheduler.step.<locals>._enable_get_sl_call.__enter__c                 S   s   d| j _d S )NFrH   )r-   r$   r0   	tracebackr   r   r   __exit__   s    z8BaseScheduler.step.<locals>._enable_get_sl_call.__exit__N)r%   
__module____qualname__r.   rI   rK   r   r   r   r   _enable_get_sl_call   s   rN   r   c                 S   s   g | ]}|d  qS r   r   r	   r   r   r   r      s     z&BaseScheduler.step.<locals>.<listcomp>T)r   hasattrr&   r*   r:   r;   UserWarningr)   r=   	enumeratezipr'   rB   r+   r8   Zenable_mask_update)r-   rA   rN   valuesidataZparam_groupr@   r   r   r   r*   p   s(    

zBaseScheduler.stepc                 C   sT   t | jj}t|ttfs$|g| S t ||krHtd| dt | t|S dS )zPUtility that extends it to the same length as the .groups, ensuring it is a listzExpected variable of length z
, but got N)lenr&   r'   r"   listtuple
ValueError)r-   varnr   r   r   _make_sure_a_list   s    
zBaseScheduler._make_sure_a_list)r   F)N)N)r%   rL   rM   r.   r5   r7   r9   r=   rB   rF   r*   r\   r   r   r   r   r      s   
2	

	
()Ztorch.ao.pruningr   	functoolsr   r:   r   __all__r   r   r   r   r   <module>   s
   