
    j8                     p   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 Zd Zd Z G d d	e          Z G d
 de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdS )    N)
accumulate)OptionalTupleUnion)Modulec                     t          | t          t          f          r1t          |           |k    rt	          |          t          |           S t          | t
                    st	          |          | g|z  S )N)
isinstancelisttuplelen
ValueErrorint)xnmsgs      _/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/mlx/nn/layers/pooling.py_value_or_listr      sg    !dE]## q66Q;;S//!Awwa oo37N    c                    |d         g}t          |dd          |          D ]2\  }}|                    ||z             |                    |           3|                    |d                    t          |          dz
  }dgt          d|d          t          d|d          |}|                     |          } |                     |          } | S )Nr         )zipappendr   rangereshape	transpose)r   shapewindow_shape	new_shapesw	last_axis
axis_orders           r    _non_overlapping_sliding_windowsr%      s    q
IE!""I|,,  1a   U2YI"IQeAy!,,QuQ	1/E/EQyQJ			)A	JAHr   c                    | j         dk     rt          d| j          d          | j        dd         }t          |          t          |          cxk    rt          |          k    sBn t          dt          |           dt          |           dt          |           d	          | j        }t	          d
 t          |||          D                       rt          | ||          S t          t          t          t          t          |dz             t          j                                                dd          }|d         g}|d t          |||          D             z  }||z  }||d         gz  }|d d         }|d t          |dd         |          D             z  }||dd         z  }||dd          z  }t          j        | ||          S )N   zcTo extract sliding windows at least 1 spatial dimension (3 total) is needed but the input only has z dimensions.r   r   zTo extract sliding windows the window shapes and strides must have the same number of spatial dimensions as the signal but the signal has z dims and the window shape has z and strides have .c              3   <   K   | ]\  }}}||k    o||z  d k    V  dS r   N .0sizewindowstrides       r   	<genexpr>z#_sliding_windows.<locals>.<genexpr>8   sO         D&& 	&/TF]a/     r   r   r   c                 ,    g | ]\  }}}||z
  |z  d z   S r2   r+   r,   s       r   
<listcomp>z$_sliding_windows.<locals>.<listcomp>B   s<        D&& 
6!A%  r   c                     g | ]
\  }}||z  S r+   r+   )r-   	og_strider0   s      r   r4   z$_sliding_windows.<locals>.<listcomp>K   s.       0y&	F  r   )ndimr   r   r   allr   r%   r
   reversedr   operatormulmx
as_strided)r   r   window_stridesspatial_dimsr   stridesfinal_shapefinal_stridess           r   _sliding_windowsrC   '   sV   vzzO:;&O O O
 
 	

 71R4=L\!2!2IIIIc.6I6IIIII7|$$7 7EHEVEV7 7 !$N 3 37 7 7
 
 	
 GE
  $'lN$S$S     H 05,GGG8DHUT\,B,BHL!Q!QRRSSTTUVUWUWXG 8*K  $'lN$S$S   K <KE"I;K BQBKM  47"~4V4V   M WQrT]"MWRSS\!M=K777r   c                   *     e Zd Z fdZd Zd Z xZS )_Poolc                     t                                                       || _        || _        || _        || _        || _        t          t          t          | j                   dz
  dd                    | _
        d S )Nr   r   )super__init___pooling_function_kernel_size_stride_padding_padding_valuer   r   r   _axes)selfpooling_functionkernel_sizer0   paddingpadding_value	__class__s         r   rH   z_Pool.__init__U   sq    !1'+5#d&7"8"8!81!<b!DDEE


r   c                     t          | j                  }t          | j                  }t          d | j        D                       }d| d| d| S )Nc              3   &   K   | ]}|d          V  dS r*   r+   r-   ps     r   r1   z$_Pool._extra_repr.<locals>.<genexpr>b   s&      //A1Q4//////r   zkernel_size=z	, stride=z
, padding=)r   rJ   rK   rL   )rO   ksstpds       r   _extra_reprz_Pool._extra_repr_   s]    4$%%4<  ///////=b==2=====r   c                     t          d | j        D                       r)t          j        |dg| j        z   dgz   | j                  }t          || j        | j                  }|                     || j	                  S )Nc              3   .   K   | ]}|d          d k    V  dS r*   r+   rW   s     r   r1   z!_Pool.__call__.<locals>.<genexpr>g   s*      //Aqtax//////r   )r   r   )constant_values)
anyrL   r<   padrM   rC   rJ   rK   rI   rN   )rO   r   s     r   __call__z_Pool.__call__f   s    /////// 	4=(F83 $ 3  A
 Q 14<@@%%a444r   )__name__
__module____qualname__rH   r\   rb   __classcell__rT   s   @r   rE   rE   T   s[        F F F F F> > >5 5 5 5 5 5 5r   rE   c            
            e Zd Z	 	 ddeeee         f         deeeee         f                  deeee         f         f fdZ xZS )_Pool1dNr   rQ   r0   rR   c                 ~   t          |           j        }d}t          |d|                    |d                    }|&t          |d|                    |d                    }n|}t          |d|                    |d                    }d |D             }t	                                          |||||           d S )Nz<[{}] '{}' must be an integer or a tuple containing 1 integerr   rQ   r0   rR   c                     g | ]}||fS r+   r+   rW   s     r   r4   z$_Pool1d.__init__.<locals>.<listcomp>       +++aAq6+++r   typerc   r   formatrG   rH   	rO   rP   rS   rQ   r0   rR   
class_namer   rT   s	           r   rH   z_Pool1d.__init__r   s     $ZZ(
L$CJJz=AA
 
 #FAszz*h/O/OPPFF F !SZZ
I-N-NOO++7+++);WWWWWr   Nr   	rc   rd   re   r   r   r   r   rH   rf   rg   s   @r   ri   ri   q   s         48*+X X 3c
?+	X
 sE#J/0X sE#J'X X X X X X X X X Xr   ri   c                        e Zd Z	 	 ddeeeeef         f         deeeeeef         f                  deeeeeef         f                  f fdZ xZS )_Pool2dNr   rQ   r0   rR   c                 ~   t          |           j        }d}t          |d|                    |d                    }|&t          |d|                    |d                    }n|}t          |d|                    |d                    }d |D             }t	                                          |||||           d S )Nz=[{}] '{}' must be an integer or a tuple containing 2 integersr   rQ   r0   rR   c                     g | ]}||fS r+   r+   rW   s     r   r4   z$_Pool2d.__init__.<locals>.<listcomp>   rl   r   rm   rp   s	           r   rH   z_Pool2d.__init__        $ZZ(
M$CJJz=AA
 
 #FAszz*h/O/OPPFF F !SZZ
I-N-NOO++7+++);WWWWWr   rr   rs   rg   s   @r   ru   ru      s         9=9:X X 3c3h/0	X
 sE#s(O345X %U38_ 456X X X X X X X X X Xr   ru   c                        e Zd Z	 	 ddeeeeeef         f         deeeeeeef         f                  deeeeeeef         f                  f fdZ xZS )_Pool3dNr   rQ   r0   rR   c                 ~   t          |           j        }d}t          |d|                    |d                    }|&t          |d|                    |d                    }n|}t          |d|                    |d                    }d |D             }t	                                          |||||           d S )Nz=[{}] '{}' must be an integer or a tuple containing 3 integersr'   rQ   r0   rR   c                     g | ]}||fS r+   r+   rW   s     r   r4   z$_Pool3d.__init__.<locals>.<listcomp>   rl   r   rm   rp   s	           r   rH   z_Pool3d.__init__   rx   r   rr   rs   rg   s   @r   rz   rz      s         >B>?X X 3c3m 445	X
 sE#sC-$889:X %U3S=%9 9:;X X X X X X X X X Xr   rz   c            
            e Zd ZdZ	 	 ddeeee         f         deeeee         f                  deeee         f         f fdZ xZ	S )		MaxPool1da,  Applies 1-dimensional max pooling.

    Spatially downsamples the input by taking the maximum of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    Args:
        kernel_size (int or tuple(int)): The size of the pooling window kernel.
        stride (int or tuple(int), optional): The stride of the pooling window.
            Default: ``kernel_size``.
        padding (int or tuple(int), optional): How much negative infinity
            padding to apply to the input. The padding amount is applied to
            both sides of the spatial axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(4, 16, 5))
        >>> pool = nn.MaxPool1d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                     t                                          t          j        t	          d           |||           d S NinfrG   rH   r<   maxfloatrO   rQ   r0   rR   rT   s       r   rH   zMaxPool1d.__init__   5     	%,,VWMMMMMr   rr   
rc   rd   re   __doc__r   r   r   r   rH   rf   rg   s   @r   r~   r~      s         0 48*+	N N3c
?+N sE#J/0N sE#J'	N N N N N N N N N Nr   r~   c            
            e Zd ZdZ	 	 ddeeee         f         deeeee         f                  deeee         f         f fdZ xZ	S )		AvgPool1da#  Applies 1-dimensional average pooling.

    Spatially downsamples the input by taking the average of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    Args:
        kernel_size (int or tuple(int)): The size of the pooling window kernel.
        stride (int or tuple(int), optional): The stride of the pooling window.
            Default: ``kernel_size``.
        padding (int or tuple(int), optional): How much zero padding to apply to
            the input. The padding amount is applied to both sides of the spatial
            axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(4, 16, 5))
        >>> pool = nn.AvgPool1d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                 f    t                                          t          j        d|||           d S rr   rG   rH   r<   meanr   s       r   rH   zAvgPool1d.__init__   -     	![&'BBBBBr   rr   r   rg   s   @r   r   r      s         0 48*+	C C3c
?+C sE#J/0C sE#J'	C C C C C C C C C Cr   r   c                        e Zd ZdZ	 	 ddeeeeef         f         deeeeeef         f                  deeeeeef         f                  f fdZ xZ	S )		MaxPool2da  Applies 2-dimensional max pooling.

    Spatially downsamples the input by taking the maximum of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    The parameters ``kernel_size``, ``stride``, and ``padding`` can either be:

    * a single ``int`` -- in which case the same value is used for both the
      height and width axis.
    * a ``tuple`` of two ``int`` s -- in which case, the first ``int`` is
      used for the height axis, the second ``int`` for the width axis.

    Args:
        kernel_size (int or tuple(int, int)): The size of the pooling window.
        stride (int or tuple(int, int), optional): The stride of the pooling
            window. Default: ``kernel_size``.
        padding (int or tuple(int, int), optional): How much negative infinity
            padding to apply to the input. The padding is applied on both sides
            of the height and width axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(8, 32, 32, 4))
        >>> pool = nn.MaxPool2d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                     t                                          t          j        t	          d           |||           d S r   r   r   s       r   rH   zMaxPool2d.__init__  r   r   rr   r   rg   s   @r   r   r      s         > 9=9:	N N3c3h/0N sE#s(O345N %U38_ 456	N N N N N N N N N Nr   r   c                        e Zd ZdZ	 	 ddeeeeef         f         deeeeeef         f                  deeeeeef         f                  f fdZ xZ	S )		AvgPool2da|  Applies 2-dimensional average pooling.

    Spatially downsamples the input by taking the average of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    The parameters ``kernel_size``, ``stride``, and ``padding`` can either be:

    * a single ``int`` -- in which case the same value is used for both the
      height and width axis.
    * a ``tuple`` of two ``int`` s -- in which case, the first ``int`` is
      used for the height axis, the second ``int`` for the width axis.

    Args:
        kernel_size (int or tuple(int, int)): The size of the pooling window.
        stride (int or tuple(int, int), optional): The stride of the pooling
            window. Default: ``kernel_size``.
        padding (int or tuple(int, int), optional): How much zero
            padding to apply to the input. The padding is applied on both sides
            of the height and width axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(8, 32, 32, 4))
        >>> pool = nn.AvgPool2d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                 f    t                                          t          j        d|||           d S rr   r   r   s       r   rH   zAvgPool2d.__init__:  r   r   rr   r   rg   s   @r   r   r     s         > 9=9:	C C3c3h/0C sE#s(O345C %U38_ 456	C C C C C C C C C Cr   r   c                        e Zd ZdZ	 	 ddeeeeeef         f         deeeeeeef         f                  deeeeeeef         f                  f fdZ xZ	S )		MaxPool3da  Applies 3-dimensional max pooling.

    Spatially downsamples the input by taking the maximum of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    The parameters ``kernel_size``, ``stride``, and ``padding`` can either be:

    * a single ``int`` -- in which case the same value is used for the depth,
      height, and width axis.
    * a ``tuple`` of three ``int`` s -- in which case, the first ``int`` is used
      for the depth axis, the second ``int`` for the height axis, and the third
      ``int`` for the width axis.

    Args:
        kernel_size (int or tuple(int, int, int)): The size of the pooling window.
        stride (int or tuple(int, int, int), optional): The stride of the pooling
            window. Default: ``kernel_size``.
        padding (int or tuple(int, int, int), optional): How much negative infinity
            padding to apply to the input. The padding is applied on both sides
            of the depth, height and width axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(8, 16, 32, 32, 4))
        >>> pool = nn.MaxPool3d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                     t                                          t          j        t	          d           |||           d S r   r   r   s       r   rH   zMaxPool3d.__init__a  r   r   rr   r   rg   s   @r   r   r   C  s         @ >B>?	N N3c3m 445N sE#sC-$889:N %U3S=%9 9:;	N N N N N N N N N Nr   r   c                        e Zd ZdZ	 	 ddeeeeeef         f         deeeeeeef         f                  deeeeeeef         f                  f fdZ xZ	S )		AvgPool3da  Applies 3-dimensional average pooling.

    Spatially downsamples the input by taking the average of a sliding window
    of size ``kernel_size`` and sliding stride ``stride``.

    The parameters ``kernel_size``, ``stride``, and ``padding`` can either be:

    * a single ``int`` -- in which case the same value is used for the depth,
      height, and width axis.
    * a ``tuple`` of three ``int`` s -- in which case, the first ``int`` is used
      for the depth axis, the second ``int`` for the height axis, and the third
      ``int`` for the width axis.

    Args:
        kernel_size (int or tuple(int, int, int)): The size of the pooling window.
        stride (int or tuple(int, int, int), optional): The stride of the pooling
            window. Default: ``kernel_size``.
        padding (int or tuple(int, int, int), optional): How much zero
            padding to apply to the input. The padding is applied on both sides
            of the depth, height and width axis. Default: ``0``.

    Examples:
        >>> import mlx.core as mx
        >>> import mlx.nn.layers as nn
        >>> x = mx.random.normal(shape=(8, 16, 32, 32, 4))
        >>> pool = nn.AvgPool3d(kernel_size=2, stride=2)
        >>> pool(x)
    Nr   rQ   r0   rR   c                 f    t                                          t          j        d|||           d S rr   r   r   s       r   rH   zAvgPool3d.__init__  r   r   rr   r   rg   s   @r   r   r   j  s         @ >B>?	C C3c3m 445C sE#sC-$889:C %U3S=%9 9:;	C C C C C C C C C Cr   r   )r:   	itertoolsr   typingr   r   r   mlx.corecorer<   mlx.nn.layers.baser   r   r%   rC   rE   ri   ru   rz   r~   r   r   r   r   r   r+   r   r   <module>r      s                ) ) ) ) ) ) ) ) ) )       % % % % % %	 	 	   *8 *8 *8Z5 5 5 5 5F 5 5 5:X X X X Xe X X X0X X X X Xe X X X0X X X X Xe X X X0N N N N N N N N>C C C C C C C C>#N #N #N #N #N #N #N #NL#C #C #C #C #C #C #C #CL$N $N $N $N $N $N $N $NN$C $C $C $C $C $C $C $C $C $Cr   