ó
àÆ÷Xc           @` sp  d  d l  m Z m Z m Z d  d l 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 d  d l j j Z d „  Z d e f d	 „  ƒ  YZ e e ƒ Z d
 e f d „  ƒ  YZ e e ƒ Z d d d d „ Z d „  Z e j re e d  g ƒ e e d  d g ƒ n  e j j e e g ƒ d „  ƒ Z e j j j  d e
 e d e
 j! ƒd d d ƒ d S(   i    (   t   absolute_importt   print_functiont   divisionN(   t   DisconnectedType(   t   Opt   Applyt   TopoOptimizer(   t   copy_stack_trace(   t   tensorc         C` sÓ   t  | ƒ } t  | ƒ } |  j | |  j | k  rA t d ƒ ‚ n  t d ƒ g |  j } t |  j | d d d ƒ | | <|  j t | ƒ ƒ } t | j	 ƒ } |  j | d k rÏ | | c | | 8<| | _	 n  | S(   s—   
    Helper function for DiagonalSubtensor and IncDiagonalSubtensor.

    Notes
    -----
    It returns a partial view of x, not a partial copy.

    s   is this allowed?i   N(
   t   intt   shapet   NotImplementedErrort   slicet   Nonet   ndimt   __getitem__t   tuplet   listt   strides(   t   xt   i0t   i1t   idxt   xviewR   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   get_diagonal_subtensor_view
   s    !t   DiagonalSubtensorc           B` sM   e  Z d  Z d Z d „  Z e d „ Z d „  Z d „  Z d „  Z	 d „  Z
 RS(	   s_  
    Return a form a nd diagonal subtensor.

    Parameters
    ----------
    x
        n-d tensor
    i0
        Axis index in x
    i1
        Axis index in x

    Notes
    -----
    Work on the GPU.

    Extended summary
    ----------------
    ``x`` is some n-dimensional tensor, but this Op only deals with a
    matrix-shaped slice, using axes i0 and i1. Without loss of
    generality, suppose that ``i0`` picks out our ``row`` dimension,
    and i1 the ``column`` dimension.

    So the relevant part of ``x`` is some matrix ``u``. Suppose it has 7 rows
    and 4 columns::

        [ 0 0 0 0 ]
        [ 0 0 0 0 ]
        [ 0 0 0 0 ]
        [ 0 0 0 0 ]
        [ 0 0 0 0 ]
        [ 0 0 0 0 ]

    The view returned by this function is also a matrix. It's a thick,
    diagonal ``stripe`` across u that discards the lower left triangle
    and the upper right triangle:

        [ x 0 0 0 ]
        [ x x 0 0 ]
        [ x x x 0 ]
        [ 0 x x x ]
        [ 0 0 x x ]
        [ 0 0 0 x ]

    In this case the return value would be this view of shape 3x4. The
    returned view has the same number of dimensions as the input
    ``x``, and the only difference is that the shape along dimension
    ``i0`` has been reduced by ``shape[i1] - 1`` because of the
    triangles that got chopped out.

    The NotImplementedError is meant to catch the case where shape[i0]
    is too small for the stripe to reach across the matrix, in which
    case it's not clear what this function should do. Maybe always
    raise an error. I'd look back to the call site in the Conv3D to
    see what's necessary at that point.

    t   inplacec         C` s%   |  j  r d |  j j Sd |  j j S(   Ns   %s{inplace}s   %s(   R   t	   __class__t   __name__(   t   self(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   __str__`   s    	c         C` s)   | |  _  | r% i d g d 6|  _ n  d  S(   Ni    (   R   t   view_map(   R   R   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   __init__e   s    	c         C` s@   t  j | ƒ } t  j | ƒ } t |  | | | g | j ƒ  g ƒ S(   N(   R   t   as_tensor_variableR   t   type(   R   R   R   R   t   _i0t   _i1(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt	   make_nodej   s    c         C` s>   t  | Œ  } |  j r& | | d d <n | j ƒ  | d d <d  S(   Ni    (   R   R   t   copy(   R   t   nodet   inputst   output_storageR   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   performo   s    	c         C` sM   t  j | d ƒ } t | | d | d | d ƒ } | t ƒ  ƒ  t ƒ  ƒ  g S(   Ni    i   i   (   R   t
   zeros_liket   inc_diagonal_subtensorR   (   R   R(   t	   g_outputst   zt   gx(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   gradv   s    !c         C` s   t  g t g t g g } | S(   N(   t   Truet   False(   R   R'   t   rval(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   connection_pattern{   s    (   s   inplace(   R   t
   __module__t   __doc__t	   __props__R   R2   R    R%   R*   R0   R4   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR   #   s   9				t   IncDiagonalSubtensorc           B` sM   e  Z d  Z d Z d „  Z e d „ Z d „  Z d „  Z d „  Z	 d „  Z
 RS(	   s-   
    The gradient of DiagonalSubtensor.

    R   c         C` s%   |  j  r d |  j j Sd |  j j S(   Ns   %s{inplace}s   %s(   R   R   R   (   R   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR   Š   s    	c         C` s)   | |  _  | r% i d g d 6|  _ n  d  S(   Ni    (   R   t   destroy_map(   R   R   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR       s    	c         C` sC   t  j | ƒ } t  j | ƒ } t |  | | | | g | j ƒ  g ƒ S(   N(   R   R!   R   R"   (   R   R   R   R   t   amtR#   R$   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR%   ”   s    c   	      C` sX   | \ } } } } |  j  s* | j ƒ  } n  t | | | ƒ } | | 7} | | d d <d  S(   Ni    (   R   R&   R   (	   R   R'   R(   R)   R   R   R   R:   R   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR*   ™   s    	
c         C` sD   | \ } } } } | d } | t  ƒ  ƒ  t  ƒ  ƒ  t | | | ƒ g S(   Ni    (   R   t   diagonal_subtensor(   R   R(   R-   R   R   R   R:   t   gy(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR0   ¡   s    
c         C` s"   t  g t g t g t  g g } | S(   N(   R1   R2   (   R   R'   R3   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR4   §   s    (   s   inplace(   R   R5   R6   R7   R   R2   R    R%   R*   R0   R4   (    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyR8   ‚   s   				t   validc      
   C` s±  t  | t ƒ r! | | | f } n  | d k r9 |  j } n | } | d k rW | j } n | } | \ } } }	 }
 } | \ } } }	 } } | | |	 |
 | f } | | |	 | | f } | d | d k rÖ t d ƒ ‚ n  | } | } | d k r÷ d } n  | d k rd } n  t j j |  j | ƒ | j | ƒ d | d | d | d ƒ} | d d k rx|
 | d } | | d } n• | d d k r§|
 | d } | | d } nf | d d	 k rÞ|
 | d d } | | d d } n/ | d d
 k rút ƒ  ‚ n t	 d | d ƒ ‚ | j | | | | | | f ƒ } | d k r[| j | | | | | f ƒ } nR| d d k rtd } ni | d d k r‘| d } nL | d d	 k r®| d } n/ | d d
 k rÊt ƒ  ‚ n t	 d | d ƒ ‚ | d k r
t
 | d d ƒ j d d ƒ } n£ t j d | j d | | d | | | | | f ƒ } t j | d d … | | | … d d … d d … d d … d d … f | ƒ } t
 | d d ƒ j d d ƒ } | S(   s  
    Convolve spatio-temporal filters with a movie.

    It flips the filters.

    Parameters
    ----------
    signals
        Timeseries of images whose pixels have color channels.
        Shape: [Ns, Ts, C, Hs, Ws].
    filters
        Spatio-temporal filters.
        Shape: [Nf, Tf, C, Hf, Wf].
    signals_shape
        None or a tuple/list with the shape of signals.
    filters_shape
        None or a tuple/list with the shape of filters.
    border_mode
        One of 'valid', 'full' or 'half'.

    Notes
    -----
    Another way to define signals: (batch,  time, in channel, row, column)
    Another way to define filters: (out channel,time,in channel, row, column)

    For the GPU, you can use this implementation or
    :func:`conv3d_fft <theano.sandbox.cuda.fftconv.conv3d_fft>`.

    See Also
    --------
    Someone made a script that shows how to swap the axes between
    both 3d convolution implementations in Theano. See the last
    `attachment <https://groups.google.com/d/msg/theano-users/1S9_bZgHxVw/0cQR9a4riFUJ>`_

    i   i   s'   height and width bordermodes must matcht   input_shapet   filter_shapet   border_modeR=   t   fullt   halft   sames   invalid border modei    i   t   axist   dtypeR
   N(   t
   isinstancet   strR   R
   R   R   t   nnett   conv2dt   reshapet
   ValueErrorR;   t   sumt   zerosRE   t   set_subtensor(   t   signalst   filterst   signals_shapet   filters_shapeR@   t   _signals_shape_5dt   _filters_shape_5dt   Nst   Tst   Ct   Hst   Wst   Nft   Tft   Hft   Wft   _signals_shape_4dt   _filters_shape_4dt   conv2d_signal_shapet   conv2d_filter_shapet   out_4dt   Houtt   Woutt   out_tmpt   out_5dt   Tpadt   out_tmp_padded(    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   conv3d­   sv    '			!!	!#A	c         ` sT   t  j j ˆ  t j g ƒ ‡  ‡ f d †  ƒ } d ˆ  j | _ t j j ƒ  | ƒ d S(   s“  
    This function create optimizer that move some inputs to the GPU
    for op that work on both CPU and GPU.

    The op object is created by calling op(), so good default value
    are needed.

    We suppose the same op work with CPU and GPU inputs.

    Parameters
    ----------
    op
        The op that support GPU inputs.
    to_gpu
        A list of op inputs that are moved to the GPU.

    c         ` s\  t  ˆ  j ˆ ƒ rµ t ‡  f d †  ˆ Dƒ ƒ rµ t ˆ  j ƒ } x% ˆ D] } t j | | ƒ | | <qD Wˆ ƒ  | Œ  } t ˆ  j d | ƒ t j	 | ƒ } t ˆ  j d | ƒ | g Sn  ˆ  j t j k rXˆ  j d } | j
 rXt  | j
 j ˆ ƒ rX| j
 } t | j ƒ } x% ˆ D] } t j | | ƒ | | <qWˆ ƒ  | Œ  } t | | ƒ | g Sn  t S(   sj   
        op(host_from_gpu()) -> host_from_gpu(op)
        gpu_from_host(op) -> op(gpu_from_host)

        c         3` s>   |  ]4 } ˆ  j  | j o5 t ˆ  j  | j j t j ƒ Vq d  S(   N(   R(   t   ownerRF   t   opt   cudat   HostFromGpu(   t   .0R   (   R'   (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pys	   <genexpr>G  s   i    (   RF   Rk   t   anyR   R(   Rl   t   gpu_from_hostR   t   outputst   host_from_gpuRj   R2   (   R'   t   new_inpR   t   result_nodet   transfer_nodet
   host_inputt   op_nodet   new_node(   Rk   t   to_gpu(   R'   s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   local_to_gpu<  s.    
		
t   local_to_gpu_N(   t   theanot   goft   local_optimizerRl   Rp   R   t   optt   register_opt(   Rk   Ry   Rz   (    (   Rk   Ry   s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   make_gpu_optimizer*  s    -#i   c         C` sh   t  |  j t t f ƒ rd |  j j rd |  j j d t ƒ } | |  j Œ  } t |  j	 d | ƒ | g St
 S(   s#   Also work for IncDiagonalSubtensor.R   i    (   RF   Rk   R   R8   R   R   R1   R(   R   Rq   R2   (   R'   t   new_opRx   (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   local_inplace_DiagonalSubtensorg  s    Rƒ   t   failure_callbacki<   t   fast_runR   ("   t
   __future__R    R   R   R|   t   theano.gradientR   t
   theano.gofR   R   R   t   theano.gof.optR   R   t   theano.sandbox.cudat   sandboxRl   R   R   R2   R;   R8   R,   R   Ri   R   t   cuda_availableR}   R~   Rƒ   t   compilet   optdbt   registert   warn_inplace(    (    (    s;   /tmp/pip-build-X4mzal/theano/theano/tensor/nnet/conv3d2d.pyt   <module>   s0   	\({	8	!
	