
    i$                    V   d Z ddlmZ ddlZddlmZ ddlm	Z	  G d de	j                        Z G d de	j                        Z G d d	e	j                        Z G d
 de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Z G d de	j                        Zy)zR
Shared MLX layers and NCL/NCHW wrappers.
Optimized for memory layout efficiency.
    )annotationsNc                  (     e Zd Zd fdZddZ xZS )Lambdac                0    t         |           || _        y N)super__init__fn)selfr
   	__class__s     j/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/demucs_mlx/mlx_layers.pyr	   zLambda.__init__   s        c                $    | j                  |      S r   )r
   r   xs     r   __call__zLambda.__call__   s    wwqzr   )r
   z!tp.Callable[[mx.array], mx.array]r   mx.arrayreturnr   __name__
__module____qualname__r	   r   __classcell__r   s   @r   r   r      s    r   r   c                      e Zd ZddZy)Identityc                    |S r    r   s     r   r   zIdentity.__call__   s    r   Nr   )r   r   r   r   r   r   r   r   r      s    r   r   c                  (     e Zd Zd fdZddZ xZS )
Sequentialc                B    t         |           t        |      | _        y r   )r   r	   listlayers)r   r$   r   s     r   r	   zSequential.__init__   s    6lr   c                8    | j                   D ]
  } ||      } |S r   )r$   )r   r   layers      r   r   zSequential.__call__    s    [[EaA !r   )r$   z	nn.Moduler   r   r   s   @r   r!   r!      s    #r   r!   c                  V     e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZddZ xZS )	Conv1dNCLz~
    Conv1d wrapper for NCL (Batch, Channels, Length) layout.
    MLX Conv1d expects NLC, so we transpose inputs/outputs.
    c	           
     f    t         	|           t        j                  ||||||||      | _        y N)stridepaddingdilationgroupsbias)r   r	   nnConv1dconv
r   in_channelsout_channelskernel_sizer+   r,   r-   r.   r/   r   s
            r   r	   zConv1dNCL.__init__+   8     	II	
	r   c                p    |j                  ddd      }| j                  |      }|j                  ddd      S Nr         	transposer2   r   r   ys      r   r   zConv1dNCL.__call__B   s4    KK1a IIaL{{1a##r   r;   r   r;   r;   T)r4   intr5   rA   r6   rA   r+   rA   r,   rA   r-   rA   r.   rA   r/   boolr   r   r   r   __doc__r	   r   r   r   s   @r   r(   r(   &   sq     

 
 	

 
 
 
 
 
.$r   r(   c                  V     e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZddZ xZS )ConvTranspose1dNCLzK
    ConvTranspose1d wrapper for NCL (Batch, Channels, Length) layout.
    c	           
     f    t         	|           t        j                  ||||||||      | _        y N)r+   r,   r-   output_paddingr/   )r   r	   r0   ConvTranspose1dr2   
r   r4   r5   r6   r+   r,   r-   rI   r/   r   s
            r   r	   zConvTranspose1dNCL.__init__N   :     	&&)	
	r   c                p    |j                  ddd      }| j                  |      }|j                  ddd      S r9   r<   r>   s      r   r   zConvTranspose1dNCL.__call__e   s4    KK1a IIaL{{1a##r   r;   r   r;   r   T)r4   rA   r5   rA   r6   rA   r+   rA   r,   rA   r-   rA   rI   rA   r/   rB   r   rC   r   s   @r   rF   rF   J   sq     

 
 	

 
 
 
 
 
.$r   rF   c                  F     e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 d fdZddZ xZS )
Conv2dNCHWzg
    Conv2d wrapper for NCHW (Batch, Channels, Height, Width) layout.
    MLX Conv2d expects NHWC.
    c	           
     f    t         	|           t        j                  ||||||||      | _        y r*   )r   r	   r0   Conv2dr2   r3   s
            r   r	   zConv2dNCHW.__init__p   r7   r   c                t    |j                  dddd      }| j                  |      }|j                  dddd      S Nr   r:      r;   r<   r>   s      r   r   zConv2dNCHW.__call__   s8    KK1a#IIaL{{1aA&&r   r@   )r4   rA   r5   rA   r.   rA   r/   rB   r   rC   r   s   @r   rP   rP   k   sI     

 
 
 
.'r   rP   c                  >     e Zd Z	 	 	 	 	 d	 	 	 	 	 d fdZddZ xZS )ConvTranspose2dNCHWc	           
     f    t         	|           t        j                  ||||||||      | _        y rH   )r   r	   r0   ConvTranspose2dr2   rK   s
            r   r	   zConvTranspose2dNCHW.__init__   rL   r   c                t    |j                  dddd      }| j                  |      }|j                  dddd      S rT   r<   r>   s      r   r   zConvTranspose2dNCHW.__call__   s8    KK1a#IIaL{{1aA&&r   rN   )r4   rA   r5   rA   r/   rB   r   r   r   s   @r   rW   rW      s:     

 
 
.'r   rW   c                  .     e Zd ZdZdd fdZddZ xZS )GroupNormNCLz
    Optimized GroupNorm for NCL layout.
    Avoids transposing NCL -> NLC, which causes strided memory access.
    Performs reduction on contiguous dimensions (L) instead.
    c                   t         |           t        |      | _        t        |      | _        t        |      | _        t        |      | _        | j                  rWt        j                  |ft        j                        | _        t        j                  |ft        j                        | _        y d | _        d | _        y N)dtyper   r	   rA   
num_groupsnum_channelsfloatepsrB   affinemxonesfloat32weightzerosr/   r   ra   rb   rd   re   r   s        r   r	   zGroupNormNCL.__init__       j/-:6l;;''</DDK,

CDIDKDIr   c                   |j                   d   |j                   d   }}| j                  }||z  dk7  rt        d| d|        |j                  ||||z  g|j                   dd   }t	        t        d|j                              }|j                  |d      }t        j                  ||d      }||z
  t        j                  || j                  z         z  }	|	j                  |j                         }
| j                  rRd|gdg|
j                  dz
  z  z   }|
| j                  j                  |      z  | j                  j                  |      z   }
|
S )Nr   r;   znum_channels z not divisible by num_groups r:   Taxiskeepdims)shapera   
ValueErrorreshapetuplerangendimmeanrf   varrsqrtrd   re   ri   r/   r   r   BCG
x_reshapedaxesrw   rx   x_normx_outrq   s               r   r   zGroupNormNCL.__call__   s8   wwqz1771:1OOq5A:}QC/LQCPQQ
 QYYq!Q!V:aggabk:
 U1joo./D48ffZdT: t#rxxdhh'?? qww';;FaSEJJN33EDKK//669J9J59QQEr   h㈵>Tra   rA   rb   rA   rd   rc   re   rB   r   rC   r   s   @r   r\   r\      s    
r   r\   c                  .     e Zd ZdZdd fdZddZ xZS )GroupNormNCHWz.
    Optimized GroupNorm for NCHW layout.
    c                   t         |           t        |      | _        t        |      | _        t        |      | _        t        |      | _        | j                  rWt        j                  |ft        j                        | _        t        j                  |ft        j                        | _        y d | _        d | _        y r^   r`   rk   s        r   r	   zGroupNormNCHW.__init__   rl   r   c                z   |j                   d   |j                   d   }}| j                  } |j                  ||||z  g|j                   dd   }t        t	        d|j
                              }|j                  |d      }t        j                  ||d      }||z
  t        j                  || j                  z         z  }	|	j                  |j                         }
| j                  rRd|gdg|
j
                  dz
  z  z   }|
| j                  j                  |      z  | j                  j                  |      z   }
|
S )Nr   r;   r:   Trn   )rq   ra   rs   rt   ru   rv   rw   rf   rx   ry   rd   re   ri   r/   rz   s               r   r   zGroupNormNCHW.__call__   s   wwqz1771:1OO QYYq!Q!V:aggabk:
U1joo./D48ffZdT:t#rxxdhh'??qww';;FaSEJJN33EDKK//669J9J59QQEr   r   r   r   rC   r   s   @r   r   r      s    r   r   c                  *     e Zd Zdd fdZddZ xZS )GLUNCLc                0    t         |           || _        y r   )r   r	   ro   )r   ro   r   s     r   r	   zGLUNCL.__init__  s    	r   c                |    t        j                  |d| j                        \  }}|t        j                  |      z  S )Nr:   )ro   )rf   splitro   sigmoid)r   r   abs       r   r   zGLUNCL.__call__
  s/    xx1499-12::a=  r   )r;   )ro   rA   r   r   r   s   @r   r   r     s    !r   r   c                  &     e Zd Z fdZddZ xZS )GELUNCLc                "    t         |           y r   )r   r	   )r   r   s    r   r	   zGELUNCL.__init__  s    r   c                ,    t        j                  |      S r   )r0   gelur   s     r   r   zGELUNCL.__call__  s    wwqzr   r   r   r   s   @r   r   r     s    r   r   c                  .     e Zd ZdZdd fdZddZ xZS )FusedGroupNormGELUzFused GroupNorm + GELU using a custom Metal kernel.

    Replaces the pattern: GELUNCL()(GroupNormNCL/NCHW(x))
    into a single kernel launch.
    c                .   t         |           t        |      | _        t        |      | _        t        |      | _        t        j                  |ft        j                        | _
        t        j                  |ft        j                        | _        y r^   r   r	   rA   ra   rb   rc   rd   rf   rg   rh   ri   rj   r/   r   ra   rb   rd   r   s       r   r	   zFusedGroupNormGELU.__init__  a    j/-:gg|oRZZ@HHl_BJJ?	r   c                v    ddl m}  ||| j                  | j                  | j                  | j
                        S )Nr;   )fused_groupnorm_gelu)metal_kernelsr   ri   r/   ra   rd   )r   r   r   s      r   r   zFusedGroupNormGELU.__call__%  s+    7#At{{DIItPTPXPXYYr   r   ra   rA   rb   rA   rd   rc   r   rC   r   s   @r   r   r     s    
@Zr   r   c                  .     e Zd ZdZdd fdZddZ xZS )FusedGroupNormGLUzFused GroupNorm + GLU using a custom Metal kernel.

    Replaces the pattern: GLUNCL()(GroupNormNCL/NCHW(x))
    into a single kernel launch. Input has 2C channels, output has C channels.
    c                .   t         |           t        |      | _        t        |      | _        t        |      | _        t        j                  |ft        j                        | _
        t        j                  |ft        j                        | _        y r^   r   r   s       r   r	   zFusedGroupNormGLU.__init__0  r   r   c                v    ddl m}  ||| j                  | j                  | j                  | j
                        S )Nr;   )fused_groupnorm_glu)r   r   ri   r/   ra   rd   )r   r   r   s      r   r   zFusedGroupNormGLU.__call__8  s(    6"1dkk499dootxxXXr   r   r   r   rC   r   s   @r   r   r   *  s    
@Yr   r   )rD   
__future__r   typingtpmlx.corecorerf   mlx.nnr0   Moduler   r   r!   r(   rF   rP   rW   r\   r   r   r   r   r   r   r   r   <module>r      s    #   RYY ryy 
 !$		 !$H$ $B!' !'H'")) '</299 /d#BII #L!RYY !bii Z Z&Y		 Yr   