
Xc           @` s>  d  Z  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 Z d d l Z d d l m Z m Z d d l m Z m Z m Z 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 d l m Z d d l m Z m  Z  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 d l) m* Z* m+ Z+ m, Z, d Z- d Z. d Z/ d Z0 e j1 d  Z2 e j j3 e j j4 e j j5 e j j6 e j j7 g Z8 d   Z9 d   Z: e j; e' j< g  d    Z= d e j# f d     YZ> d e j# f d     YZ? d e j# f d      YZ@ d! e# f d"     YZA d# e j# f d$     YZB d% e j# f d&     YZC d'   ZD d(   ZE e j; e' j< g  d)    ZF d* e j# f d+     YZG e j jH   ZI e j jJ   ZK e j jH   ZL e jM d, eI d- d. d/  e jM d0 eL d1 d. d/  e jM d2 eB   d3 d. d/  e jM d4 eA d5 eN d6 eO  d7 d. d8 d/  eI jM d9 eK d: d. d/  eK jM d; e jP e= d< eQ d: d= d. d/  eK jM d> e>   d? d. d/  eK jM d@ e?   dA d. d/  eK jM dB eG   dC d. dD d/  eK jM dE e@   dF d. dD d/  eL jM dG e jP e j j7 d< eQ d: d. d/  eL jM dH e jP e= d< eQ d? d= d. d/  eL jM dI eC   dC d. d/  eL jM dJ e jP e= d< eQ dF d= d. d/  eL jM dK e jP eF d< eQ dL dM d. d/  eL jM dN e jP e= d< eQ dO d= d. d/  d S(P   s  
This module provides optimizations for scan.
The Optimization provided in this file:

local opt: remove_constants_and_unused_inputs_scan,
           constant_folding_for_scan2,
           scan_merge_inouts
           They are wrapped in in2out to create global opt.
global opt: ScanInplaceOptimizer,
            PushOutNonSeqScan,
            PushOutSeqScan,
            PushOutDot1,
            ScanMerge,
            ScanSaveMem

How the are registered:

optdb: scan_eqopt1 (.1), scan_eqopt2(1.6), scan_inplace(75)
scan_eqopt1 -> scan_seqopt1
scan_seqopt1 -> in2out(remove_constants_and_unused_inputs_scan)(1),
                PushOutNonSeqScan(2),
                PushOutSeqScan(3), PushOutDot1(4)
scan_eqopt2 -> They are all global optimizer. (in2out convert local to global).
               This is important, as the order is important and all global
               optimizer run before local optimizer in the order they where
               registered. (So don't change the order we register them!)
               If we convert to local optimizer, we must convert all of them
               to local optimizer. But:
               1) can ScanMerge be made local? Can we keep only this one
               global?
               2) ScanSaveMem assert that we remove all nodes outputs,
                  we need to keep this.
               3) It is ScanSaveMem suppose the the others ran before.
                  I added an assert at one place, but didn't looked for
                  other place.
               4) Moving this to local opt could speed up significant this opt,
                  as we pass frequently on all nodes in the graph for no
                  good reason.
               5) We register remove_constant_*  many places, as some
                  opt create them and let this one clean up the mess.
                  Doing it that way, make things simpler for those already
                  complex opt.

               in2out(constant_folding),
               in2out(remove_constants_and_unused_inputs_scan1),
               ScanMerge,
               in2out(remove_constants_and_unused_inputs_scan2),
               in2out(scan_merge_inouts),
               ScanSaveMem,
               in2out(remove_constants_and_unused_inputs_scan3)
i    (   t   absolute_importt   print_functiont   divisionN(   t   maxsize(   t   OrderedDict(   t   tensort   scalar(   t   optt   get_scalar_constant_valuet   Alloct
   AllocEmpty(   t   gof(   t   integer_typest	   iteritems(   t   xrange(   t   optdb(   t   deep_copy_op(   t   toolboxt   DestroyHandlert   InconsistencyError(   t	   Optimizer(   t   pre_constant_merget   pre_greedy_local_optimizer(   t   scan_op(   t
   scan_utils(   t   equal_computationst   find_upt	   scan_argss   restructedtext ensN   Razvan Pascanu Frederic Bastien James Bergstra Pascal Lamblin Arnaud Bergeron s    (c) 2010, Universite de Montreals    Razvan Pascanu <r.pascanu@gmail>s   theano.scan_module.scan_optc          G` s   t  j d d j |    d  S(   Ns   WARNING theano.scan: t    (   t   _loggert   warningt   join(   t   msg(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR   _   s    c          G` s   t  j d d j |    d  S(   Ns   INFO theano.scan: R   (   R   t   infoR   (   R    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR!   c   s    c         C` s  t  |  j t j  s t S|  j } | j } | t t g  | j | j	 | j
  D] } t |  ^ qL   7} | | j 7} | | j 7} | j } | j } | | j | !} | | } | j | j	 | j
 | j | j | j d } |  j | } |  j d | j | !}	 t   }
 g  } |  j d g } t j j |  } xt | j  D]} |  j | d } t  | t j  r| j j d k	 ry | j   d |
 | | <WqKt k
 rqKXqF| | | k rFg  | D]$ } t j | g | g  r| ^ q} | r*|  j j | d  d } | | |
 | | <qK| j | |  | j |  qFqFWt |  } | | 7} | |	 7} g  } g  } x t  t! | |   D] \ } \ } } t  | t j"  r| j   |
 | <q| | k rg  t  |  D]* \ } } t j | g | g  r| ^ q} | r,| | d |
 | <qI| j |  | j |  qqW| j# |  | j# |  t |  t |  k r	t j | d |
 } t$ j% | j&  } | | d <t j | | |  } | | t' d t(    } t d |  g f g t) t! |  j |    St Sd S(   sf  
    Move constants into the inner graph, and remove unused inputs.

    Constants that are in the outer graph are represented by a free symbolic
    variable in the inner graph. If we move them into the inner graph,
    constant-folding can happen in the inner graph.
    This is applied only on sequences and non-sequences,
    not on initial states.

    i   i    t   replacet   n_seqst   return_listt   removeN(*   t
   isinstancet   opR   t   Scant   FalseR#   t   intt   sumt	   tap_arrayt	   n_mit_mott	   n_mit_sott   lent	   n_sit_sott   n_shared_outst   inputst   outputst	   n_nit_sotR   R   t   graphR   R   t   TensorConstantt   tagt   unique_valuet   Nonet   clonet	   TypeErrorR   R   t   indext   appendt	   enumeratet   zipt   Constantt   extendt   copyt   deepcopyR!   t   dictt   Truet   list(   t   nodeR'   t   stt   xt   op_inst   op_outst   out_stuff_innert   non_seqst   outer_non_seqst   out_stuff_outert   givenst   nw_innert   nw_outert   all_inst   idxt   node_inpt   identical_seqsR<   t	   nw_n_seqst   nw_inner_nonseqt   nw_outer_nonseqt   nw_int   nw_outt   it   identical_nonseq_idxt   nw_infot   nwScant   nw_outs(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt'   remove_constants_and_unused_inputs_scang   sz    		4		
0	

($
,t   PushOutNonSeqScanc           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   sq   
    A global optimizer for pushing out the variables inside the scan that depend
    only on non-sequences.
    c         C` s   t  j j |   d  S(   N(   R   R   t   __init__(   t   self(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc      s    c         C` s   | j  t j j    d  S(   N(   t   attach_featureR   R   t   ReplaceValidate(   Rd   t   fgraph(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   add_requirements   s    c         C` sY   g  | j    D]! } t | j t j  r | ^ q } x | D] } |  j | |  q; Wd  S(   N(   t   toposortR&   R'   R   R(   t   process_node(   Rd   Rg   RI   t   nodelistRG   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   apply   s    c   0      ` s  t  j | j j | j j  \ } } t j j j | |  } t	 |  } t
 g  t |  D] \ } } | | f ^ qX  }	 t	   }
 t	    t        f d     d   _ g  } g  } | j } | j |  } t	 |  } t
 g  t |  D] \ } } | | f ^ q  } | j | j  } | j |  } | j | j  } t |  t |  k sdt  t |  t |  k st  x| D]} | |
 k rt g  | j D]3 } | | k p| j |
 k pt | t j  ^ q rt | j t j j  rt | j t j j  r|
 j |  g  } x | j D] } | | k rc| | } | j | |  q3|  k r| j |  |  q3t | t j  r| j | j    q3t d |   q3Wg  t  | j |  D] \ } } | j! j" |  ^ q} | j | t
 d t#    d j } x t | j  D]k \ } } t  j$ | d  }   |  | j |  t | t! | j |   st  | j | j |  q+WqqWg  } g  } g  } g  | D] } | |
 k r| ^ q} t	 |  }  t	 g   }! x | D] } |! j% | j  qWx}  j&   D]o \ }" } | | j! |" j! k r|" |! k r|" j |  k r| j |"  | j | |  | j | |  qqWt |  d k rt   }# g  }$ g  }% xh t  | | |  D]T \ }& }' }( t |( t j  r|( j   }' n |% j |'  |$ j |(  |' |# |& <qWt  j | d |# }) | |% }* t' j( |* |) | j)  }+ |+ | j |$ t
 d t#    d j }, | j* t+ t  | j |, j   d | g d d	 t# S|! st   }- x  j&   D]r \ }" } |" | k r| j |	 |" } | | } g  | j, D] }. |. ^ q}/ t j- | | j d |/  |- | <qqW|- rt | j  t |-  k r| j* |- j&   d | g d d	 q| j. |- j&   d d	 qn t/ Sd
 S(   s  
        IMPORTANT NOTE: This function uses set and dictionary data structures.
        By default they are not ordered for efficiency reasons. Take care
        and make sure of changing them with their Ordered counterparts if you
        need to iterate over these variables.

        c         ` s-    j  |     j  |  <  j d 7_ d  S(   Ni   (   t   addt   n(   t   y(   t   add_to_replacet   to_replace_mapt   to_replace_set(    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRp      s    i    s   Error in the `scan_pushout_non_seq_operations`. The optimization tries to move some computation fron scan which is not allowed to move. Report this on theano-users listR$   t   _replaceR"   R%   t   reasont   scanOp_pushout_nonseqs_opsN(0   R   t   reconstruct_graphR'   R2   R3   t   theanoR   R5   t   io_toposortt   setRD   R>   R   Rn   t   inner_non_seqsRN   t
   inner_seqst
   outer_seqsR/   t   AssertionErrort   allt   ownerR&   R   R@   t   compilet   ViewOpt
   DeepCopyOpRm   R=   R:   t	   ExceptionR?   t   typet   filter_variableRE   t   safe_newt   updatet   itemsR   R(   R!   t   replace_all_validate_removeRF   t   shapet   alloct   replace_all_validateR)   (0   Rd   Rg   RG   t   clean_inputst   clean_outputst   local_fgraph_topot   local_fgraph_outs_sett   kt   vt   local_fgraph_outs_mapt   to_remove_sett   replace_with_int   replace_with_outR'   Rz   t   inner_non_seqs_sett   inner_non_seqs_mapRN   R{   R|   t   ndRI   t   outside_inst   _idxRo   t   nw_outer_nodeRT   t   y_place_holdert   clean_to_replacet   clean_replace_with_int   clean_replace_with_outt   existent_nodest   existent_nodes_sett   to_keep_sett   outRP   RR   RQ   t   to_replt   repl_int   repl_outRK   RJ   R_   t   nw_nodet   replace_witht   shpR   (    (   Rp   Rq   Rr   s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRj      s    		+					+C
4	
"		
		
	
	
	(   t   __name__t
   __module__t   __doc__Rc   Rh   Rl   Rj   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRb      s
   			t   PushOutSeqScanc           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s{   
    A global optimizer for pushing out the variables inside the
    scan that depend only on constants and sequences.
    c         C` s   t  j j |   d  S(   N(   R   R   Rc   (   Rd   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc     s    c         C` s   | j  t j j    d  S(   N(   Re   R   R   Rf   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh     s    c         C` sY   g  | j    D]! } t | j t j  r | ^ q } x | D] } |  j | |  q; Wd  S(   N(   Ri   R&   R'   R   R(   Rj   (   Rd   Rg   RI   Rk   RG   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl     s    !c   <      ` sr	  t  j | j j | j j  \ } } t j j j | |  } t	 |  } t
 g  t |  D] \ } } | | f ^ qX  }	 t	   }
 t	    t        f d     d   _ g  } g  } | j } | j |  } t	 |  } t
 g  t |  D] \ } } | | f ^ q  } | j | j  } | j |  } t	 |  } t
 g  t |  D] \ } } | | f ^ qP } | j | j  } t |  t |  k st  t |  t |  k st  x| D]} | |
 k rt g  | j D]? } | | k p!| j |
 k p!t | t j  p!| | k ^ q rt | j t j j  rg  } t } x | j D] } | | k r| | } | j | |  q[| | k r| j | | |  t } q[|  k r| j |  |  t } q[t | t j  r| j | j    q[t d |   q[W| s&qn  |
 j |  | j | t
 d t    d j } xt | j  D]I \ } } t  j  | d  }   |  | j |  | j | j |  qeWq| |
 k rt | j t j j!  r| j d | k s| j d j |
 k r|
 j |  | j d } | | k r9| | | } n |  k rV|  | } n  d } xA | j j" D]3 }  |  d k r| |  f 7} qi| |  d f 7} qiW| j# |  }! | j d } t  j  | d  }   |  | j |  | j |!  t$ |! j% d  r[|! j% j& j' }" | j% j& j' d f }# |# | j d j% j& j' 7}# |" |# k sXt  q[qqWg  }$ g  }% g  }& g  | D] } | |
 k rx| ^ qx}' t	 |'  }( t	 g   }) x |' D] } |) j( | j  qWx}  j)   D]o \ }* } |* |) k r|* j |( k r| | j* |* j* k r|$ j |*  |% j | |  |& j | |  qqWt |$  d k rt   }+ g  }, g  }- xh t+ |$ |% |&  D]T \ }. }/ }0 t |0 t j  r|0 j   }/ n |- j |/  |, j |0  |/ |+ |. <qWt  j | d	 |+ }1 |- | }2 | j, j-   }3 |3 d
 c t |-  7<t. j/ |2 |1 |3  }4 |4 | j d  |, | j d t
 d t    d j }5 | j0 t1 t+ | j |5 j   d | g d d t S|) rj	| j2 rj	| j3 |  rj	t   }6 xI j)   D];\ }* } |* | k r| j |	 |* } | | }7 | }8 |* | j4 |8  k r| j4 |8  j5 |*  }9 | j6 |  |9 }: t7 t8 j9 | j:     }; t j; |: |; |7  } n |* | j< |8  k r| j< |8  j5 |*  }9 | j= |  |9 }: t j; |: d |7  } n( |* | j> |8  k r|7 } n
 |7 d } | |6 | <qqW|6 rn	t |6  t | j  k rn	| j0 t1 |6 j)    d | g d d t Sn t Sd S(   s  
        IMPORTANT NOTE: This function uses set and dictionary data structure.
        By default they are not ordered for efficiency reasons. Take care
        and make sure of changing them to Ordered versions if you need to
        iterate over those variables.

        c         ` s-    j  |     j  |  <  j d 7_ d  S(   Ni   (   Rm   Rn   (   Ro   (   Rp   Rq   Rr   (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRp     s    i    s   Error in the `scan_pushout_seq_operations`. The optimization tries to move some computation fron scan which is not allowed to move. Report this on theano-users listR$   Rs   RI   i   t
   test_valueR"   R#   R%   Rt   t   scanOp_pushout_seqs_opsiN(   i    (?   R   Rv   R'   R2   R3   Rw   R   R5   Rx   Ry   RD   R>   R   Rn   Rz   RN   R{   R|   R/   R}   R~   R   R&   R   R@   t   ElemwiseR)   R=   RE   R:   R   Rm   R   t
   DimShufflet	   new_ordert
   dimshufflet   hasattrR7   R   R   R   R   R   R?   R!   RB   R   R(   R   RF   t   as_whilet   outer_mitmott   inner_mitsot_outsR<   t   outer_mitsott   abst   numpyt   mint   mitsot_tapst   set_subtensort   inner_sitsot_outst   outer_sitsott   inner_nitsot_outs(<   Rd   Rg   RG   R   R   R   R   R   R   R   R   R   R   R'   Rz   R   R   RN   R{   t   inner_seqs_sett   inner_seqs_mapR|   R   RI   R   t   depends_on_seqsR   R   RT   Ro   R   t   new_ordt   old_ordt	   new_outert   new_sht   ref_shR   R   R   R   R   R   R   RP   RR   RQ   R   R   R   RK   RJ   R^   R_   R   R   t   _yt   lst   odxt   inpRH   (    (   Rp   Rq   Rr   s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRj     s4   		+					++O
				

		
	
	
	
!	(   R   R   R   Rc   Rh   Rl   Rj   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR     s
   			t   PushOutScanOutputc           B` sV   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 RS(	   s   
    This is an optimization that can push operations performed
    at the end of the inner graph of scan to outside of scan.
    c         C` s   t  j j |   d  S(   N(   R   R   Rc   (   Rd   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc     s    c         C` s   | j  t j j    d  S(   N(   Re   R   R   Rf   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh     s    c         C` s{   g  | j    D]. } t | j t j  r | j j r | ^ q } x3 | D]+ } x" | d  k	 rr |  j | |  } qQ WqH Wd  S(   N(   Ri   R&   R'   R   R(   R   R9   Rj   (   Rd   Rg   RI   Rk   RG   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl     s    c         C` s  | j  } t | j | j | j | j | j  } d  } i  } t j j j	 | j
 | j d | } x| D]} t | j  t j j j  rg t | j  j t j  rg | j | j k rg |  j | j |  rg | j j | j  }	 | j |	 | j k r| j j | j |	  }
 d |
 } | j | } | j d  k	 rt | j j  t j j  rt | |  d k r| j j d j d k r| j j d j d k r|  j | j j d |  d k r|  j | j j d |  d k r| j | j j } |  j | | | |  \ } } } t j j | d j d d d  d d | d <t j j  | d  } | d j! | d | d | d f  | d <t j j" |   } | j# |	 d } | | } | j$ |	 } | j% d d } | j d } | j& | | f g d d Pqqqg qg W| S(	   Nt   clientsi   i    i   i   t   outdimRt   t   scanOp_pushout_output('   R'   R   R2   R3   R!   R9   Rw   R   R5   Rx   t   inner_inputst   inner_outputsR&   R   t   elemwiseR   t	   scalar_opR   t   AddR   t   inner_out_sit_sott    inner_sitsot_only_last_step_usedR<   t   inner_in_sit_sotR   t   DotR/   t   ndimt   get_outer_ndimt   push_out_inner_varst   flattenR   R   t   reshapet   dott   outer_in_sit_sott   outer_out_sit_sotR   t   replace_all(   Rd   Rg   RG   R'   t   argst   new_scan_nodeR   R   R   t
   sitsot_idxt   sitsot_in_idxt
   dot_in_idxt	   dot_inputt   inner_dot_inputst   outer_dot_inputst   new_scan_argst   shape_input1t   outer_dot_outputt
   init_valuet   replacementR   t   subtensor_nodet   outer_sitsot_last_step(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRj     s\    				

""	&
c         C` s   | j  j |  } | j | } t | j  d k r | j d d } | d k r t | j t j j	  r t j j
 j | j | j j  } t |  d k r t j j | d  d k r t Sq n  t S(   s   
        Given a inner nit_sot output of scan, return True iff the outer
        nit_sot output has only one client and that client is a Subtensor
        instance that takes only the last step (last element along the first
        axis).

        i   i    t   outputi(   R   R<   R   R/   R   R&   R'   Rw   R   t	   Subtensort	   subtensort   get_idx_listR2   t   idx_listt   extract_constantRE   R)   (   Rd   t   varR   RT   t	   outer_vart   clientt   lst(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR     s    
c         C` s>   | | j  k s! t | t j  r- | j } n | j d } | S(   Ni   (   t   inner_in_non_seqsR&   Rw   R@   R   (   Rd   R   R   t
   outer_ndim(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR   #  s
    c         C` s	  d  g t |  } | } | } x t t |   D] } | | }	 |	 | j k rw | j j |	  }
 | j |
 | | <q2 |	 | j k r | j j |	  } | j | | | <q2 t |	 t	 j
  r |	 j   | | <q2 |	 | j k r2 | j j |	  } | j | | | <q2 q2 Wg  t t |   D] } | | d  k r| ^ q} g  | D] } | | ^ qF} t |  d k r|  j | | | |  } t | j | j | j j | j j | j j  } | j t |  } x/ t t |   D] } | | | | | <qWn  | | | f S(   Ni    (   R9   R/   t   ranget   inner_in_seqsR<   t   outer_in_seqsR   t   outer_in_non_seqsR&   Rw   R@   R:   t   inner_out_nit_sott   outer_out_nit_sott   add_nitsot_outputsR   R2   R3   R'   R!   (   Rd   Rg   t
   inner_varst   old_scan_nodet   old_scan_argst
   outer_varsR   R   RT   R   t   idx_seqt   idx_non_seqt
   idx_nitsotR\   t   idx_add_as_nitsotst   add_as_nitsotst   new_outs(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR   0  s@    
				c         C` s  t  |  } g  t |  D] } | j d ^ q } t j |  } | j j |  | j j |  t j | j	 | j
 | j  }	 |	 | j t d t    d j }
 t  | j  t  | j  } |
 j |  |
 j | | } | j t t | j |   d | g d d |
 S(   Ni    R$   R%   Rt   R   (   R/   R   R2   RB   R  RA   t   outer_in_nit_sotR   R(   R   R   R!   t   outer_inputsRD   RE   R   t   outer_outputst   outer_out_sharedR3   R   RF   R?   (   Rd   Rg   R  R  t   new_outputs_innert   nb_new_outsR\   t   new_nitsots_initial_valueR   t   new_scan_opR   t   new_node_new_outputs_idxt   new_node_old_outputs(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR  d  s(    #	
	(   R   R   R   Rc   Rh   Rl   Rj   R   R   R   R  (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR     s   				]			4t   ScanInplaceOptimizerc           B` s;   e  Z d  Z d e e d  Z d   Z d   Z d   Z RS(   s;   
    Graph optimizer for Scan (makes it run inplace).

    c         C` s,   t  j |   | |  _ | |  _ | |  _ d  S(   N(   R   Rc   t	   typeInfert   gpu_flagt	   gpua_flag(   Rd   R  R  R  (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc     s    		c         C` s'   | j  t j    | j  t    d  S(   N(   Re   R   Rf   R   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh     s    c         C` s  | j  } t j | j  } d | k r7 t   | d <n  x. | D]& } | d | j d g | d | <q> W| j d | j  } | j | j  }	 |	 | j | j  7}	 |	 | j	 | j  7}	 | j
 | j  }
 |
 | j | j  7}
 |
 | j | j  7}
 xv t t |	   D]b } |	 | } t | j  d k r| j rt | j j  |  r| j j  | j j   |	 | <qqWt |	  } x? t |  D]1 } |	 | |	 |  k rt |	 |  |	 | <qqW| |	 |
 } |  j d
 k rd
 } n |  j |  } t j | j | j | d | } | | t d t    } y= | j t t | j |   d | g d d | d	 j SWn t k
 r~| SXd
 S(   sy  Attempts to replace a Scan node by one which computes the specified
        outputs inplace.

        Parameters
        ----------
        fgraph : FunctionGraph
            Function graph in which to attempt the replacement
        node : Apply node
            Scan node to replace by an inplace version
        output_indices : list of integers
            Indices of the outputs to attempt to compute inplace
        alloc_ops : list of Op classes
            Classes that represent operation that allocate new memory and
            that the optimization should duplicate so it can operate inplace
            on them.
        t   destroy_mapi   R#   t   typeConstructorR$   R%   Rt   t   scanOp_make_inplacei    N(   R'   RB   RC   R!   R   R2   R#   R   R   R   t   outer_sharedt   outer_nitsotRN   R   R/   R   R   R&   R   R   R  R9   R   R(   R3   RD   RE   R   RF   R?   R   (   Rd   Rg   RG   t   output_indicest	   alloc_opsR'   R!   t   out_idxt   ls_beginR   t   ls_endR\   R   t   n_outsRT   R2   R  t   new_opR  (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   attempt_scan_inplace  sN    	$
#			c         C` s  t  t f } |  j r: | t j j j t j j j f 7} n  |  j rp y  | t j	 j t j	 j f 7} Wqp qp Xn  | j
   d  d  d  } g  | D]S } t | j t j  r | j j d |  j k r | j j d |  j k r | ^ q } xt t |   D]} | | } | j } | j d | j d | j d }	 g  }
 xt |	  D]} d | j | } | j | } | j rt | j j |  r|
 j |  qKn  t } x | j | j D]} } | d } t | j d	  rt | j j j   g   } g  | D] } | j | ^ q} | j | | k r4t } Pq4qqW| sK|
 j |  qKqKW|  j | | | |
 |  } | | k r x, |
 D]! } |  j | | | g |  } qWq q Wd  S(
   Nit   gput   gpuaR-   R.   R0   i   i    R  (   R	   R
   R  Rw   t   sandboxt   cudat   GpuAlloct   GpuAllocEmptyR  t   gpuarrayRi   R&   R'   R   R(   R!   R   R/   R   R#   R2   R   R=   R)   R   R   R+   R  t   valuesRE   R*  (   Rd   Rg   R$  t   nodesRI   t
   scan_nodest   scan_idxt   original_nodeR'   R(  t   out_indicesR%  t   inp_idxR   t   input_used_inplacet   cR   t   inplace_inp_indicesR\   t   inplace_inpsRG   t   pos(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl     sX    		%
	
 N(	   R   R   R   R9   R)   Rc   Rh   R*  Rl   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR    s
   		Ht   ScanSaveMemc           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s@   
    Graph Optimizer that reduces scan memory consumption.

    c         C` s   t  j j |   d  S(   N(   R   R   Rc   (   Rd   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc   ?  s    c         C` s   | j  t j j    d  S(   N(   Re   R   R   Rf   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh   B  s    c   O      C` s  d   } d   } d   } t  | d  r< | j j j } n	 t   } | j } | j | j | j | j	 } g  t
 | j  D] }	 d ^ q| }
 |
 g  | j | j D] } t t |   ^ q 7}
 |
 g  t
 | j	  D] }	 d ^ q 7}
 t | j  | k st  t | j  | k r.i d d 6g  d 6} n d  } g  | j D] } d  ^ q>} g  t
 | j  D] } d ^ q`} | g  | j | j | !D] } d ^ q7} t } xt | j |   D]\ } } g  | | <x| j D]\ } } t |  t k rd  } d  | | <Pqt | j t j  s1d  } d  | | <Pqt j | j | j j  } | d  k rld  } d  | | <Pn  | | j k ry | | d } Wqt k
 r| j d |
 | } qXn3 y | | d } Wn t k
 r| j d } n Xt j | d |  } | | c | | f g 7<t | d t   rJ| d j! d  k rJd  } n  t | d t   ryt j" j# | d j!  } n t j" j# | d  d	 } | t$ k s| | k rd  } n | |
 | } | d  k	 r| d  k	 rt | t j%  r| d c | g 7<qt |  t& k r)| t$ k r)d  } qt |  t& k rX| d | k  rX| | d <qt |  t& k ry| d k ryqd  } qqWqW| d  k	 rO| j d } t | d  d k rd  } n9 | d d } x( | d d	 D] } t j' | |  } qW| d d k r| d } n d  } | | | |  | j d  } | | d	  } n | j d } d  } xt | j |   D]\ } } x| j D]x\ } } t |  t k rd | | <Pqt | j t j  sd | | <Pqt j | j | j j  } | d  k rd | | <Pn  t | d t   rD| d j( d  k rDd | | <Pn  | | j k rk| j d |
 | } n3 y | | d } Wn t k
 r| j d } n Xt j | d |  } t | d t   rt j" j# | d j(  } n t j" j# | d  } | d k s| | d k r"d | | <qt) j* j+ j, } | j j } | j j | j j | j j d	 }  | | k ox|  k n }! | r|! r| | | |
 | |
 | d	  }" n | | | |
 | |
 |  }" | | d k r| |" | |  }" n  |" | | <t- } qWqvWg  t |  D]0 \ } }	 t |	  t. k r|	 d k  r| ^ q}# | pdt |#  d k } | sy| d  k	 rg  }$ t/ | j  }% | |% d <t0 j1 | j |#  \ }& }' g  }( d	 | j2 | j }) x/t | | j  D]\ }* }+ |* | j } t |+  t. k o!	|+ d k o!	| |& k s|* | j |& k r@	d	 }, n |+ }, |* | j | j k  r@|% |) |* j3 rk
t |% |) |* j3 j t j4  rk
t |% |) |* j3 j j d t   rk
t |% |) |* j3 j t j4  s	t  |% |) |* j3 j d	 }- t j5 |,  }. t j5 |
 |  }/ t j6 |. |/ k  |. |/ |. |/  }0 t7 t8 |0  }1 t9 |1 g  d }1 t0 j: |- |1  }2 nh t j5 |,  }1 t j5 |
 |  }/ t j' |1 |/  }1 t7 t8 |1  }1 t9 |1 g  d }1 |% |) |* |1  }2 |2 |% |) |* <|( j; | j |*  | j |* }3 |$ |3 g  | j |3 j D] }	 |	 d j d ^ qf g 7}$ q|* | j | j | j	 k  r| j |* | j2 d	 | j< }4 |% |4 | j d k r|, |% |4 <n  | j |* }3 |( j; |3  |$ |3 g  | j |3 j D] }	 |	 d j d ^ qf g 7}$ qqqW| d  k	 rXxJt | | j  D]2\ }* }, |, d k r|* | j | j k  r|) |* }5 |
 | j |* }/ |% |5 j3 rt |% |5 j3 j t j4  rt |% |5 j3 j j d t   r|% |5 j3 j d	 }- t0 j: |- |  }2 |2 |% |5 <qN|% |5 |/ |  }2 qQ|* | j | j | j	 k  rQ|) |* | j< }5 |% |5 | j d k rN| |% |5 <qNqQqqWn  t0 j= | |' |%  \ }6 }7 }8 }9 }: t   }; x$ t> |:  D] \ }< } |< |; | <qWg  |9 D] }	 t7 t8 |	  ^ q}9 t9 |9  }9 t- |8 d
 <t) j j# |9 d  d k rd  St? j@ |6 |7 |8  |9 tA d t-    }= g  }> xt |  D]v\ }* }? | r>|? d  k	 r>| |* d k r>xEt | j |* j  D]*\ }@ } |? |@ \ }A }B t |A d t   rt  | |A d j(  | |A d j!  | |A d jB   }C n | |A d  }C |C f tC |B d	  }D |; |* }E t j |D  }F t j jD |D d    }G |F |= |E |G  }H |H jE d k r|H d  d  |A d	  }H n  |( j; |*  |> | d j d |H f g 7}> qWq>q>Wx|$ D]\ }4 }I t |I  d k r|: |4 }E xt |I  D]\ }< }J | |4 |< \ }A }B t |A d  t  k r|A d j( | |
 |4 | |4 } |A d j! d  k	 r|A d j! t$ k r|A d j! | |
 |4 | |4 } n d  } t  | |  | |  | |A d jB   f tC |B d	  }D n; |A d | |
 |4 | |4 }K | |K  f tC |B d	  }D t j |D  }F t j jD |D d    }G |F |= |E |G  }H |H jE d k rx|H d  d  |A d	  }H n  |> |J |H f g 7}> qWqqW| s| d  k	 rxY t | j  D]H \ }* } |* |( k r|* |' k r|: |* }E |> | |= |E f g 7}> qqWg  |> D]! \ }J }L t0 jF |L j3 |  ^ q}M tG |M  rBt Sg  |> D] \ }J }L |J j3 ^ qI}N |N j; |  | jH |> |N d d qn  d  S(   Nc         S` s0   |  d  k r | S| d  k r  |  St j |  |  S(   N(   R9   R   t   minimum(   RI   Ro   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt
   select_minH  s
    c         S` s0   |  d  k r | S| d  k r  |  St j |  |  S(   N(   R9   R   t   maximum(   RI   Ro   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt
   select_maxO  s
    c         S` s!   |  d  k r d  St j |   Sd  S(   N(   R9   R   t   as_tensor_variable(   RI   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   sanitizeV  s    t   shape_featurei    it   realt   symi   t   _scan_savemem_visitedR$   c         S` s   t  |  t j  S(   N(   R&   R   t   Variable(   t   entry(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   <lambda>  s   c         S` s   t  |  t j  S(   N(   R&   R   RI  (   RJ  (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRK  :  s   Rt   t   scanOp_save_mem(I   R   Rg   RE  t   shape_ofR   R'   R-   R.   R0   R4   R   R,   R   R   R/   R3   R}   R9   R)   R>   R   R   t   strR&   R   R   R   R2   R   t   KeyErrorR   t   get_canonical_form_slicet   slicet   stopt   basicR   R   RI  R   RA  t   startRw   t   configt   scant   allow_output_preallocRE   R*   RF   R   t   scan_can_remove_outsR#   R   t   IncSubtensorRC  t   switchR   t   list_opt_sliceR   t   expand_emptyR=   R1   t   compress_outsR   R   R(   RD   t   stept   tuplet   collapseR   R   t   anyR   (O   Rd   Rg   RG   R@  RB  RD  RM  R'   t   c_outsRI   t   init_lR   t   global_nstepst   ot   slicest   store_stepst
   flag_storeR\   R   t   clt   _t
   this_slicet   lengtht   cf_sliceRR  t   nw_stepst	   sym_stepsR:  t
   real_stepsRT  t   prealloc_outst   first_mitsot_idxt   last_sitsot_idxt   preallocable_outputt   pvalt   orphane_outst   old_outputst	   nw_inputst   requiredt   not_requiredt   replaced_outst   offsetRT   t   _valt   valt	   _nw_inputt   cvalt   initlt   tmp_idxt   tmpt   nw_inputR   R=  t   in_idxt   inpst   outsR!   t   node_inst   compress_mapt   inv_compress_mapR   R  t   old_newt   slt   hdxt	   cnf_slicet
   old_slicest   fslicet   nw_slicet   nw_post   subtenst   sl_inst   new_ot   old_outst   oldt   positiont   newt   old_scan_is_usedR%   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRj   E  s.   				
	"3&"* 



		
		 



	$
*
 *					5	< 
			$	
"#
	)
!$		
+"	c         C` sY   g  | j    D]! } t | j t j  r | ^ q } x | D] } |  j | |  q; Wd  S(   N(   Ri   R&   R'   R   R(   Rj   (   Rd   Rg   RI   Rk   RG   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl   T  s    (   R   R   R   Rc   Rh   Rj   Rl   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR>  9  s   			  t	   ScanMergec           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s:   
    Graph Optimizer that merges different scan ops.

    c         C` s   | j  t j j    d  S(   N(   Re   R   R   Rf   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh   b  s    c         C` s	  | d j  j r- t } | d j  j d } n t } t   } g  | d <t g  | D] } | j  j ^ qP  | d <t g  | D] } | j  j ^ qy  | d <t g  | D] } | j  j	 ^ q  | d <g  | d <t g  | D] } | j  j
 ^ q  | d <t g  | D] } | j  j ^ q  | d	 <t g  | D] } | j  j ^ q' | d
 <t g  | D] } | j  j ^ qP | d <| d j  j | d <d j g  | D] } | j  j ^ q | d <| d j  j | d <t | d <| | d <| d j  j | d <| d j  j | d <g  | D] } g  ^ q} g  } g  | D] } g  ^ q%} g  }	 d   }
 xh t |  D]Z \ } } | | j |
 | j  j | j  j  |   | |
 | j  j | j  |  7} qSWx t |  D] \ } } | | j |
 | j  j | j  j  |   | | j | j  j | j  j   | d c | j  j   7<| d c | j  j   7<| |
 | j  j | j  |  7} |	 | j  j | j  7}	 qWx t |  D] \ } } | | j |
 | j  j | j  j  |   | | j | j  j  | j  j   | d c | j  j!   7<| |
 | j  j" | j  |  7} |	 | j  j# | j  7}	 qWx t |  D] \ } } | | j |
 | j  j$ | j  j  |   | d c g  t% | j  j  D] } d g ^ q7<| | j | j  j& | j  j   | |
 | j  j' | j  |  7} |	 | j  j( | j  7}	 qWWxh t |  D]Z \ } } | | j |
 | j  j) | j  j  |   | |
 | j  j* | j  |  7} q0Wxx t |  D]j \ } } | | j | j  j+ | j  j   | |
 | j  j, | j  |  7} |	 | j  j- | j  7}	 qWxV t |  D]H \ } } |	 | j  j. | j  7}	 | | j | j  j/ | j  j   qWxh t |  D]Z \ } } | | j |
 | j  j0 | j  j  |   | |
 | j  j1 | j  |  7} qoW| d j d g | } | r| d j | g  n  x
t |  D] \ } } t | | g   } t | | g   } t2 j3 | |  \ } } g  } d } x@ | | D]4 } t4 |  } | j | | | | ! | | 7} qpWg  } d } x@ | | D]4 } t4 |  } | j | | | | ! | | 7} qW| | | <| | | <qWg  } g  } t4 | d  } t4 | d  } x t |  D]y \ } } t4 | |  | k spt5  | r| d k rt4 | |  | d k st5  qHt4 | |  | k sHt5  qHWxC t6 |  D]5 } x, t |  D] \ } } | | | | 7} qWqWxh t6 |  D]Z } xQ t |  D]C \ } } | r\	| d k r\	| | d k r\	q+	| | | | 7} q+	Wq	Wt7 j8 | | |  } | |   } t9 | t: t; f  s	| g } n  t: t< |	 |   S(   Ni    iR,   R#   R-   t   n_mit_mot_outst   mit_mot_out_slicesR.   R0   R1   R4   t   truncate_gradientt   &t   namet   modeR+  R   t   profilet   allow_gcc         S` s6   x/ |  D]' } | j  r | j  t |  7_  q q W|  S(   N(   R  RN  (   R   t   suffixR   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   rename  s    	i   (=   R'   R   RE   R3   R)   R   R+   R#   R-   R  R.   R0   R1   R4   R  R   R  R  R  R  R>   R=   R{   R2   R|   t   inner_mitmott   inner_mitmot_outst   mitmot_tapst   mitmot_out_tapsR   t   outer_mitmot_outst   inner_mitsotR   R   R   t   outer_mitsot_outst   inner_sitsotR   R   R   t   outer_sitsot_outst   inner_sharedR!  R   R"  t   outer_nitsot_outst   outer_shared_outst   inner_shared_outsRz   RN   R   Rv   R/   R}   R   R   R(   R&   RF   R_  R?   (   Rd   R3  R   t	   conditionR!   R   t	   inner_inst	   outer_inst
   inner_outst
   outer_outsR  RT   RI   t   flat_inner_inst   flat_inner_outst   new_inner_inst   countt   nlt   seq_lent   new_inner_outst   nb_ins_groupst   nb_outs_groupst   gr_idxR)  R  (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   mergee  s    	
)))
)))),

	,&
"#"
"#"
"2#"
"&#"'
"&
# "c   
      C` sm  | d } | j  j | j  j k sR | j  j | j  j k sR | j  j | j  j k rV t S| j d } y t t |   } Wn t j	 k
 r n X| j d } y t t |   } Wn t j	 k
 r n Xx0 | D]( } t
 | |  s t
 | |  r t Sq W| j  j s| | k S| j  j d } | j  j d } t j | g | g | j  j | j  j  }	 |	 ol| | k S(   s  
        This function checks if node `node` belongs to `set_nodes`, in the
        sense that it can be merged together with every other node in
        `set_nodes`. In order for two nodes to be mergeable, they have to go
        over the same number of steps, have the same condition (if any),
        have the same value for truncate_gradient, and have the same mode.
        Questionable, we should also consider profile ?

        i    i(   R'   R   R  R  R)   R2   R*   R   R   t   NotScalarConstantErrorR   R3   R   R   (
   Rd   RG   t	   set_nodest   rept   nstepst
   rep_nstepsR   t   condt   rep_condt	   same_cond(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   belongs_to_set  s4    


	c   	      C` s  g  | j    D]! } t | j t j  r | ^ q } g  } x} | D]u } d } x6 t |  D]( \ } } |  j | |  rZ | } PqZ qZ W| d k r | j | g  qA | | j |  qA WxK | D]C } t |  d k r |  j	 |  } | j
 | d | d d q q Wd  S(   Nii   R%   Rt   t   scanOp_merge(   Ri   R&   R'   R   R(   R>   R  R=   R/   R  R   (	   Rd   Rg   R   R4  t   all_setst   belongs_to_set_idxR=  t   subsett   proposal(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl   6  s$    !(   R   R   R   Rh   R  R  Rl   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR  \  s
   			*c         C` s   t  t |    t  |   k  S(   sF   
    Returns true if l has any duplicates (according to __eq__).

    (   R/   Ry   (   t   l(    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   has_duplicatesW  s    c         C` sr   t    } g  } g  } xP t |  |  D]? \ } } | | k rZ | | g 7} | | g 7} q% | | | <q% W| | f S(   s   
    Builds a dictionary of equivalences between inner inputs based on
    the equivalence of their corresponding outer inputs.

    (   R   R?   (   t   lot   lit   seenot   leftt   rightRe  R\   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt
   make_equiv_  s    	c   -      ` sf  t  |  j t j  s t St |  j |  j |  j j |  j j |  j j  } t	   } t
 | j  r g  } g  } xi t | j | j  D]R \ } } | | k r | j |  } | | | | <q | j |  | j |  q W| | _ | | _ n  t
 | j  rg  } g  }	 xi t | j | j  D]R \ }
 } |
 | k rW| j |
  } |	 | | | <q| j |
  |	 j |  qW| | _ |	 | _ n  t |  d k rD| j } | j } | j } | j } t j | d | } t j | | |  } | |   } t  | t t f  s| g } n  t | | | j | j | j  } |  g } n | } g  } g    g   t
 | j  rt | j | j  \ } }   | 7   | 7 n  t
 | j  rt | j | j  \ } }   | 7   | 7 n  t
 | j  r}t	   } x t | j | j  | j!  D]d \ } } } t |  } | | f | k rf| | | f }   | 7   | 7 q| | | | f <qWn  t
 | j"  rt	   } x t | j" | j# | j$  D]d \ } } } t |  } | | f | k r| | | f }   | 7   | 7 q| | | | f <qWn     f d   }  g  } t | j%  t | j&  k sXt'  t | j&  t | j(  k s|t'  g  t | j% | j& | j(  D]$ \ }! }" }# |  |! |" |# |  ^ q| _( g  } t | j  t | j)  k st'  t | j)  t | j*  k st'  g  t | j | j) | j*  D]$ \ }! }" }# |  |! |" |# |  ^ q/| _* g  } t | j"  t | j+  k st'  t | j+  t | j,  k st'  g  t | j" | j+ | j,  D]$ \ }! }" }# |  |! |" |# |  ^ q| _, g  } g  }$ t | j  t | j-  k s#t'  t | j-  t | j.  k sGt'  t | j.  t | j/  k skt'  x t | j | j- | j. | j/  D] \ }% }& }' }( x~ | D]P \ }) }* }+ }, |( |, k rt0 |& |*     r|% |) k r|$ j |+  PqqW| j |% |& |' |( f  |$ j |'  qW|$ | _. | r_t	 d | f g t t |  j | j1    S| j1 S(   Ni    R"   c         ` s_   xB | D]: \ } } } t  | g | g     r |  | k r | Sq W| j |  | | f  | S(   N(   R   R=   (   t   outer_it   inner_ot   outer_ot   seent	   s_outer_it	   s_inner_ot	   s_outer_o(   R  R  (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   map_out  s    R%   (2   R&   R'   R   R(   R)   R   R2   R3   R!   R   R  R  R?   R   R<   R=   R  R   R/   R   R  R   R   R:   RF   R_  t   outer_in_sharedR  t   inner_in_sharedR   R   t   outer_in_mit_mott   inner_in_mit_mott   mit_mot_in_slicest   outer_in_mit_sott   inner_in_mit_sott   mit_sot_in_slicesR  R  R}   R  R   R   t   inner_out_mit_sott   outer_out_mit_sott   inner_out_mit_mott   outer_out_mit_motR  R   R  (-   RG   t   at	   inp_equivt   new_outer_seqst   new_inner_seqst   out_seqt   in_seqR\   t   new_outer_nseqst   new_inner_nseqst   out_nseqt   in_nseqR   R  R!   t   a_inner_outsR   R'   R3   t   naR%   t   _leftt   _rightR  t   ommt   immt   _slR  t   simmt   omst   imst   simsR  R  R  R  t   new_outer_out_mit_mott	   outer_immt	   inner_ommt	   outer_ommt   oslt   s_outer_immt   s_inner_ommt   s_outer_ommt   sosl(    (   R  R  s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   scan_merge_inoutsq  s    !	"	"					!

	
	
$$	7$$	7$$	7$$$	t   PushOutDot1c           B` s2   e  Z d  Z d   Z d   Z d   Z d   Z RS(   s:   
    Graph optimizer for Scan(makes it run inplace).

    c         C` s   t  j |   d  S(   N(   R   Rc   (   Rd   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRc     s    c         C` s   | j  t j    d  S(   N(   Re   R   Rf   (   Rd   Rg   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRh   !  s    c         C` s_   | j    } g  | D]! } t | j t j  r | ^ q } x | D] } |  j | |  qA Wd  S(   N(   Ri   R&   R'   R   R(   t	   apply_opt(   Rd   Rg   R3  RI   R4  RG   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyRl   $  s    .c   6      C` s3  | j  } | j | j  } | j | j  } | j |  } | j | j  } xt | | |  D]\ } }	 }
 |	 j ra t	 |	 j j  t
 j j  ra t	 |	 j j  j t
 j j  ra | |	 j j k ra t |
 j  d k ra t	 |
 j d d t  ra t	 |
 j d d j  t
 j j  ra |
 j d d j  j d k ra |	 j j d } | | k rc|	 j j d } n  | j r+t	 | j j  t
 j j  r+| j j d j d k r+| j j d j d k r+| j j d } | j j d } | | k s| | k r(| } | | k r| } n  | j |	  } | j | j  } | j |  } | j | j  } | j |  } | j | j  } | j | j  } | j |  } | j | j  } | j | j  } | j |  } | j | j  } | j  |  } | j! | j  } | j" | j  } | j# |  } | j$ | j  } | j% | j  } | j& |  }  | j' j(   }! t | j)    t | j*    }" |! d |" |  |! d |" | d |! d <|! d c d 8<|! d c d 7<| |  | | d } | |  | | d } | |  | | d } | j+ |  | | | | | | }# | | | | | }$ t, j- |# |$  \ }% }& t. j/ |% |& |!  }' | j d g | | | | | | | j d g |  }( |' |(   }) t0 |)  t1 t2 f k r|) g }) n  |' j3 |)  }* |* d }+ |* d  }* | | k r| j |  | j |  }, |, | j d  }, |, j4 d }- |, j4 d }. |, j4 d }/ |, j5 d d d  }0 |0 j6 |. |- |/ f  }0 |+ j4 d }- |+ j4 d }. |+ j4 d }/ |+ j6 |- |. |/ f  }1 t j7 |0 |1  }2 n | j |  | j |  }, |, j6 |, j4 d |, j4 d |, j4 d f  }0 |+ j5 d d d  j6 |+ j4 d |+ j4 d |+ j4 d f  }1 t j7 |1 |0  }2 | j j |
  }3 t1 t | j |3  |) |3    }4 | j |3 j d d j d }5 |4 j+ |5 |2 f  |4 t1 t | j |3 d |) |3   7}4 | j8 |4 d | g d	 d
 q(q+qa qa Wd  S(   Ni   i    ii   R,   R0   R4   R%   Rt   t   scan_pushout_dot1(   i(9   R'   R  R2   R   R3   R  R{   R?   R   R&   Rw   R   R   R   R   R   R/   R   RN  R   R   R   R   R<   R|   R  R   R  R  R   R   R   R"  R   R  R!  R  Rz   RN   R!   RB   R  R   R=   R   Rv   R   R(   R   RF   R_  R  R   R   R   R   R   (6   Rd   Rg   RG   R'   t
   sitsot_inst   sitsot_outsR   t   seqsR   R   t	   outer_outRI   t   inp1t   inp2t   new_scan_outRT   R{   R|   R  R   R  R  R   R   R  R   R"  R   R  R!  R  Rz   RN   t   new_infoRH   t   _new_inner_inpst   _new_inner_outst   new_inner_inpsR  R)  t   _scan_inputsR  R  R}  t   _out_seqt   sh0t   sh1t   sh2R  R~  t   new_outR=  R  R  (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR  +  s    	"	#$2	"		3


 (   R   R   R   Rc   Rh   Rl   R  (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyR    s
   			t   scan_eqopt1g?t   fast_runRV  t   scan_eqopt2g?RL  g(\?R   R  R  iK   t   inplacet   all_pushout_opti   t*   scanOp_remove_constants_and_unused_inputs0t   ignore_newtreesRa   Ru   i   R   i   R  i   t   more_memR   i   t   constant_folding_for_scan2t*   scanOp_remove_constants_and_unused_inputs1R  t*   scanop_remove_constants_and_unused_inputs2t   scanOp_merge_inoutsi   R  t*   scanOp_remove_constants_and_unused_inputs3i   (R   R   t
   __future__R    R   R   t   loggingRB   t   sysR   t   collectionsR   R   Rw   R   R   t   theano.tensorR   R   R	   R
   R   t   sixR   R   t	   six.movesR   t   theano.compileR   t   theano.compile.function_moduleR   t
   theano.gofR   R   R   t   theano.gof.optR   R   R   t   theano.scan_moduleR   R   t   theano.scan_module.scan_utilsR   R   R   t   __docformat__t   __authors__t   __copyright__t   __contact__t	   getLoggerR   t   local_abs_merget   local_mul_switch_sinkt%   local_upcast_elemwise_constant_inputst   local_useless_switcht   constant_foldingR[  R   R!   t   local_optimizerR(   Ra   Rb   R   R   R  R>  R  R  R  R  R  t   EquilibriumDBR   t
   SequenceDBt   scan_seqopt1R"  t   registerR9   R)   t   in2outRE   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/scan_module/scan_opt.pyt   <module>3   s   "						m  %														