char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Zijun YuOpenVINO: Qwen3.5, memory optimization, and test-recurrent-state-rollback (#26952)aee56b3ab

char/aliceai-t5-moe
3.2 KiB82 linesraw
1#include "../node_context.h"
2#include "../op_table.h"
3#include "../utils.h"
4
5#include <openvino/op/constant.hpp>
6#include <openvino/op/greater.hpp>
7#include <openvino/op/greater_eq.hpp>
8#include <openvino/op/less.hpp>
9#include <openvino/op/less_eq.hpp>
10#include <openvino/op/range.hpp>
11#include <openvino/op/reshape.hpp>
12#include <openvino/op/select.hpp>
13
14namespace ov {
15namespace frontend {
16namespace ggml {
17namespace op {
18
19// GGML TRI zeroes out elements outside a triangular region of a square matrix.
20// The type param (stored in op_params[0]) maps to ggml_tri_type:
21//   0 = UPPER_DIAG : keep where col >= row
22//   1 = UPPER      : keep where col >  row
23//   2 = LOWER_DIAG : keep where col <= row
24//   3 = LOWER      : keep where col <  row
25//
26// In OV layout (ggml [ne0, ne1, ne2, ne3] → OV [ne3, ne2, ne1, ne0]):
27//   ggml dim 0 (ne0, cols) → OV axis 3
28//   ggml dim 1 (ne1, rows) → OV axis 2
29// The matrix is square so ne0 == ne1.
30OutputVector translate_tri(const NodeContext & context) {
31    num_inputs_check(context, 1, 1);
32
33    auto x = context.get_input(0);  // OV shape: [ne3, ne2, ne1, ne0]
34
35    int32_t tri_type = context.get_output_op_params()[0];
36
37    auto shape = context.get_input_shape(0).to_shape();
38    int64_t n = static_cast<int64_t>(shape[3]);  // ne0 == ne1
39
40    // Build index range [0, 1, ..., n-1]
41    auto start = ov::op::v0::Constant::create(ov::element::i64, {}, {int64_t(0)});
42    auto stop  = ov::op::v0::Constant::create(ov::element::i64, {}, {n});
43    auto step  = ov::op::v0::Constant::create(ov::element::i64, {}, {int64_t(1)});
44    auto range = std::make_shared<ov::op::v4::Range>(start, stop, step, ov::element::i64);
45
46    // col_idx shape [1, 1, 1, n] — broadcasts over batch and row dims
47    auto col_shape = ov::op::v0::Constant::create(ov::element::i64, {4}, std::vector<int64_t>{1, 1, 1, n});
48    auto col_idx   = std::make_shared<ov::op::v1::Reshape>(range, col_shape, false);
49
50    // row_idx shape [1, 1, n, 1] — broadcasts over batch and col dims
51    auto row_shape = ov::op::v0::Constant::create(ov::element::i64, {4}, std::vector<int64_t>{1, 1, n, 1});
52    auto row_idx   = std::make_shared<ov::op::v1::Reshape>(range, row_shape, false);
53
54    // Build boolean mask: true where element should be kept
55    std::shared_ptr<ov::Node> mask;
56    switch (tri_type) {
57        case 0:  // UPPER_DIAG: col >= row
58            mask = std::make_shared<ov::op::v1::GreaterEqual>(col_idx, row_idx);
59            break;
60        case 1:  // UPPER: col > row
61            mask = std::make_shared<ov::op::v1::Greater>(col_idx, row_idx);
62            break;
63        case 2:  // LOWER_DIAG: col <= row
64            mask = std::make_shared<ov::op::v1::LessEqual>(col_idx, row_idx);
65            break;
66        case 3:  // LOWER: col < row
67            mask = std::make_shared<ov::op::v1::Less>(col_idx, row_idx);
68            break;
69        default:
70            throw std::runtime_error("translate_tri: invalid tri_type " + std::to_string(tri_type));
71    }
72
73    auto zero = ov::op::v0::Constant::create(ov::element::f32, {}, {0.0f});
74    auto res  = std::make_shared<ov::op::v1::Select>(mask, x, zero);
75
76    return rename_outputs_with_suffix({res}, context.get_name());
77}
78
79}  // namespace op
80}  // namespace ggml
81}  // namespace frontend
82}  // namespace ov