Ë
    îÿæiÞ  ã                   óÂ  — d dl mZmZ d dlmZ d dlmZ ej                  d„ «       Z	d„ Z
 e
«       Zdej                  dej                  dej                  dej                  d	ej                  d
ej                  dej                  dej                  deeef   fd„Zdd„Z	 	 	 	 	 ddej                  dej                  dej                  dej                  d	ej                  d
ej                  dej                  deej                     deeef   deej                     deej                     dedeej                  ej                  f   fd„Z	 	 	 	 ddej                  dej                  dej                  dej                  d	ej                  d
ej                  dej                  deej                     deeef   deej                     deej                     fd„Zy)é    )ÚOptionalÚTupleNc                 ól   — t        j                  | |z   «      } t        j                  | |d   |d   «      S )Nr   é   )ÚnnÚsoftplusÚmxÚclip)ÚdtÚdt_biasÚtime_step_limits      úf/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/mlx_lm/models/ssm.pyÚ
compute_dtr      s1   € ä	�‰�R˜'‘\Ó	"€BÜ�7‰7�2� qÑ)¨?¸1Ñ+=Ó>Ð>ó    c                  ó’   — t         j                  j                  «       sy d} t         j                  j	                  dg d¢ddg| ¬«      S )Na  
        auto n = thread_position_in_grid.z;
        auto h_idx = n % H;
        auto g_idx = n / G;
        constexpr int n_per_t = Ds / 32;

        auto x = X + n * Dh;
        out += n * Dh;
        auto i_state = state_in + n * Dh * Ds;
        auto o_state = state_out + n * Dh * Ds;

        // C and B have shape [batch, group, state_dim]
        // C and B need to be offset by group size
        auto C_ = C + g_idx * Ds;
        auto B_ = B + g_idx * Ds;

        auto ds_idx = thread_position_in_threadgroup.x;
        auto d_idx = thread_position_in_grid.y;

        auto dt_ = static_cast<float>(dt[n]);
        auto A = -fast::exp(static_cast<float>(A_log[h_idx]));
        auto dA = fast::exp(A * dt_);

        float acc = 0.0;
        auto x_ = static_cast<float>(x[d_idx]);

        for (int i = 0; i < n_per_t; ++i) {
            auto s_idx = n_per_t * ds_idx + i;
            auto idx = d_idx * Ds + s_idx;
            auto dB_by_x = x_ * dt_ * static_cast<float>(B_[s_idx]);
            auto state = dA * i_state[idx] + dB_by_x;
            o_state[idx] = static_cast<T>(state);
            acc += state * C_[s_idx];
        }
        acc = simd_sum(acc);
        if (thread_index_in_simdgroup == 0) {
            out[d_idx] = static_cast<T>(acc + x_ * D[h_idx]);
        }
    Ú
ssm_kernel)ÚXÚA_logÚBÚCÚDr   Ústate_inÚoutÚ	state_out)ÚnameÚinput_namesÚoutput_namesÚsource)r	   ÚmetalÚis_availableÚfastÚmetal_kernel)r   s    r   Úmake_ssm_kernelr#      sL   € Ü�8‰8× Ñ Ô"Øð&€FôN �7‰7×ÑØÚCØ˜[Ð)Øð	  ó ð r   Úhidden_statesr   r   r   r   r   r   Ústater   c	           
      óþ   — | j                   \  }	}
}}| j                  }|j                   dd  \  }}t        |||«      }t        | ||||||gd|fd|fd|fd|fd||z  fgd|||	z  fd|	d	||f|j                   g||g¬
«      S )NéþÿÿÿÚTÚDhÚDsÚHÚGé    )r-   é   r   r   )ÚinputsÚtemplateÚgridÚthreadgroupÚoutput_shapesÚoutput_dtypes)ÚshapeÚdtyper   Ú_ssm_kernel)r$   r   r   r   r   r   r   r%   r   ÚnÚ_ÚhÚdÚ
input_typeÚhbÚdss                   r   Ússm_update_kernelr?   B   s¶   € ð ×$Ñ$�J€A€qˆ!ˆQØ×$Ñ$€JØ�W‰W�R�Sˆ\�F€BˆÜ	�B˜ Ó	1€BÜØ˜u a¨¨A¨r°5Ð9Ø˜
Ð# d¨A Y°°r°
¸SÀ!¸HÀsÈAÐQSÉGÀnÐUØ�!�Q˜‘Uˆ^ØØ˜1˜a �| U§[¡[Ð1Ø! :Ð.ôð r   c                 óP  — | j                   d   }|�t        j                  |d«      }| |z  } t        j                  | d   |d¬«      } t        j                  | d«      } t        j
                  | d¬«      }|�/t        j                  |dd d d …f   |d   z  |t        d«       «      }|S )Néÿÿÿÿr   ©.N©Úaxisr'   .Úinf)r5   r	   Úexpand_dimsÚrepeatÚtrilÚcumsumÚwhereÚfloat)ÚxÚmaskÚlÚx_segsums       r   ÚsegsumrP   [   sŸ   € Ø	�‰�‰€AØÐÜ�~‰~˜d AÓ&ˆØ�‰HˆÜ
�	‰	�!�I‘, ¨Ô+€AÜ
�‰��2‹€AÜ�y‰y˜ Ô$€HØÐÜ—8‘8Ø��dšA�Ñ  i¡Ñ0°(¼UÀ5»\¸Mó
ˆð €Or   rL   rM   ÚlengthsÚstepÚreturnc                 ó¤  ‡
‡‡‡‡‡‡‡— | j                   \  Š}ŠŠ|j                   \  }}ŠŠt        |||«      }‰‰z  Št        j                  |«      j	                  |j
                  «       }||j                  ddd«      z  }|j                  ‰|‰d«      | z  }ˆˆˆˆˆˆ
ˆˆfd„}g }t        d|‰«      D ]h  } ||dd…||‰z   …f   |dd…||‰z   …f   |dd…||‰z   …f   |dd…||‰z   …f   ||	€dn|	d||‰z   …f   «      \  }}‰
�‰
‰z
  Š
|j                  |«       Œj t        j                  |d¬«      | |j                  dd‰d«      z  z   }||fS )a5  SSD-SSM forward pass.

    Args:
        x: Input of shape (batch_size, seq_len, num_heads, head_dim).
        dt: Time deltas of shape (seq_len, num_heads,).
        A_log: State transition of shape (num_heads,).
        B: Input mixing of shape (batch_size, seq_len, num_groups, n).
        C: Output mixing of shape (batch_size, seq_len, num_groups, n).
        D: Residual connection.
        dt_bias: Bias for time deltas of shape (num_heads,).
        time_step_limit: Minimum and maximum value for time deltas.
        mask: Optional multiplicative mask.
        lengths: Optional lenghts of sequences, assumed to be the full length if unspecified.
        step: Step size for processing x.

    Code modified from
    https://github.com/cartesia-ai/edge/blob/main/cartesia-mlx/cartesia_mlx/layers/ssd/ops.py

    r   rA   c                 óð  •— | j                   d   }t        j                  |d«      }t        j                  |dd«      |z  }t        j                  |‰d¬«      }t        j
                  t        |j                  dd«      |¬«      «      }t        j                  ||z  d«      }	|	| j                  dd«      z  }
t        j                  |
dd«      }
‰�\t        j                  t        j                  ‰‰«      dz
  d«      }t        j                  |d«      }t        j                  ||d¬«      }n|d d …d d …dd …d d …f   }|j                  dd	dd«      }t        j                  |‰‰z  d¬«      j                  dd	«      }| |z  }|j                  dd«      j                  dd	«      }||z  }|�˜t        j
                  t        j                  |d
¬«      «      }||d d …dd d …d d f   |z  z  }|j                  ‰|‰d‰d«      }|j                  ‰d‰‰‰‰f«      |z  j                  d«      j                  dd	«      }|
|d   |z  z  }
‰�0|�.t        j                   t        j                  ‰dk  d«      ||«      }|
|fS )Nr   )r   é   é   r   rV   rC   )rM   r   )r   rV   rW   rA   rW   r'   rB   )r5   r	   Ú	transposeÚswapaxesrG   ÚexprP   rH   ÚmaximumÚminimumrF   Útake_along_axisrI   ÚreshapeÚsqueezeÚflattenrJ   )ÚdtxÚdtAr   r   r%   rM   ÚsÚCBÚdecayÚsurrogate_attention_matrixÚyÚposÚdtxdecayÚ
next_stateÚexp_dtA_cumsumÚy_prevÚbr;   ÚdhÚgr:   rQ   ÚrepeatsrR   s                   €€€€€€€€r   Ú_stepzssm_attn.<locals>._step”   sO  ø€ Ø�I‰I�a‰LˆÜ�L‰L˜˜LÓ)ˆä�[‰[˜˜A˜qÓ! AÑ%ˆÜ�Y‰Y�r˜7¨Ô+ˆä—‘”v˜cŸl™l¨1¨aÓ0°tÔ<Ó=ˆä%'§W¡W¨R°%©Z¸Ó%;Ð"à&¨¯©°a¸Ó);Ñ;ˆÜ�K‰K˜˜1˜aÓ ˆàÐÜ—*‘*œRŸZ™Z¨°Ó6¸Ñ:¸AÓ>ˆCÜ—.‘.  iÓ0ˆCÜ×&Ñ& u¨c¸Ô:‰Eàš!šQ ¡¢Q˜,Ñ'ˆEà—‘  1 a¨Ó+ˆÜ�I‰I�a˜˜a™ aÔ(×1Ñ1°!°QÓ7ˆØ˜‘;ˆØ×$Ñ$ Q¨Ó*×3Ñ3°A°qÓ9ˆà ‘\ˆ
àÐÜŸV™V¤B§I¡I¨c¸Ô$;Ó<ˆNØ˜.ª¨B²°4¸Ð)=Ñ>ÀÑFÑFˆJØ—	‘	˜!˜Q  1 a¨Ó+ˆAà—‘  1 a¨°"°aÐ8Ó9¸AÑ=×FÑFÀrÓJ×RÑRÐSTÐVWÓXð ð � 	Ñ*¨VÑ3Ñ3ˆAØÐ 5Ð#4ÜŸ™Ü—‘˜w¨™{¨IÓ6¸¸zóˆJð �*ˆ}Ðr   r   N.rC   )
r5   r   r	   rZ   Úastyper6   r^   ÚrangeÚappendÚconcatenate)rL   r   r   r   r   r   r   r%   r   rM   rQ   rR   rN   r9   ÚArb   ra   rq   ÚysÚirg   rm   r;   rn   ro   r:   rp   s             ``         @@@@@@r   Ússm_attnry   j   s  ÿ€ ðB —'‘'�K€A€qˆ!ˆRØ—‘�J€A€qˆ!ˆQä	�B˜ Ó	1€BØ�1‰f€GÜ	�‰�‹×	Ñ	˜bŸh™hÓ	'Ð'€AØ
ˆq�y‰y˜˜A˜rÓ"Ñ
"€CØ
�*‰*�Q˜˜1˜aÓ
  1Ñ
$€C÷)ó )ðV 
€BÜ�1�a˜ÖˆÙØ’�1�q˜4‘x�<�Ñ Ø’�1�q˜4‘x�<�Ñ ØŠa��Q˜‘X�ˆoÑØŠa��Q˜‘X�ˆoÑØØ�L‰D d¨3°°A¸±H°Ð+<Ñ&=ó
‰ˆˆ5ð ÐØ ‘nˆGØ
�	‰	�!�ð ô 	�‰�r Ô" Q¨¯©°1°a¸¸AÓ)>Ñ%>Ñ>€AØˆeˆ8€Or   c                 ó  — | j                   d   }|dkD  sE|�Ct        j                  «       t        j                  k7  st        j                  j                  «       st        | |||||||||	|
¬«      S t        | ||||||||«	      S )Nr   )rM   rQ   )r5   r	   Údefault_deviceÚgpur   r    ry   r?   )r$   r   r   r   r   r   r   r%   r   rM   rQ   Úseq_lens               r   Ú
ssm_updater~   Ð   s�   € ð ×!Ñ! !Ñ$€Gà�!ŠØˆ=Ü×ÑÓ¤"§&¡&Ò(Ü�x‰x×$Ñ$Ô&äØØØØØØØØØØØô
ð 	
ô !ØØØØØØØØØó

ð 
	
r   )N)N©gü©ñÒMbP?g      Y@NNé   )Nr   NN)Útypingr   r   Úmlx.coreÚcorer	   Úmlx.nnr   Úcompiler   r#   r7   ÚarrayrK   r?   rP   Úintry   r~   © r   r   Ú<module>r‰      sq  ðß "å Ý ð ‡�ñ?ó ð?ò
/ñd Ó€ðØ—8‘8ðà�8‰8ðð 
‡x�xðð 
‡x�xð	ð
 
‡x�xðð 	�‰ðð �X‰Xðð �8‰8ðð ˜5 %˜<Ñ(óó2ð. !%Ø+9Ø#Ø"&ØñcØ	‡x�xðcà�8‰8ðcð 
‡x�xðcð 
‡x�xð	cð
 
‡x�xðcð 	�‰ðcð �X‰Xðcð �B—H‘HÑðcð ˜5 %˜<Ñ(ðcð �2—8‘8Ñ
ðcð �b—h‘hÑðcð ðcð ˆ2�8‰8�R—X‘XÐÑócð\ !%Ø+9Ø#Ø"&ñ,
Ø—8‘8ð,
à�8‰8ð,
ð 
‡x�xð,
ð 
‡x�xð	,
ð
 
‡x�xð,
ð 	�‰ð,
ð �X‰Xð,
ð �B—H‘HÑð,
ð ˜5 %˜<Ñ(ð,
ð �2—8‘8Ñ
ð,
ð �b—h‘hÑô,
r   