ó
àÆ÷Xc           @` s(  d  d l  m Z m Z m Z d  d l Z d  d l Z d  d l m Z d  d l m	 Z	 d  d l
 m Z m Z d  d l m Z d  d l m Z d e f d	 „  ƒ  YZ d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   i    (   t   absolute_importt   print_functiont   divisionN(   t   DefaultOrderedDict(   t
   OrderedSet(   t   StringIOt   integer_types(   t   opt(   t   configt   DBc           B` sh   e  Z d  „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 e j d	 „ Z RS(
   c         C` s<   t  |  d ƒ s5 t j d |  _ t j d c d 7<n  |  j S(   Nt   _optimizer_idxi    i   (   t   hasattrR   R
   (   t   self(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __hash__   s    c         C` s(   t  t ƒ |  _ t ƒ  |  _ d  |  _ d  S(   N(   R   R   t   __db__t   sett   _namest   Nonet   name(   R   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __init__   s    c         O` s2  t  | t t j t j f ƒ s0 t d | ƒ ‚ n  | |  j k rT t d | | ƒ ‚ n  | r… d | k sl t ‚ | d t	 k s§ t ‚ n" |  j
 d k	 r§ | |  j
 f } n  | | _
 | j
 |  j k rÞ t d | j
 | f ƒ ‚ n  t | g ƒ |  j | <|  j j | ƒ |  j | j j j | ƒ |  j | | Œ d S(   sÉ  

        Parameters
        ----------
        name : str
            Name of the optimizer.
        obj
            The optimizer to register.
        tags
            Tag name that allow to select the optimizer.
        kwargs
            If non empty, should contain only use_db_name_as_tag=False.
            By default, all optimizations registered in EquilibriumDB
            are selected when the EquilibriumDB name is used as a
            tag. We do not want this behavior for some optimizer like
            local_remove_all_assert. use_db_name_as_tag=False remove
            that behavior. This mean only the optimizer name and the
            tags specified will enable that optimization.

        s$   Object cannot be registered in OptDBsX   The name of the object cannot be an existing tag or the name of another existing object.t   use_db_name_as_tags¡   You can't register the same optimization
multiple time in a DB. Tryed to register "%s" again under the new name "%s".
 Use theano.gof.ProxyDB to work around thatN(   t
   isinstanceR	   R   t	   Optimizert   LocalOptimizert	   TypeErrorR   t
   ValueErrort   AssertionErrort   FalseR   R   R   R   t   addt	   __class__t   __name__t   add_tags(   R   R   t   objt   tagst   kwargs(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   register   s$    	c         G` s„   |  j  | } t | ƒ d k s% t ‚ | j ƒ  j ƒ  } xF | D]> } | |  j k rh t d | | ƒ ‚ n  |  j  | j | ƒ q> Wd  S(   Ni   s+   The tag of the object collides with a name.(   R   t   lenR   t   copyt   popR   R   R   (   R   R   R!   R    t   tag(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   I   s    c         G` s„   |  j  | } t | ƒ d k s% t ‚ | j ƒ  j ƒ  } xF | D]> } | |  j k rh t d | | ƒ ‚ n  |  j  | j | ƒ q> Wd  S(   Ni   s+   The tag of the object collides with a name.(   R   R$   R   R%   R&   R   R   t   remove(   R   R   R!   R    R'   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   remove_tagsS   s    c   
      C` sl  t  | t ƒ s! t d | ƒ ‚ n  t ƒ  } x% | j D] } | j |  j | ƒ q4 Wx% | j D] } | j |  j | ƒ q\ Wx% | j	 D] } | j
 |  j | ƒ q„ Wt ƒ  } t ƒ  } x— | D] } t  | t ƒ r» | } | j rú t j | ƒ } g  | _ n  | j j | j | ƒ } | j | ƒ }	 | j |	 _ | j | ƒ | j |	 ƒ q» q» W| j
 | ƒ | j | ƒ | S(   Ns   Expected a Query.(   R   t   QueryR   R   t   includet   updateR   t   requiret   intersection_updatet   excludet   difference_updateR	   t   extra_optimizationsR%   t   subqueryt   getR   t   queryR   (
   R   t   qt	   variablesR'   R(   R   R    t   def_sub_queryt   sqt   replacement(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt	   __query__]   s2    				c      
   O` sM  t  | ƒ d k rc t | d t ƒ rc t  | ƒ d k s= | rR t d | | ƒ ‚ n  |  j | d ƒ Sg  | D] } | j d ƒ rj | d ^ qj } g  | D] } | j d ƒ r– | d ^ q– } g  | D] } | j d ƒ rÂ | d ^ qÂ } t  | ƒ t  | ƒ t  | ƒ t  | ƒ k  r%t d | ƒ ‚ n  |  j t d | d	 | d
 | d | ƒ ƒ S(   Ni   i    sN   If the first argument to query is a Query, there should be no other arguments.t   +t   &t   -sI   All tags must start with one of the following characters: '+', '&' or '-'R+   R-   R/   R2   (   R$   R   R*   R   R:   t
   startswithR   (   R   R!   t   kwtagsR'   R+   R-   R/   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4   z   s    %,,,,c         C` sa   |  j  | } | s& t d | ƒ ‚ n% t | ƒ d k rK t d | ƒ ‚ n  x | D] } | SWd  S(   Ns   Nothing registered for '%s'i   s-   More than one match for %s (please use query)(   R   t   KeyErrorR$   R   (   R   R   R6   t   variable(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __getitem__Œ   s    c         C` s   | |  j  k S(   N(   R   (   R   R   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __contains__–   s    c         C` sV   t  d |  j j t |  ƒ f d | ƒt  d |  j d | ƒt  d |  j d | ƒd  S(   Ns
   %s (id %i)t   files     namess     db(   t   printR   R   t   idR   R   (   R   t   stream(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   print_summary™   s    &(   R   t
   __module__R   R   R#   R   R)   R:   R4   RB   RC   t   syst   stdoutRH   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR	      s   			0	
	
			
	R*   c           B` sb   e  Z d  Z d	 d	 d	 e d ƒ d	 d „ Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z RS(
   s©   

    Parameters
    ----------
    position_cutoff : float
        Used by SequenceDB to keep only optimizer that are positioned before
        the cut_off point.

    t   infc         C` sÇ   t  | ƒ |  _ | p t  ƒ  |  _ | p- t  ƒ  |  _ | p< i  |  _ | |  _ | d  k r` g  } n  | |  _ t |  j t	 t
 f ƒ r– t  |  j ƒ |  _ n  t |  j t	 t
 f ƒ rÃ t  |  j ƒ |  _ n  d  S(   N(   R   R+   R-   R/   R2   t   position_cutoffR   R1   R   t   listt   tuple(   R   R+   R-   R/   R2   RM   R1   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   ª   s    			c         C` s,   d |  j  |  j |  j |  j |  j |  j f S(   NsK   Query{inc=%s,ex=%s,require=%s,subquery=%s,position_cutoff=%f,extra_opts=%s}(   R+   R/   R-   R2   RM   R1   (   R   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __str__º   s    c         C` s/   |  j  j | ƒ t |  d ƒ s+ g  |  _ n  d  S(   NR1   (   t   __dict__R,   R   R1   (   R   t   state(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   __setstate__À   s    c         G` s4   t  |  j j | ƒ |  j |  j |  j |  j |  j ƒ S(   N(   R*   R+   t   unionR-   R/   R2   RM   R1   (   R   R!   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt	   includingÆ   s    c         G` s4   t  |  j |  j |  j j | ƒ |  j |  j |  j ƒ S(   N(   R*   R+   R-   R/   RT   R2   RM   R1   (   R   R!   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt	   excludingÏ   s    	c         G` s4   t  |  j |  j j | ƒ |  j |  j |  j |  j ƒ S(   N(   R*   R+   R-   RT   R/   R2   RM   R1   (   R   R!   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt	   requiringØ   s    	c      	   G` s5   t  |  j |  j |  j |  j |  j |  j t | ƒ ƒ S(   N(   R*   R+   R-   R/   R2   RM   R1   RN   (   R   t   optimizations(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR#   à   s    	N(   R   RI   t   __doc__R   t   floatR   RP   RS   RU   RV   RW   R#   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR*   Ÿ   s   								t   EquilibriumDBc           B` s/   e  Z d  Z e e d „ Z d „  Z d „  Z RS(   s«  
    A set of potential optimizations which should be applied in an arbitrary
    order until equilibrium is reached.

    Canonicalize, Stabilize, and Specialize are all equilibrium optimizations.

    Parameters
    ----------
    ignore_newtrees
        If False, we will apply local opt on new node introduced during local
        optimization application. This could result in less fgraph iterations,
        but this doesn't mean it will be faster globally.

    tracks_on_change_inputs
        If True, we will re-apply local opt on nodes whose inputs
        changed during local optimization application. This could
        result in less fgraph iterations, but this doesn't mean it
        will be faster globally.

    Notes
    -----
    We can put LocalOptimizer and Optimizer as EquilibriumOptimizer
    suppor both.

    It is probably not a good idea to have ignore_newtrees=False and
    tracks_on_change_inputs=True

    c         C` s;   t  t |  ƒ j ƒ  | |  _ | |  _ i  |  _ i  |  _ d  S(   N(   t   superR[   R   t   ignore_newtreest   tracks_on_change_inputst	   __final__t   __cleanup__(   R   R]   R^   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR     s
    			c         O` st   | j  d t ƒ } | j  d t ƒ } | o- | s7 t ‚ t t |  ƒ j | | | | Ž | |  j | <| |  j | <d  S(   Nt	   final_optt   cleanup(   R&   R   R   R\   R[   R#   R_   R`   (   R   R   R    R!   R?   Ra   Rb   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR#     s    c         O` s'  t  t |  ƒ j | | Ž  } g  | D]$ } |  j j | j t ƒ r" | ^ q" } g  | D]$ } |  j j | j t ƒ rS | ^ qS } g  | D]$ } | | k r„ | | k r„ | ^ q„ } t | ƒ d k rÉ d  } n  t | ƒ d k rä d  } n  t
 j | d t j j d |  j d |  j d t
 j j d | d | ƒS(   Ni    t   max_use_ratioR]   R^   t   failure_callbackt   final_optimizerst   cleanup_optimizers(   R\   R[   R4   R_   R3   R   R   R`   R$   R   R   t   EquilibriumOptimizerR   t   optdbRc   R]   R^   t   NavigatorOptimizert   warn_inplace(   R   R!   R?   t   _optst   ot
   final_optst   cleanup_optst   opts(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4     s$    1$				(   R   RI   RY   t   TrueR   R   R#   R4   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR[   é   s   		t
   SequenceDBc           B` sS   e  Z d  Z e j Z e j j d „ Z d „  Z d „  Z	 e
 j d „ Z d „  Z RS(   sà  
    A sequence of potential optimizations.

    Retrieve a sequence of optimizations (a SeqOptimizer) by calling query().

    Each potential optimization is registered with a floating-point position.
    No matter which optimizations are selected by a query, they are carried
    out in order of increasing position.

    The optdb itself (`theano.compile.mode.optdb`), from which (among many
    other tags) fast_run and fast_compile optimizers are drawn is a SequenceDB.

    c         C` s)   t  t |  ƒ j ƒ  i  |  _ | |  _ d  S(   N(   R\   Rq   R   t   __position__Rd   (   R   Rd   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   =  s    	c         G` sœ   t  t |  ƒ j | | | Œ | d k rp t |  j ƒ d k rM d |  j | <q˜ t |  j j ƒ  ƒ d |  j | <n( t | t t	 f ƒ s‹ t
 ‚ | |  j | <d  S(   Nt   lasti    i   (   R\   Rq   R#   R$   Rr   t   maxt   valuesR   R   RZ   R   (   R   R   R    t   positionR!   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR#   B  s    #c         ` sÓ  t  t |  ƒ j | | Ž  } | j d t j j ƒ } |  j ‰  t | ƒ d k r3t	 | d t
 ƒ r3t | ƒ d k sy t ‚ t | d d d	 ƒ rŸ | d j } n  t | d j ƒ d k r3ˆ  j ƒ  ‰  xi | d j D]W } | \ } } d | j t | ƒ f | _ | | k  rÒ | j | ƒ | ˆ  | j <qÒ qÒ Wq3n  g  | D] } ˆ  | j | k  r:| ^ q:} | j d ‡  f d †  ƒ i  }	 |  j r—|  j |	 d <n  |  j | |	  }
 t | d d ƒ rÏ| d j |
 _ n  |
 S(
   s¨   

        Parameters
        ----------
        position_cutoff : float or int
            Only optimizations with position less than the cutoff are returned.

        RM   i   i    s   %s_%it   keyc         ` s   ˆ  |  j  |  j  f S(   N(   R   (   R    (   t   position_dict(    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   <lambda>t  s    Rd   R   N(   R\   Rq   R4   R&   R   Rh   RM   Rr   R$   R   R*   R   t   getattrR   R1   R%   R   RF   R   R   t   sortRd   t   seq_optR   (   R   R!   R?   Ro   RM   t	   extra_optR   Rv   Rl   R"   t   ret(    (   Rx   s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4   M  s2    			%,	c         C` s’   t  |  j j d t |  ƒ d | ƒt |  j j ƒ  ƒ } d „  } | j | ƒ t  d | d | ƒt  d |  j d | ƒt  d |  j	 d | ƒd  S(   Ns    (id %i)RD   c         S` s$   |  d | d k |  d | d k  S(   Ni   (    (   t   at   b(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   c  s    s
     positions     namess     db(
   RE   R   R   RF   RN   Rr   t   itemsR{   R   R   (   R   RG   t	   positionsR   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyRH   }  s    $	c         C` s    t  ƒ  } |  j | ƒ | j ƒ  S(   N(   R   RH   t   getvalue(   R   t   sio(    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyRP   ‰  s    	(   R   RI   RY   R   t   SeqOptimizerR|   t   warnR   R#   R4   RJ   RK   RH   RP   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyRq   ,  s   			0t   LocalGroupDBc           B` s5   e  Z d  Z e e e j d „ Z d „  Z d „  Z RS(   s›   
    Generate a local optimizer of type LocalOptGroup instead
    of a global optimizer.

    It supports the tracks, to only get applied to some Op.

    c         C` sD   t  t |  ƒ j ƒ  d  |  _ | |  _ | |  _ i  |  _ | |  _ d  S(   N(	   R\   Rˆ   R   R   Rd   t   apply_all_optst   profileRr   t	   local_opt(   R   R‰   RŠ   R‹   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   ˜  s    				c         O` s®   t  t |  ƒ j | | | Œ | j d d ƒ } | d k r‚ t |  j ƒ d k r_ d |  j | <qª t |  j j ƒ  ƒ d |  j | <n( t | t	 t
 f ƒ s t ‚ | |  j | <d  S(   NRv   Rs   i    i   (   R\   Rˆ   R#   R&   R$   Rr   Rt   Ru   R   R   RZ   R   (   R   R   R    R!   R"   Rv   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR#   ¡  s    #c         ` s_   t  t t ˆ  ƒ j | | Ž  ƒ } | j d ‡  f d †  ƒ ˆ  j d ˆ  j d ˆ  j | Œ } | S(   NRw   c         ` s   ˆ  j  |  j |  j f S(   N(   Rr   R   (   R    (   R   (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyRy   °  s    R‰   RŠ   (   RN   R\   Rˆ   R4   R{   R‹   R‰   RŠ   (   R   R!   R?   Ro   R~   (    (   R   s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4   ­  s    !		(	   R   RI   RY   R   R   t   LocalOptGroupR   R#   R4   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyRˆ     s
   	t   TopoDBc           B` s)   e  Z d  Z d e d d „ Z d „  Z RS(   s>   

    Generate a Global Optimizer of type TopoOptimizer.

    t	   in_to_outc         C` s;   t  t |  ƒ j ƒ  | |  _ | |  _ | |  _ | |  _ d  S(   N(   R\   R   R   t   dbt   orderR]   Rd   (   R   R   R   R]   Rd   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   ¿  s
    			c         O` s.   t  j |  j j | | Ž  |  j |  j |  j ƒ S(   N(   R   t   TopoOptimizerR   R4   R   R]   Rd   (   R   R!   R?   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4   Ç  s    N(   R   RI   RY   R   R   R   R4   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   ¸  s   t   ProxyDBc           B` s    e  Z d  Z d „  Z d „  Z RS(   s“   
    Wrap an existing proxy.

    This is needed as we can't register the same DB mutiple times in
    different positions in a SequentialDB.

    c         C` s(   t  | t ƒ s t d ƒ ‚ | |  _ d  S(   Nt    (   R   R	   R   R   (   R   R   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR   ×  s    c         O` s   |  j  j | | Ž  S(   N(   R   R4   (   R   R!   R?   (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR4   Û  s    (   R   RI   RY   R   R4   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyR’   Î  s   	(   t
   __future__R    R   R   R%   RJ   t   theano.compatR   t   theano.misc.ordered_setR   t   sixR   R   t
   theano.gofR   t   theanoR   t   objectR	   R*   R[   Rq   Rˆ   R   R’   (    (    (    s0   /tmp/pip-build-X4mzal/theano/theano/gof/optdb.pyt   <module>   s   “JCc)