+
    UV-j¸  ã                   ó€   € R t ^ RIHt ^ RIHtHt ^ RIHtHt ^ RI	H
t ] ! R R4      4       tR R ltR	^/R
 R lltR# )u/  DDTree best-first draft-tree construction (Algorithm 1 from the paper).

Given per-position token marginals ``q_i(v) = softmax(â„“_i)_v`` for
``i = 1..L`` from a single block-diffusion drafter forward pass, this module
builds a prefix-closed draft tree of up to ``B`` nodes that maximizes

    E_{y~Q(Â·|c,b)}[Î±_T(Y_{1:L})] = Î£_{u âˆˆ T} q(u|c,b)

where ``q(u|c,b) = âˆ�_{iâ‰¤|u|} q_i(u_i|c,b)`` is the factorized prefix mass
and ``Î±_T`` is the expected accepted acceptance length under the drafter's
factorized distribution (Proposition 1 of the paper).

Lemma 1 reduces the search space to the top-``K = min(B, |V|)`` tokens at
each depth. Algorithm 1 enumerates those prefixes in descending
log-probability order with a max-heap, popping one prefix per iteration and
pushing its first child and next sibling.
)Ú	dataclass)ÚheappopÚheappush)ÚListÚTupleNc                   ó4   a € ] tR t^t o RtRtV 3R ltRtV tR# )Ú
DDTreeNodea–  A single tree node, identified by its rank-tuple path from the root.

``ranks[i]`` is the 1-indexed rank of this node's token at depth ``i+1``
(1 = highest-probability token at that depth). ``token_ids`` is the
resolved vocab id at each depth. ``parent`` is the index (in the flat
tree list returned by ``build_ddtree``) of this node's parent, or -1 for
depth-1 nodes whose parent is the root bonus token.
c                ó~   <€ V ^8„  d   Qh/ S[ S[R3,          ;R&   S[ S[R3,          ;R&   S[;R&   S[;R&   S[;R&   # )é   .ÚranksÚ	token_idsÚlog_probÚdepthÚparent©r   ÚintÚfloat)ÚformatÚ__classdict__s   "€Úk/Volumes/fast/ai/experiments/ui-tars-smoke/.venv/lib/python3.14/site-packages/mlx_vlm/speculative/ddtree.pyÚ__annotate__ÚDDTreeNode.__annotate__   sT   ø‡ ‚ ñ ‘�c��?Ññ ñ ‘S˜#�X�Ññ ñ �Oñ ñ �Jñ ñ Ñò ó    © Néÿÿÿÿ)	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__)r   s   @r   r   r      s   ø‡ € ñð €F÷ ƒ r   r   c                óš   € V ^8„  d   QhR\         P                  R\        R\        \         P                  \         P                  3,          /# )r
   Ú	log_probsÚKÚreturn)ÚmxÚarrayr   r   )r   s   "r   r   r   ,   s7   € ÷ 
ñ 
¤r§x¡xð 
´Cð 
¼EÄ"Ç(Á(ÌBÏHÉHÐBTÕ<Uñ 
r   c                óÄ   € V P                   w  r#\        W4      p\        P                  ! V ) RR7      RRV13,          pVR,          p\        P                  ! WRR7      pWd3# )zkReturn (top_log_probs[L, K], top_ids[L, K]) along the vocabulary
axis. ``log_probs`` has shape ``[L, V]``.
)ÚaxisºNNNNr   )Nr+   r+   )ÚshapeÚminr'   ÚargsortÚtake_along_axis)r$   r%   ÚLÚVÚtop_idsÚ
gather_idxÚtop_lps   &&     r   Ú_top_k_tokens_per_depthr5   ,   s[   € ð �?‰?�D€AÜˆA‹	€Aä�jŠj˜)˜¨"Ô-¨a°°!°¨eÕ4€GØ˜Õ$€JÜ×Ò 	¸Ô<€FØˆ?Ðr   Úslot_offsetc          	      ór   € V ^8„  d   QhR\         P                  R\        R\        R\        \        ,          /# )r
   Údrafter_logitsÚbudgetr6   r&   )r'   r(   r   r   r   )r   s   "r   r   r   9   s?   € ÷ kñ kÜ—H‘Hðkäðkô ð	kô
 
Œ*Õñkr   c               ó’  aa€ V P                   ^8X  d   V P                  ^ ,          ^8X  g   Q hV P                  R	,          pV P                  ^,          pWB,
          pV^ 8:  g   V^ 8:  d   . # V ^ VR1R3,          pV\        P                  ! VR	RR7      ,
          p\	        W4      p\        Wx4      w  rš\        P                  ! Wš4       V	P                  4       oV
P                  4       o. p^ pR V3R llpR
p\        W½! V4      ) WÎR	34       V^,          p. p/ pV'       Ed&   \        V4      V8  Ed   \        V4      w  ppppV) p\        V4      p\        ;QJ d     . V3R l\        V4       4       F  NK  	  5M! V3R l\        V4       4       4      p\        VVVVVR7      p\        V4      pVP                  V4       VVV&   VR	,          pV^,           V8:  d5   VRR	 V^,           3,           p\        VV! V4      ) VVV34       V^,          pVV8  g   EK  VR
,           p\        VV! V4      ) VVV34       V^,          pEK.  V# )uq  Algorithm 1 â€” return up to ``budget`` tree nodes in the order they
are popped (= descending log-probability).

Parameters
----------
drafter_logits : mx.array
    Shape ``[1, noise_len, V]``. Logits from the DFlash drafter forward
    pass for one sequence in the batch.
budget : int
    Maximum number of tree nodes to return (``B`` in the paper). The
    root bonus token is *not* counted toward the budget.
slot_offset : int, default=1
    Starting slot index inside ``drafter_logits``. When the drafter's
    noise block is laid out as ``[b, m, m, â€¦, m]`` (length ``L+1``),
    depth-1 predictions live at slot index 1, so the default of 1 is
    correct. Set to 0 if you fed a noise block of pure masks.

Returns
-------
List[DDTreeNode]
    Flat list of nodes. ``list[i].parent`` indexes earlier entries in
    the same list (or ``-1`` for depth-1 children of the root).
Nr+   T)r*   Úkeepdimsc                óJ   € V ^8„  d   QhR\         \        R3,          R\        /# )r
   r   .r&   r   )r   s   "r   r   Ú"build_ddtree.<locals>.__annotate__m   s"   € ÷ ñ œE¤# s (�Oð ´ñ r   c                 óp   <€ R p\        V 4       F#  w  r#VSV,          V^,
          ,          ,          pK%  	  V# )g        )Ú	enumerate)r   Úsr   ÚrÚ	top_lp_nps   &   €r   Ú_lp_of_ranksÚ"build_ddtree.<locals>._lp_of_ranksm   s6   ø€ ØˆÜ! %Ö(‰HˆEØ�˜5Õ! ! a¥%Õ(Õ(ŠAñ )àˆr   c              3   óV   <"  € T F  w  rSV,          V^,
          ,          x € K   	  R# 5i)é   Nr   )Ú.0ÚdrA   Ú
top_ids_nps   &  €r   Ú	<genexpr>Úbuild_ddtree.<locals>.<genexpr>   s%   øé € ÐLÑ;K±4°1˜* Q�-¨¨A­×.Ò.Ó;Kùs   ƒ&))r   r   r   r   r   r   )rF   )Úndimr,   r'   Ú	logsumexpr-   r5   ÚevalÚtolistr   Úlenr   Útupler?   r   Úappend)r8   r9   r6   r1   ÚL_totalr0   Ú	logits_2dr$   r%   r4   r2   ÚheapÚcounterrC   Ústart_ranksÚtreeÚrank_to_indexÚneg_lpÚ_r   r   Úlpr   r   ÚnodeÚidxÚ	last_rankÚ	new_ranksrI   rB   s   &&$                         @@r   Úbuild_ddtreera   9   sE  ù€ ð: ×Ñ !Ô#¨×(<Ñ(<¸QÕ(?À1Ô(DÐDÐDØ×Ñ˜RÕ €AØ×"Ñ" 1Õ%€GØÕ€AØˆA„v�˜1”Øˆ	à˜q +¡,°Ð1Õ2€Ið œBŸLšL¨¸ÀdÔKÕK€IäˆF‹€AÜ-¨iÓ;�O€FÜ‡G‚GˆFÔØ—‘“€IØ—‘Ó!€Jð ;=€DØ€G÷ð ð €KÜˆT�\ +Ó.Ð.°ÀbÐIÔJØˆq…L€Gà€DØ€Mç
ˆ$”3�t“9˜vÕ%Ü#*¨4£=Ñ ˆ��5˜&ØˆWˆÜ�E“
ˆß”EÔL¼9ÀUÔ;KÓL—E‘EÔL¼9ÀUÔ;KÓLÓLˆ	ÜØ 9°rÀÈvô
ˆô �$‹iˆØ�‰�DÔØ"ˆ�eÑð ˜"•Iˆ	Ø�q�=˜AÔØ˜c˜r˜
 i°!¥mÐ%5Õ5ˆIÜØá! )Ó,Ð,ØØØð	ôð �q�LˆGð �1�9Ø �ˆIÜØá! )Ó,Ð,ØØØð	ôð �q�L‹Gà€Kr   )r   Údataclassesr   Úheapqr   r   Útypingr   r   Úmlx.coreÚcorer'   r   r5   ra   r   r   r   Ú<module>rg      sM   ðñõ$ "ß #ß å ð ÷ð ó ðõ"
ðkð ÷	kñ kr   