| 19 | const core::TensorValue & table, |
| 20 | int64_t half_dim, |
| 21 | const char * label) { |
| 22 | core::validate_rank_between(table, 4, 4, label); |
| 23 | if (!((table.shape.dims[0] == 1 || table.shape.dims[0] == input.shape.dims[0]) && |
| 24 | table.shape.dims[1] == input.shape.dims[1] && |
| 25 | table.shape.dims[2] == input.shape.dims[2] && |
| 26 | table.shape.dims[3] == half_dim)) { |
| 27 | throw std::runtime_error(std::string("SplitRoPE ") + label + " shape mismatch"); |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | core::TensorValue repeat_like( |
| 32 | core::ModuleBuildContext & ctx, |
| 33 | const core::TensorValue & value, |
| 34 | const core::TensorValue & like) { |
| 35 | if (value.shape.rank == like.shape.rank) { |
| 36 | bool same = true; |
| 37 | for (size_t axis = 0; axis < value.shape.rank; ++axis) { |
| 38 | same = same && value.shape.dims[axis] == like.shape.dims[axis]; |
| 39 | } |
| 40 | if (same) { |
| 41 | return value; |
| 42 | } |
| 43 | } |
| 44 | return core::wrap_tensor(ggml_repeat(ctx.ggml, value.tensor, like.tensor), like.shape, value.type); |
| 45 | } |
| 46 | |
| 47 | } // namespace |
| 48 | |
| 49 | RoPEModule::RoPEModule(RoPEConfig config) : config_(config) { |
| 50 | require_positive(config_.dimensions, "RoPEConfig.dimensions"); |
| 51 | } |
| 52 | |
| 53 | core::TensorValue RoPEModule::build( |
| 54 | core::ModuleBuildContext & ctx, |
| 55 | const core::TensorValue & input, |
| 56 | const core::TensorValue & positions, |
nothing calls this directly
no test coverage detected