main.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #pragma once
  15. #include <pybind11/eval.h>
  16. #include <pybind11/numpy.h>
  17. #include <pybind11/pybind11.h>
  18. #include <pybind11/stl.h>
  19. #include <type_traits>
  20. #include "ultra_infer/runtime/runtime.h"
  21. #ifdef ENABLE_VISION
  22. #include "ultra_infer/pipeline.h"
  23. #include "ultra_infer/vision.h"
  24. #endif
  25. #ifdef ENABLE_TEXT
  26. #include "ultra_infer/text.h"
  27. #endif
  28. #include "ultra_infer/core/float16.h"
  29. namespace ultra_infer {
  30. void BindBackend(pybind11::module &);
  31. void BindVision(pybind11::module &);
  32. void BindText(pybind11::module &m);
  33. void BindPipeline(pybind11::module &m);
  34. void BindRKNPU2Config(pybind11::module &);
  35. pybind11::dtype FDDataTypeToNumpyDataType(const FDDataType &fd_dtype);
  36. FDDataType NumpyDataTypeToFDDataType(const pybind11::dtype &np_dtype);
  37. void PyArrayToTensor(pybind11::array &pyarray, FDTensor *tensor,
  38. bool share_buffer = false);
  39. void PyArrayToTensorList(std::vector<pybind11::array> &pyarray,
  40. std::vector<FDTensor> *tensor,
  41. bool share_buffer = false);
  42. pybind11::array TensorToPyArray(const FDTensor &tensor);
  43. #ifdef ENABLE_VISION
  44. cv::Mat PyArrayToCvMat(pybind11::array &pyarray);
  45. #endif
  46. template <typename T> FDDataType CTypeToFDDataType() {
  47. if (std::is_same<T, int32_t>::value) {
  48. return FDDataType::INT32;
  49. } else if (std::is_same<T, int64_t>::value) {
  50. return FDDataType::INT64;
  51. } else if (std::is_same<T, float>::value) {
  52. return FDDataType::FP32;
  53. } else if (std::is_same<T, double>::value) {
  54. return FDDataType::FP64;
  55. } else if (std::is_same<T, int8_t>::value) {
  56. return FDDataType::INT8;
  57. }
  58. FDASSERT(false, "CTypeToFDDataType only support "
  59. "int8/int32/int64/float32/float64 now.");
  60. return FDDataType::FP32;
  61. }
  62. template <typename T>
  63. std::vector<pybind11::array>
  64. PyBackendInfer(T &self, const std::vector<std::string> &names,
  65. std::vector<pybind11::array> &data) {
  66. std::vector<FDTensor> inputs(data.size());
  67. for (size_t i = 0; i < data.size(); ++i) {
  68. // TODO(jiangjiajun) here is considered to use user memory directly
  69. auto dtype = NumpyDataTypeToFDDataType(data[i].dtype());
  70. std::vector<int64_t> data_shape;
  71. data_shape.insert(data_shape.begin(), data[i].shape(),
  72. data[i].shape() + data[i].ndim());
  73. inputs[i].Resize(data_shape, dtype);
  74. memcpy(inputs[i].MutableData(), data[i].mutable_data(), data[i].nbytes());
  75. inputs[i].name = names[i];
  76. }
  77. std::vector<FDTensor> outputs(self.NumOutputs());
  78. self.Infer(inputs, &outputs);
  79. std::vector<pybind11::array> results;
  80. results.reserve(outputs.size());
  81. for (size_t i = 0; i < outputs.size(); ++i) {
  82. auto numpy_dtype = FDDataTypeToNumpyDataType(outputs[i].dtype);
  83. results.emplace_back(pybind11::array(numpy_dtype, outputs[i].shape));
  84. memcpy(results[i].mutable_data(), outputs[i].Data(),
  85. outputs[i].Numel() * FDDataTypeSize(outputs[i].dtype));
  86. }
  87. return results;
  88. }
  89. } // namespace ultra_infer
  90. namespace pybind11 {
  91. namespace detail {
  92. // Note: use same enum number of float16 in numpy.
  93. // import numpy as np
  94. // print np.dtype(np.float16).num # 23
  95. constexpr int NPY_FLOAT16_ = 23;
  96. // Note: Since float16 is not a builtin type in C++, we register
  97. // ultra_infer::float16 as numpy.float16.
  98. // Ref: https://github.com/pybind/pybind11/issues/1776
  99. template <> struct npy_format_descriptor<ultra_infer::float16> {
  100. static pybind11::dtype dtype() {
  101. handle ptr = npy_api::get().PyArray_DescrFromType_(NPY_FLOAT16_);
  102. return reinterpret_borrow<pybind11::dtype>(ptr);
  103. }
  104. static std::string format() {
  105. // Note: "e" represents float16.
  106. // Details at:
  107. // https://docs.python.org/3/library/struct.html#format-characters.
  108. return "e";
  109. }
  110. static constexpr auto name = _("float16");
  111. };
  112. } // namespace detail
  113. } // namespace pybind11