@@ -2047,24 +2047,18 @@ llm_graph_result * llama_context::process_ubatch(const llama_ubatch & ubatch, ll
20472047 if (tid >= 0 )
20482048 ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
20492049 }
2050- // Cascade: force nodes whose src tensors match ffn_moe_*
2051- bool changed;
2052- do {
2053- changed = false ;
2054- for (int i = 0 ; i < ggml_graph_n_nodes (phase2_gf); i++) {
2055- ggml_tensor * t = ggml_graph_node (phase2_gf, i);
2056- ggml_backend_t be_t = ggml_backend_sched_get_tensor_backend (sched.get (), t);
2057- if (be_t && ggml_backend_is_cuda (be_t )) continue ;
2058- for (int s = 0 ; s < GGML_MAX_SRC && t->src [s]; s++) {
2059- auto [sid, sil] = h2_hijack.match_name (t->src [s]->name );
2060- if (sid >= 0 ) {
2061- ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
2062- changed = true ;
2063- break ;
2064- }
2050+ // Cascade: force VIEW (op=37) and ADD (op=2) consumers of matched tensors
2051+ for (int i = 0 ; i < ggml_graph_n_nodes (phase2_gf); i++) {
2052+ ggml_tensor * t = ggml_graph_node (phase2_gf, i);
2053+ if (t->op != 37 && t->op != 2 ) continue ;
2054+ for (int s = 0 ; s < GGML_MAX_SRC && t->src [s]; s++) {
2055+ auto [sid, sil] = h2_hijack.match_name (t->src [s]->name );
2056+ if (sid >= 0 ) {
2057+ ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
2058+ break ;
20652059 }
20662060 }
2067- } while (changed);
2061+ }
20682062 force_idxs_to_cpu ();
20692063 if (!ggml_backend_sched_alloc_graph (sched.get (), phase2_gf)) { ret = GGML_STATUS_ALLOC_FAILED ; return nullptr ; }
20702064
@@ -2125,25 +2119,19 @@ llm_graph_result * llama_context::process_ubatch(const llama_ubatch & ubatch, ll
21252119 auto [tid, il] = h2_hijack.match_name (t->name );
21262120 if (tid >= 0 ) ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
21272121 }
2128- // Cascade: force nodes whose src tensors match ffn_moe_*
2129- // (catches VIEW and ADD nodes that consume matched tensors)
2130- bool changed;
2131- do {
2132- changed = false ;
2133- for (int i = 0 ; i < ggml_graph_n_nodes (phase2_gf); i++) {
2134- ggml_tensor * t = ggml_graph_node (phase2_gf, i);
2135- ggml_backend_t be_t = ggml_backend_sched_get_tensor_backend (sched.get (), t);
2136- if (be_t && ggml_backend_is_cuda (be_t )) continue ;
2137- for (int s = 0 ; s < GGML_MAX_SRC && t->src [s]; s++) {
2138- auto [sid, sil] = h2_hijack.match_name (t->src [s]->name );
2139- if (sid >= 0 ) {
2140- ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
2141- changed = true ;
2142- break ;
2143- }
2122+ // Cascade: force VIEW (op=37) and ADD (op=2) nodes that consume
2123+ // matched tensors (catches expert output combination chain only)
2124+ for (int i = 0 ; i < ggml_graph_n_nodes (phase2_gf); i++) {
2125+ ggml_tensor * t = ggml_graph_node (phase2_gf, i);
2126+ if (t->op != 37 && t->op != 2 ) continue ;
2127+ for (int s = 0 ; s < GGML_MAX_SRC && t->src [s]; s++) {
2128+ auto [sid, sil] = h2_hijack.match_name (t->src [s]->name );
2129+ if (sid >= 0 ) {
2130+ ggml_backend_sched_set_tensor_backend (sched.get (), t, gpu);
2131+ break ;
21442132 }
21452133 }
2146- } while (changed);
2134+ }
21472135 force_idxs_to_cpu ();
21482136 if (!ggml_backend_sched_alloc_graph (sched.get (), phase2_gf)) {
21492137 ret = GGML_STATUS_ALLOC_FAILED ; return nullptr ;
0 commit comments