@@ -662,29 +662,38 @@ static bool test_sdpa_config(
662662 }
663663
664664 const auto & outputs = result.get ();
665- // The mutating op returns [k_cache, v_cache, attn_output]; select the
666- // attention output (numel == S*Hq*D), not a mutated cache (numel Cmax*Hkv*D).
667- // Count matches and fail if ambiguous: a cache could share the same numel.
665+ // Select the attention output [1,S,Hq,D] by shape; the op returns
666+ // [k_cache, v_cache, attn_output] and a cache [1,Cmax,Hkv,D] can share numel.
668667 int attn_idx = -1 ;
669668 int attn_matches = 0 ;
670669 for (size_t i = 0 ; i < outputs.size (); i++) {
671- if (outputs[i].isTensor () && outputs[i].toTensor ().numel () == on) {
670+ if (!outputs[i].isTensor ()) {
671+ continue ;
672+ }
673+ const auto & t = outputs[i].toTensor ();
674+ if (t.dim () == 4 && static_cast <int >(t.size (1 )) == cfg.s &&
675+ static_cast <int >(t.size (2 )) == cfg.hq &&
676+ static_cast <int >(t.size (3 )) == cfg.d ) {
672677 attn_idx = static_cast <int >(i);
673678 attn_matches++;
674679 }
675680 }
676681 if (attn_idx < 0 ) {
677682 printf (
678- " FAIL: no attention output (numel %d) among %zu outputs\n " ,
679- on,
683+ " FAIL: no attention output [1,%d,%d,%d] among %zu outputs\n " ,
684+ cfg.s ,
685+ cfg.hq ,
686+ cfg.d ,
680687 outputs.size ());
681688 return false ;
682689 }
683690 if (attn_matches > 1 ) {
684691 printf (
685- " FAIL: ambiguous attention output: %d tensors match numel %d \n " ,
692+ " FAIL: ambiguous attention output: %d tensors match shape [1,%d,%d,%d] \n " ,
686693 attn_matches,
687- on);
694+ cfg.s ,
695+ cfg.hq ,
696+ cfg.d );
688697 return false ;
689698 }
690699 const auto & out_tensor = outputs[attn_idx].toTensor ();
0 commit comments