| 399 | } |
| 400 | |
| 401 | void llama_kv_cache::seq_add(llama_seq_id seq_id, llama_pos p0, llama_pos p1, llama_pos shift) { |
| 402 | GGML_ASSERT(seq_id >= 0 && (size_t) seq_id < seq_to_stream.size()); |
| 403 | GGML_ASSERT(hparams.n_pos_per_embd() == 1 && "seq_add() is only supported for n_pos_per_embd() == 1"); |
| 404 | |
| 405 | auto & cells = v_cells[seq_to_stream[seq_id]]; |
| 406 | auto & head = v_heads[seq_to_stream[seq_id]]; |
| 407 | |
| 408 | if (shift == 0) { |
| 409 | return; |
| 410 | } |
| 411 | |
| 412 | uint32_t new_head = cells.size(); |
| 413 | |
| 414 | if (p0 < 0) { |
| 415 | p0 = 0; |
| 416 | } |
| 417 | |
| 418 | if (p1 < 0) { |
| 419 | p1 = std::numeric_limits<llama_pos>::max(); |
| 420 | } |
| 421 | |
| 422 | // If there is no range then return early to avoid looping over all cells. |
| 423 | if (p0 == p1) { |
| 424 | return; |
| 425 | } |
| 426 | |
| 427 | for (uint32_t i = 0; i < cells.size(); ++i) { |
| 428 | if (!cells.pos_in(i, p0, p1)) { |
| 429 | continue; |
| 430 | } |
| 431 | |
| 432 | if (cells.seq_has(i, seq_id)) { |
| 433 | if (cells.pos_add(i, shift)) { |
| 434 | if (new_head == cells.size()) { |
| 435 | new_head = i; |
| 436 | } |
| 437 | } |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | // If we freed up a slot, set head to it so searching can start there. |
| 442 | // Otherwise we just start the next search from the beginning. |
| 443 | head = new_head != cells.size() ? new_head : 0; |
| 444 | } |
| 445 | |
| 446 | void llama_kv_cache::seq_div(llama_seq_id seq_id, llama_pos p0, llama_pos p1, int d) { |
| 447 | GGML_ASSERT(seq_id >= 0 && (size_t) seq_id < seq_to_stream.size()); |
no test coverage detected