| 16855 | } |
| 16856 | |
| 16857 | static thread_ret_t ggml_graph_compute_thread(void * data) { |
| 16858 | struct ggml_compute_state * state = (struct ggml_compute_state *) data; |
| 16859 | |
| 16860 | const struct ggml_cgraph * cgraph = state->shared->cgraph; |
| 16861 | const struct ggml_cplan * cplan = state->shared->cplan; |
| 16862 | |
| 16863 | const int n_threads = state->shared->n_threads; |
| 16864 | |
| 16865 | set_numa_thread_affinity(state->ith, n_threads); |
| 16866 | |
| 16867 | int node_n = -1; |
| 16868 | |
| 16869 | while (true) { |
| 16870 | if (cplan->abort_callback && cplan->abort_callback(cplan->abort_callback_data)) { |
| 16871 | state->shared->node_n += 1; |
| 16872 | return (thread_ret_t) GGML_EXIT_ABORTED; |
| 16873 | } |
| 16874 | if (atomic_fetch_sub(&state->shared->n_active, 1) == 1) { |
| 16875 | // all other threads are finished and spinning |
| 16876 | // do finalize and init here so we don't have synchronize again |
| 16877 | struct ggml_compute_params params = { |
| 16878 | /*.type =*/ GGML_TASK_FINALIZE, |
| 16879 | /*.ith =*/ 0, |
| 16880 | /*.nth =*/ 0, |
| 16881 | /*.wsize =*/ cplan->work_size, |
| 16882 | /*.wdata =*/ cplan->work_data, |
| 16883 | /*.aic =*/ &state->shared->aic, |
| 16884 | }; |
| 16885 | |
| 16886 | if (node_n != -1) { |
| 16887 | /* FINALIZE */ |
| 16888 | struct ggml_tensor * node = cgraph->nodes[node_n]; |
| 16889 | if (GGML_OP_HAS_FINALIZE[node->op]) { |
| 16890 | params.nth = ggml_get_n_tasks(node, n_threads); |
| 16891 | ggml_compute_forward(¶ms, node); |
| 16892 | } |
| 16893 | ggml_graph_compute_perf_stats_node(node, state->shared); |
| 16894 | } |
| 16895 | |
| 16896 | // distribute new work or execute it direct if 1T |
| 16897 | while (++node_n < cgraph->n_nodes) { |
| 16898 | GGML_PRINT_DEBUG_5("%s: %d/%d\n", __func__, node_n, cgraph->n_nodes); |
| 16899 | |
| 16900 | struct ggml_tensor * node = cgraph->nodes[node_n]; |
| 16901 | const int n_tasks = ggml_get_n_tasks(node, n_threads); |
| 16902 | |
| 16903 | state->shared->perf_node_start_cycles = ggml_perf_cycles(); |
| 16904 | state->shared->perf_node_start_time_us = ggml_perf_time_us(); |
| 16905 | |
| 16906 | params.nth = n_tasks; |
| 16907 | |
| 16908 | /* INIT */ |
| 16909 | if (GGML_OP_HAS_INIT[node->op]) { |
| 16910 | params.type = GGML_TASK_INIT; |
| 16911 | ggml_compute_forward(¶ms, node); |
| 16912 | } |
| 16913 | |
| 16914 | if (n_tasks == 1) { |
no test coverage detected