
    GJj8                     2   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y)    N)
accumulate)OptionalTupleUnion)Modulec                     t        | t        t        f      r$t        |       |k7  rt	        |      t        |       S t        | t
              st	        |      | g|z  S )N)
isinstancelisttuplelen
ValueErrorint)xnmsgs      _/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx/nn/layers/pooling.py_value_or_listr      sM    !dE]#q6Q;S/!Awao37N    c                 P   |d   g}t        |dd  |      D ]*  \  }}|j                  ||z         |j                  |       , |j                  |d          t        |      dz
  }dgt        d|d      t        d|d      |}| j	                  |      } | j                  |      } | 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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(  s2n 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}|t        |||      D 	cg c]  \  }}}	||z
  |	z  dz    c}	}}z  }||z  }||d   gz  }|d d }
|
t        |dd |      D 	cg c]
  \  }}	||	z   c}	}z  }
|
|dd z  }
|
|dd  z  }
t        j                  | ||
      S c c}	}}w c c}	}w )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   B   K   | ]  \  }}}||k(  xr ||z  d k(    ywr   N ).0sizewindowstrides       r   	<genexpr>z#_sliding_windows.<locals>.<genexpr>8   s5      $S D&& 	&/TF]a//$Ss   )r   r   )ndimr   r   r   allr   r%   r
   reversedr   operatormulmx
as_strided)r   r   window_stridesspatial_dimsr   stridesfinal_shaper-   r.   r/   final_strides	og_strides               r   _sliding_windowsr>   '   s   vvz::;&&O
 	

 771R=L\!2Ic.6II|$%%DSEVDW X  #N 34A7
 	
 GGE
 $'lN$S  05,GG8DHUT\,BHLL!QRSTUVUWXG 8*K$'lN$S$S D&& 
6!A%$S K <KE"I;K BQKM47"~4V4V0y&	F4V M WQr]"MWRS\!M==K77s   "F!
%F(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            | _
        y )Nr   r   )super__init___pooling_function_kernel_size_stride_padding_padding_valuer   r   r   _axes)selfpooling_functionkernel_sizer/   paddingpadding_value	__class__s         r   rC   z_Pool.__init__U   s\    !1'+5#d&7&7"8!81!<b!DE
r   c                     t        | j                        }t        | j                        }t        d | j                  D              }d| d| d| S )Nc              3   &   K   | ]	  }|d      ywr*   r+   r,   ps     r   r0   z$_Pool._extra_repr.<locals>.<genexpr>b   s     /A1Q4s   zkernel_size=z	, stride=z
, padding=)r   rE   rF   rG   )rJ   ksstpds       r   _extra_reprz_Pool._extra_repr_   sM    4$$%4<< ///bT2$j==r   c                    t        d | j                  D              r4t        j                  |dg| j                  z   dgz   | j                        }t        || j                  | j                        }| j                  || j                        S )Nc              3   ,   K   | ]  }|d    d kD    ywr*   r+   rR   s     r   r0   z!_Pool.__call__.<locals>.<genexpr>g   s     /Aqtaxs   )r   r   )constant_values)
anyrG   r6   padrH   r>   rE   rF   rD   rI   )rJ   r   s     r   __call__z_Pool.__call__f   st    ///4==(F83 $ 3 3A
 Q 1 14<<@%%a44r   )__name__
__module____qualname__rC   rW   r]   __classcell__rO   s   @r   r@   r@   T   s    F>5r   r@   c            
       h     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 )_Pool1drL   r/   rM   c                 >   t        |       j                  }d}t        |d|j                  |d            }|t        |d|j                  |d            }n|}t        |d|j                  |d            }|D cg c]  }||f }}t        	|   |||||       y c c}w )Nz<[{}] '{}' must be an integer or a tuple containing 1 integerr   rL   r/   rM   typer^   r   formatrB   rC   
rJ   rK   rN   rL   r/   rM   
class_namer   rS   rO   s
            r   rC   z_Pool1d.__init__r   s     $Z((
L$CJJz=A
 #FAszz*h/OPF F !SZZ
I-NO#*+7aAq67+);W ,   9BNr   	r^   r_   r`   r   r   r   r   rC   ra   rb   s   @r   rd   rd   q   sd     48*+X 3c
?+	X
 sE#J/0X sE#J'X Xr   rd   c                   z     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 )_Pool2drL   r/   rM   c                 >   t        |       j                  }d}t        |d|j                  |d            }|t        |d|j                  |d            }n|}t        |d|j                  |d            }|D cg c]  }||f }}t        	|   |||||       y c c}w )Nz=[{}] '{}' must be an integer or a tuple containing 2 integersr   rL   r/   rM   rf   ri   s
            r   rC   z_Pool2d.__init__        $Z((
M$CJJz=A
 #FAszz*h/OPF F !SZZ
I-NO#*+7aAq67+);W ,rk   rl   rm   rb   s   @r   ro   ro      sx     9=9:X 3c3h/0	X
 sE#s(O345X %U38_ 456X Xr   ro   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 )_Pool3drL   r/   rM   c                 >   t        |       j                  }d}t        |d|j                  |d            }|t        |d|j                  |d            }n|}t        |d|j                  |d            }|D cg c]  }||f }}t        	|   |||||       y c c}w )Nz=[{}] '{}' must be an integer or a tuple containing 3 integersr'   rL   r/   rM   rf   ri   s
            r   rC   z_Pool3d.__init__   rq   rk   rl   rm   rb   s   @r   rs   rs      s     >B>?X 3c3m 445	X
 sE#sC-$889:X %U3S=%9 9:;X Xr   rs   c            
       l     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)
    rL   r/   rM   c                 \    t         |   t        j                  t	        d       |||       y NinfrB   rC   r6   maxfloatrJ   rL   r/   rM   rO   s       r   rC   zMaxPool1d.__init__   $     	%,VWMr   rl   
r^   r_   r`   __doc__r   r   r   r   rC   ra   rb   s   @r   rv   rv      sg    0 48*+	N3c
?+N sE#J/0N sE#J'	N Nr   rv   c            
       l     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)
    rL   r/   rM   c                 H    t         |   t        j                  d|||       y rl   rB   rC   r6   meanr}   s       r   rC   zAvgPool1d.__init__        	![&'Br   rl   r   rb   s   @r   r   r      sg    0 48*+	C3c
?+C sE#J/0C sE#J'	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)
    rL   r/   rM   c                 \    t         |   t        j                  t	        d       |||       y rx   rz   r}   s       r   rC   zMaxPool2d.__init__  r~   r   rl   r   rb   s   @r   r   r      s{    > 9=9:	N3c3h/0N sE#s(O345N %U38_ 456	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)
    rL   r/   rM   c                 H    t         |   t        j                  d|||       y rl   r   r}   s       r   rC   zAvgPool2d.__init__:  r   r   rl   r   rb   s   @r   r   r     s{    > 9=9:	C3c3h/0C sE#s(O345C %U38_ 456	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)
    rL   r/   rM   c                 \    t         |   t        j                  t	        d       |||       y rx   rz   r}   s       r   rC   zMaxPool3d.__init__a  r~   r   rl   r   rb   s   @r   r   r   C  s    @ >B>?	N3c3m 445N sE#sC-$889:N %U3S=%9 9:;	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)
    rL   r/   rM   c                 H    t         |   t        j                  d|||       y rl   r   r}   s       r   rC   zAvgPool3d.__init__  r   r   rl   r   rb   s   @r   r   r   j  s    @ >B>?	C3c3m 445C sE#sC-$889:C %U3S=%9 9:;	C Cr   r   )r4   	itertoolsr   typingr   r   r   mlx.corecorer6   mlx.nn.layers.baser   r   r%   r>   r@   rd   ro   rs   rv   r   r   r   r   r   r+   r   r   <module>r      s       ) )  %	 *8Z5F 5:Xe X0Xe X0Xe X0N N>C C>#N #NL#C #CL$N $NN$C $Cr   