| 901 | } |
| 902 | |
| 903 | void llama_kv_cache::apply_ubatch(const slot_info & sinfo, const llama_ubatch & ubatch) { |
| 904 | // keep track of the max sequence position that we would overwrite with this ubatch |
| 905 | // for non-SWA cache, this would be always empty |
| 906 | llama_seq_id seq_pos_max_rm[LLAMA_MAX_SEQ]; |
| 907 | for (uint32_t s = 0; s < LLAMA_MAX_SEQ; ++s) { |
| 908 | seq_pos_max_rm[s] = -1; |
| 909 | } |
| 910 | |
| 911 | assert(ubatch.n_tokens == sinfo.n_stream()*sinfo.size()); |
| 912 | |
| 913 | for (uint32_t s = 0; s < sinfo.n_stream(); ++s) { |
| 914 | for (uint32_t ii = 0; ii < sinfo.size(); ++ii) { |
| 915 | const uint32_t i = s*sinfo.size() + ii; |
| 916 | |
| 917 | auto & cells = v_cells[sinfo.strm[s]]; |
| 918 | |
| 919 | const auto idx = sinfo.idxs[s][ii]; |
| 920 | |
| 921 | if (!cells.is_empty(idx)) { |
| 922 | assert(cells.seq_count(idx) == 1); |
| 923 | |
| 924 | const llama_seq_id seq_id = cells.seq_get(idx); |
| 925 | const llama_pos pos = cells.pos_get(idx); |
| 926 | |
| 927 | seq_pos_max_rm[seq_id] = std::max(seq_pos_max_rm[seq_id], pos); |
| 928 | |
| 929 | cells.rm(idx); |
| 930 | } |
| 931 | |
| 932 | cells.pos_set(idx, ubatch.pos[i]); |
| 933 | |
| 934 | if (ubatch.is_pos_2d()) { |
| 935 | llama_kv_cell_ext ext { |
| 936 | /*.x =*/ ubatch.pos[i + ubatch.n_tokens*2], |
| 937 | /*.y =*/ ubatch.pos[i + ubatch.n_tokens], |
| 938 | }; |
| 939 | cells.ext_set(idx, ext); |
| 940 | } |
| 941 | |
| 942 | for (int32_t s = 0; s < ubatch.n_seq_id[i]; s++) { |
| 943 | cells.seq_add(idx, ubatch.seq_id[i][s]); |
| 944 | } |
| 945 | } |
| 946 | } |
| 947 | |
| 948 | // note: we want to preserve the invariant that all positions between [pos_min, pos_max] for each sequence |
| 949 | // will be present in the cache. so we have to purge any position which is less than those we would overwrite |
| 950 | // ref: https://github.com/ggml-org/llama.cpp/pull/13746#issuecomment-2916057092 |
| 951 | for (uint32_t s = 0; s < LLAMA_MAX_SEQ; ++s) { |
| 952 | if (seq_pos_max_rm[s] == -1) { |
| 953 | continue; |
| 954 | } |
| 955 | |
| 956 | GGML_ASSERT(s < seq_to_stream.size()); |
| 957 | |
| 958 | auto & cells = v_cells[seq_to_stream[s]]; |
| 959 | |
| 960 | if (cells.seq_pos_min(s) <= seq_pos_max_rm[s]) { |
no test coverage detected