| 378 | } |
| 379 | |
| 380 | void llama_context::sched_reserve() { |
| 381 | if (!sched_need_reserve) { |
| 382 | return; |
| 383 | } |
| 384 | |
| 385 | sched_need_reserve = false; |
| 386 | |
| 387 | LLAMA_LOG_INFO("%s: reserving ...\n", __func__); |
| 388 | |
| 389 | synchronize(); |
| 390 | |
| 391 | const int64_t t_start_us = ggml_time_us(); |
| 392 | |
| 393 | const uint32_t n_seqs = cparams.n_seq_max; |
| 394 | const uint32_t n_tokens = std::min(cparams.n_ctx, cparams.n_ubatch); |
| 395 | |
| 396 | const size_t max_nodes = this->graph_max_nodes(n_tokens); |
| 397 | |
| 398 | LLAMA_LOG_DEBUG("%s: max_nodes = %zu\n", __func__, max_nodes); |
| 399 | |
| 400 | gf_res_prev.reset(new llm_graph_result(max_nodes)); |
| 401 | gf_res_reserve.reset(new llm_graph_result(max_nodes)); |
| 402 | |
| 403 | sched.reset(ggml_backend_sched_new(backend_ptrs.data(), backend_buft.data(), backend_ptrs.size(), max_nodes, cparams.pipeline_parallel, cparams.op_offload)); |
| 404 | |
| 405 | llama_memory_context_ptr mctx; |
| 406 | if (memory) { |
| 407 | LLAMA_LOG_DEBUG("%s: reserving full memory module\n", __func__); |
| 408 | mctx = memory->init_full(); |
| 409 | if (!mctx) { |
| 410 | throw std::runtime_error("failed to initialize memory module"); |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | // avoid reserving graphs with zero outputs - assume one output per sequence |
| 415 | const int n_outputs = n_seqs; |
| 416 | |
| 417 | LLAMA_LOG_DEBUG("%s: worst-case: n_tokens = %d, n_seqs = %d, n_outputs = %d\n", __func__, n_tokens, n_seqs, n_outputs); |
| 418 | |
| 419 | // resolve automatic Flash Attention use |
| 420 | if (cparams.auto_fa) { |
| 421 | auto * gf = graph_reserve(1, n_seqs, n_outputs, mctx.get(), true); |
| 422 | if (!gf) { |
| 423 | throw std::runtime_error("failed to split graph for Flash Attention check"); |
| 424 | } |
| 425 | |
| 426 | const size_t prefix_len = strlen(LLAMA_TENSOR_NAME_FATTN) + 1; |
| 427 | bool fa_device_mismatch = false; |
| 428 | for (int i = 0; i < ggml_graph_n_nodes(gf); i++) { |
| 429 | ggml_tensor * n = ggml_graph_node(gf, i); |
| 430 | if (n->op != GGML_OP_FLASH_ATTN_EXT) { |
| 431 | continue; |
| 432 | } |
| 433 | ggml_backend_dev_t device_fa = ggml_backend_get_device( |
| 434 | ggml_backend_sched_get_tensor_backend(sched.get(), n)); |
| 435 | |
| 436 | // TODO: instead of the tensor names, use a map to keep track of which (FA) tensors belong to which layer |
| 437 | GGML_ASSERT(strncmp(n->name, LLAMA_TENSOR_NAME_FATTN "-", prefix_len) == 0); |
nothing calls this directly
no test coverage detected