assigns backends to ops and splits the graph into subgraphs that can be computed on the same backend TODO: merge passes
| 579 | // assigns backends to ops and splits the graph into subgraphs that can be computed on the same backend |
| 580 | // TODO: merge passes |
| 581 | static void sched_split_graph(ggml_backend_sched_t sched, struct ggml_cgraph * graph) { |
| 582 | // reset state |
| 583 | size_t hash_size = sched->hash_set.size; |
| 584 | memset(sched->hash_set.keys, 0, sizeof(sched->hash_set.keys[0]) * hash_size); |
| 585 | memset(sched->node_talloc, 0, sizeof(sched->node_talloc[0]) * hash_size); |
| 586 | memset(sched->node_copies, 0, sizeof(sched->node_copies[0]) * hash_size); |
| 587 | sched->n_splits = 0; |
| 588 | |
| 589 | struct ggml_init_params params = { |
| 590 | /*.mem_size = */ sizeof(sched->context_buffer), |
| 591 | /*.mem_buffer = */ sched->context_buffer, |
| 592 | /*.no_alloc = */ true |
| 593 | }; |
| 594 | |
| 595 | if (sched->ctx != NULL) { |
| 596 | ggml_free(sched->ctx); |
| 597 | } |
| 598 | |
| 599 | sched->ctx = ggml_init(params); |
| 600 | |
| 601 | // pass 1: assign backends to ops with allocated inputs |
| 602 | for (int i = 0; i < graph->n_leafs; i++) { |
| 603 | struct ggml_tensor * leaf = graph->leafs[i]; |
| 604 | if (node_allocr(leaf) != NULL) { |
| 605 | // do not overwrite user assignments |
| 606 | continue; |
| 607 | } |
| 608 | ggml_backend_t leaf_backend = ggml_get_backend(leaf); |
| 609 | if (leaf_backend == NULL && leaf->view_src != NULL) { |
| 610 | leaf_backend = ggml_get_backend(leaf->view_src); |
| 611 | } |
| 612 | if (leaf_backend != NULL) { |
| 613 | node_allocr(leaf) = ggml_backend_sched_get_tallocr(sched, leaf_backend); |
| 614 | } |
| 615 | } |
| 616 | |
| 617 | for (int i = 0; i < graph->n_nodes; i++) { |
| 618 | struct ggml_tensor * node = graph->nodes[i]; |
| 619 | if (node_allocr(node) != NULL) { |
| 620 | // do not overwrite user assignments |
| 621 | continue; |
| 622 | } |
| 623 | ggml_backend_t node_backend = sched_backend_from_cur(sched, node); |
| 624 | if (node_backend != NULL) { |
| 625 | node_allocr(node) = ggml_backend_sched_get_tallocr(sched, node_backend); |
| 626 | } |
| 627 | } |
| 628 | //printf("PASS 1 ASSIGNMENTS\n"); sched_print_assignments(sched, graph); |
| 629 | |
| 630 | // pass 2: assign backends to ops from current assignments |
| 631 | // TODO: |
| 632 | // - reuse sched_backend_from_cur |
| 633 | for (int i = 0; i < graph->n_nodes; i++) { |
| 634 | struct ggml_tensor * node = graph->nodes[i]; |
| 635 | ggml_tallocr_t node_allocr = node_allocr(node); |
| 636 | if (node_allocr == NULL) { |
| 637 | int cur_prio = INT_MAX; |
| 638 | size_t cur_size = 0; |
no test coverage detected