a
    ==ic  ã                   @   sV   d dl mZ d dlZd dlZe e¡ZG dd„ deƒZeƒ Z	dd„ Z
ejdd„ ƒZdS )	é    )ÚscopeNc                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚParameterSharingContextzc
    This class manages scope driven way of parameter sharing across different
    NameScopes.
    c                 C   s   i | _ g | _d S ©N)Ú_scope_overridesÚ	_contexts)Úself© r   úy/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/modeling/parameter_sharing.pyÚ__init__   s    z ParameterSharingContext.__init__c                 C   s‚   |}d}|  tj¡}d}t|ƒD ].\}}|| tj }|| jv r | j| }|}q ||kr\|S |  |¡tj ||d d… ¡ S dS )aH  
        Recursively resolves all scope overrides, i.e multiple steps of
        override can be used.

        For example, if one provides following scope overrides:
        {'scope_b': 'scope_a'} and within 'scope_b' - {'shared_child': ''},
        then name 'w' will get resolved to the following blobs depending on the
        namescope:
          a. 'scope_a' -> 'scope_a/w'
          b. 'scope_b' -> 'scope_a/w'
          c. 'scope_c' -> 'scope_c/w'
          d. 'scope_b/shared_child' -> 'scope_a/w'
          d. 'scope_b/unshared_child' -> 'scope_a/unshared_child/w'
        r   Ú é   N)Úsplitr   Ú_NAMESCOPE_SEPARATORÚ	enumerater   Ú_resolve_scope_overridesÚjoin)r   Úcandidate_scopeÚ
best_scopeZbest_scope_idxZ
sub_scopesZ	cur_scopeÚidxZ	sub_scoper   r   r	   r      s     

ÿÿz0ParameterSharingContext._resolve_scope_overridesc                 C   s4   t  ¡ }|  |¡}||kr,t d ||¡¡ || S )Nz$Overwriting scope {0} with scope {1})r   ÚCurrentNameScoper   ÚloggerÚinfoÚformat)r   Únamer   r   r   r   r	   Úget_parameter_name8   s    
ÿz*ParameterSharingContext.get_parameter_namec                 C   s   | j  |¡ | j |¡ d S r   )r   Úappendr   Úupdate)r   Úshared_scopesr   r   r	   Úadd_scope_overridesA   s    z+ParameterSharingContext.add_scope_overridesc                 C   s>   t | jƒdksJ ‚| j ¡  i | _| jD ]}| j |¡ q(d S )Nr   )Úlenr   Úpopr   r   )r   Úxr   r   r	   r    E   s
    

zParameterSharingContext.popN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r   r   r   r    r   r   r   r	   r      s    	r   c                 C   s$   | r| d t jkr| t j S | S d S )Néÿÿÿÿ)r   r   )Z	namescoper   r   r	   Ú_normalize_namescopeP   s    
r'   c                 c   sš   t | tƒsJ ‚i }t ¡ }|  ¡ D ]J\}}| |¡rDJ d ||¡ƒ‚|| }|| }t|ƒ}t|ƒ}|||< q"zt 	|¡ dV  W t 
¡  n
t 
¡  0 dS )až  
    Helper function for sharing scopes.
    All the parameters within the shared_scopes, will be remapped with the
    respect of CurrentNamescope()

    I.e. if one calls ParameterSharing with {'scope_b': 'scope_'a'}, from the
    scope 'some_global_scope', it'll effectively mean, that all parameters from
    'some_global_scope/scope_b' will shared with the parameters from
    'some_global_scope/scope_a'
    z:Illegal override for parameter sharing. {} is prefix of {}N)Ú
isinstanceÚdictr   r   ÚitemsÚ
startswithr   r'   Úparameter_sharing_contextr   r    )r   Zshared_scope_overridesZcurrent_scopeÚkÚvr   r   r	   ÚParameterSharingW   s$    ÿÿ

r/   )Zcaffe2.pythonr   Ú
contextlibÚloggingÚ	getLoggerr"   r   Úobjectr   r,   r'   Úcontextmanagerr/   r   r   r   r	   Ú<module>   s   
?