@@ -66,6 +66,37 @@ std::unique_ptr<QuantizeParamsWrapper> CreateQuantizationParamWrapper(
66
66
return quantize_param_wrapper;
67
67
}
68
68
69
+ std::string GetScalarValue (const Qnn_Scalar_t& scalar) {
70
+ switch (scalar.dataType ) {
71
+ case QNN_DATATYPE_FLOAT_32:
72
+ return std::to_string (scalar.floatValue );
73
+ case QNN_DATATYPE_FLOAT_64:
74
+ return std::to_string (scalar.doubleValue );
75
+ case QNN_DATATYPE_UINT_64:
76
+ return std::to_string (scalar.uint64Value );
77
+ case QNN_DATATYPE_INT_64:
78
+ return std::to_string (scalar.int64Value );
79
+ case QNN_DATATYPE_UINT_32:
80
+ return std::to_string (scalar.uint32Value );
81
+ case QNN_DATATYPE_INT_32:
82
+ return std::to_string (scalar.int32Value );
83
+ case QNN_DATATYPE_UINT_16:
84
+ return std::to_string (scalar.uint16Value );
85
+ case QNN_DATATYPE_INT_16:
86
+ return std::to_string (scalar.int16Value );
87
+ case QNN_DATATYPE_UINT_8:
88
+ return std::to_string (scalar.uint8Value );
89
+ case QNN_DATATYPE_INT_8:
90
+ return std::to_string (scalar.int8Value );
91
+ case QNN_DATATYPE_BOOL_8:
92
+ return std::to_string (static_cast <int >(scalar.bool8Value ));
93
+ case QNN_DATATYPE_STRING:
94
+ return std::string (scalar.stringValue );
95
+ default :
96
+ return " QNN_DATATYPE_UNDEFINED" ;
97
+ }
98
+ }
99
+
69
100
std::shared_ptr<TensorWrapper> CreateTensorWrapper (
70
101
const std::string& tensor_name,
71
102
Qnn_TensorType_t tensor_type,
@@ -176,11 +207,60 @@ PYBIND11_MODULE(PyQnnWrapperAdaptor, m) {
176
207
Qnn_QuantizationEncoding_t::
177
208
QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET)
178
209
.export_values ();
210
+
179
211
py::class_<OpWrapper, std::shared_ptr<OpWrapper>>(m, " OpWrapper" )
180
212
.def (py::init<
181
213
const std::string&,
182
214
const std::string&,
183
- const std::string&>());
215
+ const std::string&>())
216
+ .def (
217
+ " GetInputTensors" ,
218
+ &OpWrapper::GetInputTensors,
219
+ " A function which gets input tensors" )
220
+ .def (
221
+ " GetOutputTensors" ,
222
+ &OpWrapper::GetOutputTensors,
223
+ " A function which gets output tensors" )
224
+ .def (" GetOpType" , &OpWrapper::GetOpType, " A function which gets op type" )
225
+ .def (" GetName" , &OpWrapper::GetName, " A function which gets name" )
226
+ .def (
227
+ " GetPackageName" ,
228
+ &OpWrapper::GetPackageName,
229
+ " A function which gets package name" )
230
+ .def (
231
+ " GetParams" , &OpWrapper::GetRawParams, " A function which gets params" )
232
+ // lambda function
233
+ // python: op_wrapper.GetOpConfig()
234
+ .def (
235
+ " GetOpConfig" ,
236
+ [](OpWrapper& self) {
237
+ auto op_config = self.GetOpConfig ();
238
+ py::dict result;
239
+ py::list params_list;
240
+ py::list input_tensors_list;
241
+ py::list output_tensors_list;
242
+ result[" version" ] = op_config.version ;
243
+ result[" name" ] = op_config.v1 .name ;
244
+ result[" packageName" ] = op_config.v1 .packageName ;
245
+ result[" typeName" ] = op_config.v1 .typeName ;
246
+ result[" numOfParams" ] = op_config.v1 .numOfParams ;
247
+ for (size_t i = 0 ; i < op_config.v1 .numOfParams ; ++i) {
248
+ params_list.append (op_config.v1 .params [i]);
249
+ }
250
+ result[" params" ] = params_list;
251
+ result[" numOfInputs" ] = op_config.v1 .numOfInputs ;
252
+ for (size_t i = 0 ; i < op_config.v1 .numOfInputs ; ++i) {
253
+ input_tensors_list.append (op_config.v1 .inputTensors [i]);
254
+ }
255
+ result[" inputTensors" ] = input_tensors_list;
256
+ result[" numOfOutputs" ] = op_config.v1 .numOfOutputs ;
257
+ for (size_t i = 0 ; i < op_config.v1 .numOfOutputs ; ++i) {
258
+ output_tensors_list.append (op_config.v1 .outputTensors [i]);
259
+ }
260
+ result[" outputTensors" ] = output_tensors_list;
261
+ return result;
262
+ },
263
+ " Get operator configuration" );
184
264
185
265
py::class_<TensorWrapper, std::shared_ptr<TensorWrapper>>(m, " TensorWrapper" )
186
266
.def (py::init (py::overload_cast<
@@ -197,7 +277,9 @@ PYBIND11_MODULE(PyQnnWrapperAdaptor, m) {
197
277
py::class_<QuantizeParamsWrapper>(m, " QuantizeParamsWrapper" );
198
278
199
279
py::class_<Qnn_ScaleOffset_t>(m, " Qnn_ScaleOffset_t" )
200
- .def (py::init<float , int32_t >());
280
+ .def (py::init<float , int32_t >())
281
+ .def_readonly (" scale" , &Qnn_ScaleOffset_t::scale)
282
+ .def_readonly (" offset" , &Qnn_ScaleOffset_t::offset);
201
283
202
284
py::class_<PyQnnOpWrapper, std::shared_ptr<PyQnnOpWrapper>>(
203
285
m, " PyQnnOpWrapper" )
@@ -248,6 +330,158 @@ PYBIND11_MODULE(PyQnnWrapperAdaptor, m) {
248
330
.def (" GetDataType" , &PyQnnTensorWrapper::GetDataType)
249
331
.def (" GetName" , &PyQnnTensorWrapper::GetName)
250
332
.def (" GetEncodings" , &PyQnnTensorWrapper::GetEncodings);
333
+
334
+ py::class_<Qnn_OpConfig_t>(m, " Qnn_OpConfig" )
335
+ .def_readonly (" version" , &Qnn_OpConfig_t::version)
336
+ // getter
337
+ // python: op_wrapper.GetOpConfig().v1
338
+ .def_property_readonly (
339
+ " v1" , [](const Qnn_OpConfig_t& config) -> const Qnn_OpConfigV1_t& {
340
+ return config.v1 ;
341
+ });
342
+
343
+ py::enum_<Qnn_OpConfigVersion_t>(m, " Qnn_OpConfigVersion" )
344
+ .value (" QNN_OPCONFIG_VERSION_1" , QNN_OPCONFIG_VERSION_1)
345
+ .value (" QNN_OPCONFIG_VERSION_UNDEFINED" , QNN_OPCONFIG_VERSION_UNDEFINED)
346
+ .export_values ();
347
+
348
+ py::class_<Qnn_OpConfigV1_t>(m, " Qnn_OpConfigV1" )
349
+ .def_readonly (" name" , &Qnn_OpConfigV1_t::name)
350
+ .def_readonly (" packageName" , &Qnn_OpConfigV1_t::packageName)
351
+ .def_readonly (" typeName" , &Qnn_OpConfigV1_t::typeName)
352
+ .def_readonly (" numOfParams" , &Qnn_OpConfigV1_t::numOfParams)
353
+ .def_readonly (" params" , &Qnn_OpConfigV1_t::params)
354
+ .def_readonly (" numOfInputs" , &Qnn_OpConfigV1_t::numOfInputs)
355
+ .def_readonly (" inputTensors" , &Qnn_OpConfigV1_t::inputTensors)
356
+ .def_readonly (" numOfOutputs" , &Qnn_OpConfigV1_t::numOfOutputs)
357
+ .def_readonly (" outputTensors" , &Qnn_OpConfigV1_t::outputTensors);
358
+
359
+ py::class_<Qnn_Param_t>(m, " Qnn_Param" )
360
+ .def_readonly (" paramType" , &Qnn_Param_t::paramType)
361
+ .def_readonly (" name" , &Qnn_Param_t::name)
362
+ .def_property_readonly (
363
+ " scalarParam" ,
364
+ [](const Qnn_Param_t& param) -> const Qnn_Scalar_t& {
365
+ if (param.paramType == Qnn_ParamType_t::QNN_PARAMTYPE_SCALAR) {
366
+ return param.scalarParam ;
367
+ }
368
+ throw std::runtime_error (" ParamType is not scalar." );
369
+ })
370
+ .def_property_readonly (
371
+ " tensorParam" , [](const Qnn_Param_t& param) -> const Qnn_Tensor_t& {
372
+ if (param.paramType == Qnn_ParamType_t::QNN_PARAMTYPE_TENSOR) {
373
+ return param.tensorParam ;
374
+ }
375
+ throw std::runtime_error (" ParamType is not tensor." );
376
+ });
377
+
378
+ py::enum_<Qnn_ParamType_t>(m, " Qnn_ParamType_t" )
379
+ .value (" QNN_PARAMTYPE_SCALAR" , Qnn_ParamType_t::QNN_PARAMTYPE_SCALAR)
380
+ .value (" QNN_PARAMTYPE_TENSOR" , Qnn_ParamType_t::QNN_PARAMTYPE_TENSOR)
381
+ .value (
382
+ " QNN_PARAMTYPE_UNDEFINED" , Qnn_ParamType_t::QNN_PARAMTYPE_UNDEFINED)
383
+ .export_values ();
384
+
385
+ py::class_<Qnn_Scalar_t>(m, " Qnn_Scalar_t" )
386
+ .def_readonly (" dataType" , &Qnn_Scalar_t::dataType)
387
+ .def (" value" , &GetScalarValue, " Get the value of the scalar as a string" );
388
+
389
+ py::class_<Qnn_Tensor_t>(m, " Qnn_Tensor_t" )
390
+ .def_readonly (" version" , &Qnn_Tensor_t::version)
391
+ .def_property_readonly (
392
+ " v1" ,
393
+ [](Qnn_Tensor_t& t) -> Qnn_TensorV1_t& {
394
+ if (t.version == QNN_TENSOR_VERSION_1) {
395
+ return t.v1 ;
396
+ }
397
+ throw std::runtime_error (" Tensor version is not V1." );
398
+ })
399
+ .def_property_readonly (" v2" , [](Qnn_Tensor_t& t) -> Qnn_TensorV2_t& {
400
+ if (t.version == QNN_TENSOR_VERSION_2) {
401
+ return t.v2 ;
402
+ }
403
+ throw std::runtime_error (" Tensor version is not V2." );
404
+ });
405
+
406
+ py::enum_<Qnn_TensorVersion_t>(m, " Qnn_TensorVersion_t" )
407
+ .value (" QNN_TENSOR_VERSION_1" , Qnn_TensorVersion_t::QNN_TENSOR_VERSION_1)
408
+ .value (" QNN_TENSOR_VERSION_2" , Qnn_TensorVersion_t::QNN_TENSOR_VERSION_2)
409
+ .value (
410
+ " QNN_TENSOR_VERSION_UNDEFINED" ,
411
+ Qnn_TensorVersion_t::QNN_TENSOR_VERSION_UNDEFINED)
412
+ .export_values ();
413
+
414
+ py::class_<Qnn_TensorV1_t>(m, " QnnTensorV1" )
415
+ .def_readonly (" id" , &Qnn_TensorV1_t::id)
416
+ .def_readonly (" name" , &Qnn_TensorV1_t::name)
417
+ .def_readonly (" type" , &Qnn_TensorV1_t::type)
418
+ .def_readonly (" dataFormat" , &Qnn_TensorV1_t::dataFormat)
419
+ .def_readonly (" dataType" , &Qnn_TensorV1_t::dataType)
420
+ .def_readonly (" quantizeParams" , &Qnn_TensorV1_t::quantizeParams)
421
+ .def_readonly (" rank" , &Qnn_TensorV1_t::rank)
422
+ // change dimensions pointer to vector(begin to rank)
423
+ .def_property_readonly (
424
+ " dimensions" ,
425
+ [](const Qnn_TensorV1_t& t) {
426
+ return std::vector<uint32_t >(t.dimensions , t.dimensions + t.rank );
427
+ })
428
+ .def_readonly (" memType" , &Qnn_TensorV1_t::memType);
429
+
430
+ py::enum_<Qnn_TensorMemType_t>(m, " Qnn_TensorMemType_t" )
431
+ .value (
432
+ " QNN_TENSORMEMTYPE_RAW" , Qnn_TensorMemType_t::QNN_TENSORMEMTYPE_RAW)
433
+ .value (
434
+ " QNN_TENSORMEMTYPE_MEMHANDLE" ,
435
+ Qnn_TensorMemType_t::QNN_TENSORMEMTYPE_MEMHANDLE)
436
+ .value (
437
+ " QNN_TENSORMEMTYPE_UNDEFINED" ,
438
+ Qnn_TensorMemType_t::QNN_TENSORMEMTYPE_UNDEFINED)
439
+ .export_values ();
440
+
441
+ py::class_<Qnn_QuantizeParams_t>(m, " QnnQuantizeParams" )
442
+ .def_readonly (
443
+ " encodingDefinition" , &Qnn_QuantizeParams_t::encodingDefinition)
444
+ .def_readonly (
445
+ " quantizationEncoding" , &Qnn_QuantizeParams_t::quantizationEncoding)
446
+ .def_property_readonly (
447
+ " scaleOffsetEncoding" ,
448
+ [](const Qnn_QuantizeParams_t& qp) {
449
+ if (qp.quantizationEncoding ==
450
+ QNN_QUANTIZATION_ENCODING_SCALE_OFFSET) {
451
+ return qp.scaleOffsetEncoding ;
452
+ }
453
+ throw std::runtime_error (
454
+ " Invalid quantization encoding type for scaleOffsetEncoding." );
455
+ })
456
+ .def_property_readonly (
457
+ " axisScaleOffsetEncoding" , [](const Qnn_QuantizeParams_t& qp) {
458
+ if (qp.quantizationEncoding ==
459
+ QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) {
460
+ return qp.axisScaleOffsetEncoding ;
461
+ }
462
+ throw std::runtime_error (
463
+ " Invalid quantization encoding type for axisScaleOffsetEncoding." );
464
+ });
465
+
466
+ py::enum_<Qnn_Definition_t>(m, " QnnDefinition" )
467
+ .value (
468
+ " QNN_DEFINITION_IMPL_GENERATED" ,
469
+ Qnn_Definition_t::QNN_DEFINITION_IMPL_GENERATED)
470
+ .value (" QNN_DEFINITION_DEFINED" , Qnn_Definition_t::QNN_DEFINITION_DEFINED)
471
+ .value (
472
+ " QNN_DEFINITION_UNDEFINED" ,
473
+ Qnn_Definition_t::QNN_DEFINITION_UNDEFINED)
474
+ .export_values ();
475
+
476
+ py::class_<Qnn_AxisScaleOffset_t>(m, " QnnAxisScaleOffset" )
477
+ .def_readonly (" axis" , &Qnn_AxisScaleOffset_t::axis)
478
+ .def_readonly (" numScaleOffsets" , &Qnn_AxisScaleOffset_t::numScaleOffsets)
479
+ .def_property_readonly (
480
+ " scaleOffset" , [](const Qnn_AxisScaleOffset_t& aso) {
481
+ return std::vector<Qnn_ScaleOffset_t>(
482
+ aso.scaleOffset , aso.scaleOffset + aso.numScaleOffsets );
483
+ });
484
+ // op_wrapper.GetParams() get std::vector<ParamWrapper*>
251
485
}
252
486
} // namespace qnn
253
487
} // namespace backends
0 commit comments