| 119 | const size_t second_last = value.shape.rank - 2; |
| 120 | axes[second_last] = static_cast<int>(last); |
| 121 | axes[last] = static_cast<int>(second_last); |
| 122 | |
| 123 | std::array<int, core::kMaxTensorRank> ggml_axes = {0, 1, 2, 3}; |
| 124 | for (size_t out_logical_axis = 0; out_logical_axis < value.shape.rank; ++out_logical_axis) { |
| 125 | const int in_logical_axis = axes[out_logical_axis]; |
| 126 | const int out_ggml_axis = static_cast<int>(value.shape.rank) - 1 - static_cast<int>(out_logical_axis); |
| 127 | ggml_axes[out_ggml_axis] = core::logical_axis_to_ggml_axis(value.shape.rank, in_logical_axis); |
| 128 | } |
| 129 | |
| 130 | return core::wrap_tensor( |
| 131 | ggml_permute(ctx.ggml, value.tensor, ggml_axes[0], ggml_axes[1], ggml_axes[2], ggml_axes[3]), |
| 132 | transpose_last_two(value.shape), |
| 133 | value.type); |