| 754 | } |
| 755 | |
| 756 | void llama_kv_cache_recurrent::state_write_data(llama_io_write_i & io, const std::vector<std::pair<uint32_t, uint32_t>> & cell_ranges) const { |
| 757 | const uint32_t v_trans = 0; |
| 758 | const uint32_t n_layer = hparams.n_layer; |
| 759 | |
| 760 | io.write(&v_trans, sizeof(v_trans)); |
| 761 | io.write(&n_layer, sizeof(n_layer)); |
| 762 | |
| 763 | std::vector<uint8_t> tmp_buf; |
| 764 | |
| 765 | // Iterate and write all the keys first, each row is a cell |
| 766 | // Get whole range at a time |
| 767 | for (uint32_t il = 0; il < n_layer; ++il) { |
| 768 | const uint32_t n_embd_k_gqa = hparams.n_embd_k_gqa(il) + hparams.n_embd_k_s(); |
| 769 | |
| 770 | // Write key type |
| 771 | const int32_t k_type_i = (int32_t)k_l[il]->type; |
| 772 | io.write(&k_type_i, sizeof(k_type_i)); |
| 773 | |
| 774 | // Write row size of key |
| 775 | const uint64_t k_size_row = ggml_row_size(k_l[il]->type, n_embd_k_gqa); |
| 776 | io.write(&k_size_row, sizeof(k_size_row)); |
| 777 | |
| 778 | // Read each range of cells of k_size length each into tmp_buf and write out |
| 779 | for (const auto & range : cell_ranges) { |
| 780 | const size_t range_size = range.second - range.first; |
| 781 | const size_t buf_size = range_size * k_size_row; |
| 782 | io.write_tensor(k_l[il], range.first * k_size_row, buf_size); |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | if (!v_trans) { |
| 787 | for (uint32_t il = 0; il < n_layer; ++il) { |
| 788 | const uint32_t n_embd_v_gqa = hparams.n_embd_v_gqa(il) + hparams.n_embd_v_s(); |
| 789 | |
| 790 | // Write value type |
| 791 | const int32_t v_type_i = (int32_t)v_l[il]->type; |
| 792 | io.write(&v_type_i, sizeof(v_type_i)); |
| 793 | |
| 794 | // Write row size of value |
| 795 | const uint64_t v_size_row = ggml_row_size(v_l[il]->type, n_embd_v_gqa); |
| 796 | io.write(&v_size_row, sizeof(v_size_row)); |
| 797 | |
| 798 | // Read each range of cells of v_size length each into tmp_buf and write out |
| 799 | for (const auto & range : cell_ranges) { |
| 800 | const size_t range_size = range.second - range.first; |
| 801 | const size_t buf_size = range_size * v_size_row; |
| 802 | io.write_tensor(v_l[il], range.first * v_size_row, buf_size); |
| 803 | } |
| 804 | } |
| 805 | } else { |
| 806 | // When v is transposed, we also need the element size and get the element ranges from each row |
| 807 | const uint32_t kv_size = size; |
| 808 | for (uint32_t il = 0; il < n_layer; ++il) { |
| 809 | const uint32_t n_embd_v_gqa = hparams.n_embd_v_gqa(il) + hparams.n_embd_v_s(); |
| 810 | |
| 811 | // Write value type |
| 812 | const int32_t v_type_i = (int32_t)v_l[il]->type; |
| 813 | io.write(&v_type_i, sizeof(v_type_i)); |
nothing calls this directly
no test coverage detected