
Xc           @` sb  d  d l  m Z m Z 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 Z d  d l m Z e j j d d d g  Z e j d  Z e j e j k r e j e j  n  e j   Z d	   Z e
 d e d
   Z d d  Z e Z d   Z d   Z  e!   Z" e" d d d d  Z# d   Z$ d e! f d     YZ% d S(   i    (   t   absolute_importt   print_functiont   divisionN(   t   contextmanager(   t   configi  i   i   s   theano.gof.compilelockc           C` s$   t  d d d d d d  t   d S(   s>   
    Delete the compilation lock if someone else has it.

    t   min_waiti    t   max_waitgMbP?t   timeoutN(   t   get_lockt   release_lock(    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt   force_unlock   s    c         k` s)   t  d |  |  d  V| s% t   n  d  S(   Nt   lock_dir(   R   R	   (   R   t	   keep_lockt   kw(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt   lock_ctx%   s    c         K` s  |  d
 k r' t j j t j d  }  n  t t d  sx d t _ t t d  sZ t	 t _
 n  |  t _ t t j  t _ nB |  t j k r t j d k s t  |  t _ t t j  t _ n  t j
 rt j d k r
t t j |  t j t j t j  t j   t _ qt j d
 k rEx t j d k r5t   qWt d   n  t j   } | t j t j j d k rt j j t j d  } t j d t |   t |  | t _ qn  t j d	 7_ d
 S(   s   
    Obtain lock on compilation directory.

    Parameters
    ----------
    kw
        Additional arguments to be forwarded to the `lock` function when
        acquiring the lock.

    Notes
    -----
    We can lock only on 1 directory at a time.

    R   t   n_locki    t   lock_is_enabledsU   For some unknow reason, the lock was already taken, but no start time was registered.i   t   locks   Refreshing lock %si   N(   t   Nonet   ost   patht   joinR   t
   compiledirt   hasattrR   R   t   TrueR   R   t   Unlockert   unlockert   AssertionErrorR   t   atexitt   registert   unlockt   timet
   start_timeR	   t	   Exceptiont   compileR   t   _loggert   infot   strt   refresh_lock(   R   R   t   nowt   lockpath(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt	   _get_lock0   s8    				
c           C` s_   t  j d 8_ t  j d k s$ t  t  j r[ t  j d k r[ d t  _ t  j j d t  n  d S(   s1   
    Release lock on compilation directory.

    i   i    t   forceN(	   R   R   R   R   R   R    R   R   t   False(    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyR	   q   s
    	c         C` s   |  t  _ d S(   s0  
    Enable or disable the lock on the compilation directory (which is enabled
    by default). Disabling may make compilation slightly faster (but is not
    recommended for parallel execution).

    Parameters
    ----------
    use_lock : bool
        Whether to use the compilation lock or not.

    N(   R   R   (   t   use_lock(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt   set_lock_status~   s    i   c         C` s  | d k r t j j } n  | d k r4 | d } n  | t k rO t j j } n  t j j |   } t j j	 |  s y t j
 |  Wq t k
 r t j d  q Xn  t j j	 |  s t  t j j |  d  } t j   } | d k } d }	 d }
 xt ryWd } t j   } t } xt j j	 |   ry t |   } | j   d j   } Wd QXy | j d  d } Wn t k
 rd } n X| t k ry' t j t | j d  d  d  Wqt k
 rt } qt k
 rqXn  Wn t k
 rd } n X| r^| sEd | j d  d } t j d	 | |  n  t j  j! d
 t  q n  | | k r| d k	 rt j   | | k r| s| d k rd } n d | j d  d } t j d | |  n  t j  j! d
 t  q qn | } t j   } | d k } | r|
 d k r| d k r6d } n d | j d  d } t j" d | |  t j" d |   | d k rt } qn  |
 d 7}
 t j t# j$ | |   q Wy t j% |   Wn0 t k
 r|	 d 7}	 |	 d k  rw q  n Xt j j	 |   st  t& |  } t |   } | j   d j   } Wd QX| | k rTw n d SWq t k
 r} t j d t' |  |  |	 d 7}	 |	 d k r  n  t j t# j$ | |   q q Xq Wd S(   s#  
    Obtain lock access by creating a given temporary directory (whose base will
    be created if needed, but will not be deleted after the lock is removed).
    If access is refused by the same lock owner during more than 'timeout'
    seconds, then the current lock is overridden. If timeout is None, then no
    timeout is performed.

    The lock is performed by creating a 'lock' file in 'tmp_dir' that contains
    a unique id identifying the owner of the lock (the process id, followed by
    a random string).

    When there is already a lock, the process sleeps for a random amount of
    time between min_wait and max_wait seconds before trying again.

    If 'verbosity' is >= 1, then a message will be displayed when we need to
    wait for the lock. If it is set to a value >1, then this message will be
    displayed each time we re-check for the presence of the lock. Otherwise it
    is displayed only when we notice the lock's owner has changed.

    Parameters
    ----------
    tmp_dir : str
        Lock directory that will be created when acquiring the lock.
    timeout : int or None
        Time (in seconds) to wait before replacing an existing lock (default
        config 'compile.timeout').
    min_wait: int
        Minimum time (in seconds) to wait before trying again to get the lock
        (default config 'compile.wait').
    max_wait: int
        Maximum time (in seconds) to wait before trying again to get the lock
        (default 2 * min_wait).
    verbosity : int
        Amount of feedback displayed to screen (default 1).

    i   R   i    t   no_ownerNt   _t   failures   process '%s's7   Overriding existing lock by dead %s (I am process '%s')R*   s   unknown processs2   Overriding existing lock by %s (I am process '%s')s3   Waiting for existing lock by %s (I am process '%s')s'   To manually release the lock, delete %si   i
   s   Something wrong happened: %s %s(    ((   R   R   R"   t   waitt   notsetR   R   R   t   dirnamet   isdirt   makedirst   OSErrorR   t   sleepR   R   t   getpidR   R+   t   opent	   readlinest   stript   splitt
   IndexErrort   hostnamet   killt   intt   AttributeErrorR!   R#   t   warningR   R   R   R$   t   randomt   uniformt   mkdirR&   t   type(   t   tmp_dirR   R   R   t	   verbosityt	   base_lockt	   lock_filet   my_pidt
   no_displayt   nb_errort   nb_waitt
   last_ownert
   time_startt
   other_deadt   ft
   read_ownert
   other_hostt   msgt	   unique_idt   ownert   e(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyR      s    %	
'	
						
	


c      	   C` s   d t  j   d j g  t d  D] } t t j d d   ^ q  t f } y- t |  d   } | j	 | d  Wd QXWn> t
 k
 r x t j d k r t   q Wt j d	    n X| S(
   s   
    'Refresh' an existing lock by re-writing the file containing the owner's
    unique id, using a new (randomly generated) id, which is also returned.

    s   %s_%s_%st    i
   i    i	   t   ws   
NsN   Refreshing lock failed, we release the lock before raising again the exception(   R   R8   R   t   rangeR%   RC   t   randintR>   R9   t   writeR!   R   R   R	   R#   t   warn(   RJ   t   iRV   t
   lock_write(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyR&   8  s    	7
R   c           B` s#   e  Z d  Z d   Z e d  Z RS(   s   
    Class wrapper around release mechanism so that the lock is automatically
    released when the program exits (even when crashing or being interrupted),
    using the __del__ class method.

    c         C` s   | |  _  d  S(   N(   RG   (   t   selfRG   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt   __init__Z  s    c         C` s   t  j j |  j d  } | s yo t |  ] } | j   d j   } | j d  \ } } } | t t  j	    k s | t
 k r d SWd QXWq t k
 r q Xn  y t  j |  Wn t k
 r n Xy t  j |  j  Wn t k
 r n Xd S(   sS  
        Remove current lock.

        This function does not crash if it is unable to properly
        delete the lock file and directory. The reason is that it
        should be allowed for multiple jobs running in parallel to
        unlock the same directory at the same time (e.g. when reaching
        their timeout limit).

        R   i    R/   N(   R   R   R   RG   R9   R:   R;   R<   R%   R8   R>   R!   t   removet   rmdir(   Ra   R*   RJ   RR   RW   t   pidR/   t   hname(    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyR   ]  s$    $(   t   __name__t
   __module__t   __doc__Rb   R+   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyR   R  s   	(&   t
   __future__R    R   R   R   R   t   socketR   t   loggingt
   contextlibR   t   numpyt   npt   theanoR   RC   t   RandomStatet	   getLoggerR#   t   levelt   NOTSETt   setLevelt   INFOt   gethostnameR>   R
   R   R+   R   R)   R   R	   R-   t   objectR2   R   R&   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/gof/compilelock.pyt   <module>   s0   		
>				