| 2028 | } |
| 2029 | |
| 2030 | ggml_cgraph * llama_context::graph_reserve( |
| 2031 | uint32_t n_tokens, uint32_t n_seqs, uint32_t n_outputs, const llama_memory_context_i * mctx, bool split_only, size_t * sizes) { |
| 2032 | LLAMA_LOG_DEBUG("%s: reserving a graph for ubatch with n_tokens = %4u, n_seqs = %2u, n_outputs = %4u\n", __func__, n_tokens, n_seqs, n_outputs); |
| 2033 | GGML_ASSERT(n_outputs >= 1); |
| 2034 | |
| 2035 | if (n_tokens % n_seqs != 0) { |
| 2036 | n_tokens = ((n_tokens + (n_seqs - 1)) / n_seqs) * n_seqs; // round to next multiple of n_seqs |
| 2037 | n_outputs = std::max(n_outputs, n_tokens); |
| 2038 | |
| 2039 | LLAMA_LOG_DEBUG("%s: making n_tokens a multiple of n_seqs - n_tokens = %u, n_seqs = %u, n_outputs = %u\n", __func__, n_tokens, n_seqs, n_outputs); |
| 2040 | } |
| 2041 | |
| 2042 | ggml_backend_sched_reset(sched.get()); |
| 2043 | |
| 2044 | // when the scheduler is reset, we cannnot reuse the old graph, so we reset the previous graph result to prevent that |
| 2045 | gf_res_prev->reset(); |
| 2046 | |
| 2047 | // store the n_outputs as it is, and restore it afterwards |
| 2048 | // TODO: not sure if needed, might simplify in the future by removing this |
| 2049 | const auto save_n_outputs = this->n_outputs; |
| 2050 | |
| 2051 | this->n_outputs = n_outputs; |
| 2052 | |
| 2053 | llama_batch_allocr balloc(model.hparams.n_pos_per_embd()); |
| 2054 | llama_ubatch ubatch = balloc.ubatch_reserve(n_tokens/n_seqs, n_seqs); |
| 2055 | |
| 2056 | // set one output token per sequence in order to activate all backend samplers |
| 2057 | std::vector<llama_seq_id> seq_ids(n_seqs); |
| 2058 | for (uint32_t i = 0; i < n_seqs; ++i) { |
| 2059 | seq_ids[i] = i; |
| 2060 | ubatch.n_seq_id[i] = 1; |
| 2061 | ubatch.seq_id[i] = &seq_ids[i]; |
| 2062 | ubatch.output[i] = true; |
| 2063 | } |
| 2064 | |
| 2065 | auto * res = gf_res_reserve.get(); |
| 2066 | |
| 2067 | const auto gparams = graph_params(res, ubatch, mctx, LLM_GRAPH_TYPE_DEFAULT); |
| 2068 | |
| 2069 | res->reset(); |
| 2070 | |
| 2071 | auto * gf = model.build_graph(gparams); |
| 2072 | |
| 2073 | this->n_outputs = save_n_outputs; |
| 2074 | |
| 2075 | // initialize scheduler with the specified graph |
| 2076 | if (split_only) { |
| 2077 | if (sizes) { |
| 2078 | ggml_backend_sched_reserve_size(sched.get(), gf, sizes); |
| 2079 | } else { |
| 2080 | ggml_backend_sched_split_graph(sched.get(), gf); |
| 2081 | } |
| 2082 | } else if (!ggml_backend_sched_reserve(sched.get(), gf)) { |
| 2083 | GGML_ASSERT(!sizes); |
| 2084 | LLAMA_LOG_ERROR("%s: failed to allocate compute buffers\n", __func__); |
| 2085 | return nullptr; |
| 2086 | } |
| 2087 |
nothing calls this directly
no test coverage detected