| 408 | return {output, k, v}; |
| 409 | } |
| 410 | |
| 411 | core::TensorValue planner_set_compact_kv_row( |
| 412 | core::ModuleBuildContext & ctx, |
| 413 | const core::TensorValue & cache, |
| 414 | const core::TensorValue & row, |
| 415 | const core::TensorValue & cache_slot) { |
| 416 | core::validate_rank_between(cache, 4, 4, "cache"); |
| 417 | core::validate_shape( |
| 418 | row, |
| 419 | core::TensorShape::from_dims({cache.shape.dims[0], 1, cache.shape.dims[2], cache.shape.dims[3]}), |
| 420 | "row"); |
| 421 | const int64_t batch = cache.shape.dims[0]; |
| 422 | core::validate_shape(cache_slot, core::TensorShape::from_dims({batch}), "cache_slot"); |
| 423 | if (batch == 1) { |
| 424 | const modules::FastKVSetRowsModule set_rows; |
| 425 | return set_rows.build(ctx, cache, row, cache_slot); |
| 426 | } |
| 427 | |
| 428 | const int64_t steps = cache.shape.dims[1]; |
| 429 | const int64_t row_elems = cache.shape.dims[2] * cache.shape.dims[3]; |
| 430 | auto flat_cache = core::reshape_tensor( |
| 431 | ctx, |
| 432 | cache, |
| 433 | core::TensorShape::from_dims({batch * steps, row_elems})); |
| 434 | auto flat_row = core::reshape_tensor( |
| 435 | ctx, |
| 436 | ensure_planner_contiguous(ctx, row), |
| 437 | core::TensorShape::from_dims({batch, row_elems})); |
| 438 | ggml_tensor * updated = ggml_set_rows(ctx.ggml, flat_cache.tensor, flat_row.tensor, cache_slot.tensor); |
| 439 | auto flat_updated = core::wrap_tensor(updated, flat_cache.shape, cache.type); |
| 440 | return core::reshape_tensor(ctx, flat_updated, cache.shape); |
| 441 | } |
| 442 | |
| 443 | modules::QwenDecoderLayerOutputs planner_decoder_layer_with_static_cache_tail_batched( |
no test coverage detected