3
3
4
4
namespace {
5
5
6
- using op_constructor_t = std::shared_ptr<qnn::ggml_qnn_op_config> (*)(const ggml_tensor *, const std::string &,
6
+ using op_constructor_t = std::shared_ptr<qnn::ggml_qnn_op_config> (*)(const ggml_tensor *, const std::string &,
7
7
std::shared_ptr<qnn::qnn_instance>);
8
- using op_dims_calc_func_t = void (*)(const std::vector<qnn::ggml_dimension_array_t > & input_dims,
9
- qnn::ggml_dimension_array_t & output_dims);
10
8
11
- void element_wise_op_dims (const std::vector<qnn::ggml_dimension_array_t > & input_dims,
12
- qnn::ggml_dimension_array_t & output_dims) {
13
- for (size_t i = 1 ; i < std::size (output_dims); i++) {
14
- output_dims[i] = input_dims.front ()[i];
9
+ using op_description_generator_t = void (*)(const ggml_tensor * op, bool append_dimensions, std::string & output);
10
+
11
+ void get_graph_key_from_op (const ggml_tensor * op, std::string & output) {
12
+ GGML_ASSERT (op->op != GGML_OP_NONE);
13
+ output += ggml_op_desc (op);
14
+ output += qnn::get_ggml_type_name (op->type );
15
+ for (size_t i = 0 ; i < GGML_MAX_SRC && op->src [i]; ++i) {
16
+ auto * input = op->src [i];
17
+ if (!input) {
18
+ break ;
19
+ }
20
+
21
+ output += ' _' ;
22
+ qnn::append_tensor_shape_and_type (input, output);
15
23
}
16
24
}
17
25
18
- void mat_mul_op_dims (const std::vector<qnn::ggml_dimension_array_t > & input_dims,
19
- qnn::ggml_dimension_array_t & output_dims) {
20
- GGML_ASSERT (input_dims.size () == 2 );
21
- output_dims[0 ] = input_dims.front ()[1 ];
22
- output_dims[1 ] = input_dims.back ()[1 ];
26
+ void get_op_key_with_src_op_desc (const ggml_tensor * op, std::string & output) {
27
+ output += ggml_op_desc (op);
28
+ output += ' (' ;
29
+ if (op->src [0 ]) {
30
+ output += ggml_op_desc (op->src [0 ]);
31
+ }
32
+ for (size_t i = 1 ; i < GGML_MAX_SRC && op->src [i]; ++i) {
33
+ output += ' ,' ;
34
+ output += ggml_op_desc (op->src [i]);
35
+ }
36
+ output += ' )' ;
37
+ }
38
+
39
+ void generic_get_op_desc (const ggml_tensor * op, bool append_dimensions, std::string & output) {
40
+ if (append_dimensions) {
41
+ get_graph_key_from_op (op, output);
42
+ } else {
43
+ get_op_key_with_src_op_desc (op, output);
44
+ }
23
45
}
24
46
25
47
struct qnn_op_caps_t {
26
- const char * qnn_op_name = nullptr ;
27
- const size_t input_param_count = 0 ;
28
- op_dims_calc_func_t calc_dims_func = nullptr ;
29
- const char * qnn_param_name = nullptr ;
48
+ const char * qnn_op_name = nullptr ;
49
+ const size_t input_param_count = 0 ;
50
+ op_description_generator_t get_desc = nullptr ;
51
+ const char * qnn_param_name = nullptr ;
30
52
};
31
53
32
54
constexpr const qnn_op_caps_t kOpCaps [] = {
@@ -36,40 +58,40 @@ constexpr const qnn_op_caps_t kOpCaps[] = {
36
58
// GGML_OP_ADD
37
59
QNN_OP_ELEMENT_WISE_ADD, // qnn_op_name
38
60
2 , // input_param_count
39
- element_wise_op_dims , // calc_dims_func
61
+ generic_get_op_desc , // get_desc
40
62
},
41
63
{}, // GGML_OP_ADD1
42
64
{}, // GGML_OP_ACC
43
65
{
44
66
// GGML_OP_SUB
45
67
QNN_OP_ELEMENT_WISE_SUBTRACT, // qnn_op_name
46
68
2 , // input_param_count
47
- element_wise_op_dims , // calc_dims_func
69
+ generic_get_op_desc , // get_desc
48
70
},
49
71
{
50
72
// GGML_OP_MUL
51
73
QNN_OP_ELEMENT_WISE_MULTIPLY, // qnn_op_name
52
74
2 , // input_param_count
53
- element_wise_op_dims , // calc_dims_func
75
+ generic_get_op_desc , // get_desc
54
76
},
55
77
{
56
78
// GGML_OP_DIV
57
79
QNN_OP_ELEMENT_WISE_DIVIDE, // qnn_op_name
58
80
2 , // input_param_count
59
- element_wise_op_dims , // calc_dims_func
81
+ generic_get_op_desc , // get_desc
60
82
},
61
83
{}, // GGML_OP_SQR
62
84
{
63
85
// GGML_OP_SQRT
64
86
QNN_OP_ELEMENT_WISE_SQUARE_ROOT, // qnn_op_name
65
87
1 , // input_param_count
66
- element_wise_op_dims , // calc_dims_func
88
+ generic_get_op_desc , // get_desc
67
89
},
68
90
{
69
91
// GGML_OP_LOG
70
92
QNN_OP_ELEMENT_WISE_LOG, // qnn_op_name
71
93
1 , // input_param_count
72
- element_wise_op_dims , // calc_dims_func
94
+ generic_get_op_desc , // get_desc
73
95
},
74
96
{}, // GGML_OP_SIN
75
97
{}, // GGML_OP_COS
@@ -87,16 +109,16 @@ constexpr const qnn_op_caps_t kOpCaps[] = {
87
109
// GGML_OP_RMS_NORM
88
110
QNN_OP_RMS_NORM, // qnn_op_name
89
111
1 , // input_param_count
90
- nullptr , // TODO: calc_dims_func
112
+ generic_get_op_desc , // get_desc
91
113
QNN_OP_RMS_NORM_PARAM_EPSILON, // qnn_param_name
92
114
},
93
115
{}, // GGML_OP_RMS_NORM_BACK
94
116
{}, // GGML_OP_GROUP_NORM
95
117
{
96
118
// GGML_OP_MUL_MAT
97
- QNN_OP_MAT_MUL, // qnn_op_name
98
- 2 , // input_param_count
99
- mat_mul_op_dims , // calc_dims_func
119
+ QNN_OP_MAT_MUL, // qnn_op_name
120
+ 2 , // input_param_count
121
+ generic_get_op_desc , // get_desc
100
122
},
101
123
{}, // GGML_OP_MUL_MAT_ID
102
124
{}, // GGML_OP_OUT_PROD
@@ -106,9 +128,9 @@ constexpr const qnn_op_caps_t kOpCaps[] = {
106
128
{}, // GGML_OP_CONT
107
129
{
108
130
// GGML_OP_RESHAPE
109
- QNN_OP_RESHAPE, // qnn_op_name
110
- 1 , // input_param_count
111
- nullptr , // TODO: calc_dims_func
131
+ QNN_OP_RESHAPE, // qnn_op_name
132
+ 1 , // input_param_count
133
+ generic_get_op_desc , // get_desc
112
134
},
113
135
{}, // GGML_OP_VIEW
114
136
{}, // GGML_OP_PERMUTE
@@ -178,9 +200,9 @@ constexpr const qnn_op_caps_t kOpCaps[] = {
178
200
{}, // GGML_UNARY_OP_SIGMOID
179
201
{
180
202
// GGML_UNARY_OP_GELU
181
- QNN_OP_GELU, // qnn_op_name
182
- 1 , // input_param_count
183
- nullptr , // TODO: calc_dims_func
203
+ QNN_OP_GELU, // qnn_op_name
204
+ 1 , // input_param_count
205
+ generic_get_op_desc , // get_desc
184
206
},
185
207
{}, // GGML_UNARY_OP_GELU_QUICK
186
208
{}, // GGML_UNARY_OP_SILU
@@ -189,12 +211,12 @@ constexpr const qnn_op_caps_t kOpCaps[] = {
189
211
{}, // GGML_UNARY_OP_EXP
190
212
};
191
213
192
- static_assert (kOpCaps [GGML_OP_NONE].calc_dims_func == nullptr , " GGML_OP_NONE should not have calc_dims_func function" );
193
- static_assert (kOpCaps [GGML_OP_ADD].calc_dims_func == element_wise_op_dims ,
214
+ static_assert (kOpCaps [GGML_OP_NONE].get_desc == nullptr , " GGML_OP_NONE should not have get_desc function" );
215
+ static_assert (kOpCaps [GGML_OP_ADD].get_desc == generic_get_op_desc ,
194
216
" GGML_OP_ADD does not have element_wise_op_dims function" );
195
- static_assert (kOpCaps [GGML_OP_MUL_MAT].calc_dims_func == mat_mul_op_dims ,
217
+ static_assert (kOpCaps [GGML_OP_MUL_MAT].get_desc == generic_get_op_desc ,
196
218
" GGML_OP_ADD does not have element_wise_op_dims function" );
197
- static_assert (kOpCaps [GGML_OP_LOG].calc_dims_func == element_wise_op_dims ,
219
+ static_assert (kOpCaps [GGML_OP_LOG].get_desc == generic_get_op_desc ,
198
220
" GGML_OP_LOG does not have element_wise_op_dims function" );
199
221
static_assert (kOpCaps [GGML_OP_COUNT + GGML_UNARY_OP_GELU].input_param_count == 1 ,
200
222
" GGML_UNARY_OP_GELU does not have 1 input parameter" );
@@ -368,6 +390,31 @@ static_assert(std::size(kOpConstructors) == (GGML_OP_COUNT + GGML_UNARY_OP_COUNT
368
390
369
391
namespace qnn {
370
392
393
+ void append_tensor_shape_and_type (const ggml_tensor * tensor, std::string & output) {
394
+ char buffer[256 ] = {};
395
+ const auto * type_name = qnn::get_ggml_type_name (tensor->type );
396
+ int len = 0 ;
397
+ switch (ggml_n_dims (tensor)) {
398
+ case 1 :
399
+ len = snprintf (buffer, sizeof (buffer), " %ld%s" , (long ) tensor->ne [0 ], type_name);
400
+ break ;
401
+ case 2 :
402
+ len = snprintf (buffer, sizeof (buffer), " %ldx%ld%s" , (long ) tensor->ne [0 ], (long ) tensor->ne [1 ], type_name);
403
+ break ;
404
+ case 3 :
405
+ len = snprintf (buffer, sizeof (buffer), " %ldx%ldx%ld%s" , (long ) tensor->ne [0 ], (long ) tensor->ne [1 ],
406
+ (long ) tensor->ne [2 ], type_name);
407
+ break ;
408
+ case 4 :
409
+ default :
410
+ len = snprintf (buffer, sizeof (buffer), " %ldx%ldx%ldx%ld%s" , (long ) tensor->ne [0 ], (long ) tensor->ne [1 ],
411
+ (long ) tensor->ne [2 ], (long ) tensor->ne [3 ], type_name);
412
+ break ;
413
+ }
414
+ GGML_ASSERT (len > 0 && len < (int ) sizeof (buffer));
415
+ output.append (buffer, len);
416
+ }
417
+
371
418
size_t get_qnn_op_index (const ggml_tensor * tensor) {
372
419
if (tensor->op == GGML_OP_UNARY) {
373
420
return kGgmlUnaryOpStart + ggml_get_unary_op (tensor);
@@ -389,6 +436,14 @@ size_t get_qnn_op_input_param_count(const ggml_tensor * op) {
389
436
return kOpCaps [op_index].input_param_count ;
390
437
}
391
438
439
+ void get_qnn_op_desc (const ggml_tensor * op, bool append_dimensions, std::string & output) {
440
+ auto op_index = get_qnn_op_index (op);
441
+ GGML_ASSERT (op_index < std::size (kOpCaps ));
442
+ auto get_desc = kOpCaps [op_index].get_desc ;
443
+ GGML_ASSERT (get_desc);
444
+ get_desc (op, append_dimensions, output);
445
+ }
446
+
392
447
std::shared_ptr<ggml_qnn_op_config> create_op (const ggml_tensor * op, const std::string & name,
393
448
std::shared_ptr<qnn_instance> qnn_instance) {
394
449
auto op_index = get_qnn_op_index (op);
0 commit comments