| 302 | } |
| 303 | |
| 304 | engine::core::TensorValue permute_tensor( |
| 305 | engine::core::ModuleBuildContext & ctx, |
| 306 | const engine::core::TensorValue & input, |
| 307 | std::array<int, engine::core::kMaxTensorRank> axes) { |
| 308 | std::array<int, engine::core::kMaxTensorRank> ggml_axes = {0, 1, 2, 3}; |
| 309 | engine::core::TensorShape output_shape = {}; |
| 310 | output_shape.rank = input.shape.rank; |
| 311 | for (size_t out_logical_axis = 0; out_logical_axis < input.shape.rank; ++out_logical_axis) { |
| 312 | const int in_logical_axis = axes[out_logical_axis]; |
| 313 | output_shape.dims[out_logical_axis] = input.shape.dims[in_logical_axis]; |
| 314 | const int out_ggml_axis = static_cast<int>(input.shape.rank) - 1 - static_cast<int>(out_logical_axis); |
| 315 | ggml_axes[out_ggml_axis] = engine::core::logical_axis_to_ggml_axis(input.shape.rank, in_logical_axis); |
| 316 | } |
| 317 | return engine::core::wrap_tensor( |
| 318 | ggml_permute(ctx.ggml, input.tensor, ggml_axes[0], ggml_axes[1], ggml_axes[2], ggml_axes[3]), |
| 319 | output_shape, |
| 320 | input.type); |
| 321 | } |
| 322 | |
| 323 | engine::core::TensorValue transpose_last_two( |
| 324 | engine::core::ModuleBuildContext & ctx, |
no test coverage detected