eigen.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 "ultra_infer/core/fd_tensor.h"
  16. #include "ultra_infer/utils/axis_utils.h"
  17. #include "unsupported/Eigen/CXX11/Tensor"
  18. #include <algorithm>
  19. #include <memory>
  20. #include <vector>
  21. namespace ultra_infer {
  22. namespace function {
  23. // EigenDim converts shape into Eigen::DSizes.
  24. template <int D> struct EigenDim {
  25. using Type = Eigen::DSizes<Eigen::DenseIndex, D>;
  26. static Type From(const std::vector<int64_t> &dims) {
  27. Type ret;
  28. for (int64_t d = 0; d < dims.size(); d++) {
  29. ret[d] = dims[d];
  30. }
  31. return ret;
  32. }
  33. };
  34. // Interpret FDTensor as EigenTensor and EigenConstTensor.
  35. template <typename T, size_t D, int MajorType = Eigen::RowMajor,
  36. typename IndexType = Eigen::DenseIndex>
  37. struct EigenTensor {
  38. using Type = Eigen::TensorMap<Eigen::Tensor<T, D, MajorType, IndexType>>;
  39. using ConstType =
  40. Eigen::TensorMap<Eigen::Tensor<const T, D, MajorType, IndexType>>;
  41. static Type From(FDTensor &tensor,
  42. const std::vector<int64_t> &dims) { // NOLINT
  43. return Type(reinterpret_cast<T *>(tensor.Data()), EigenDim<D>::From(dims));
  44. }
  45. static Type From(FDTensor &tensor) { // NOLINT
  46. return From(tensor, tensor.shape);
  47. } // NOLINT
  48. static ConstType From(const FDTensor &tensor,
  49. const std::vector<int64_t> &dims) {
  50. return ConstType(reinterpret_cast<const T *>(tensor.Data()),
  51. EigenDim<D>::From(dims));
  52. }
  53. static ConstType From(const FDTensor &tensor) {
  54. return From(tensor, tensor.shape);
  55. }
  56. };
  57. template <typename T, int MajorType = Eigen::RowMajor,
  58. typename IndexType = Eigen::DenseIndex>
  59. struct EigenScalar {
  60. // Scalar tensor (implemented as a rank-0 tensor) of scalar type T.
  61. using Type = Eigen::TensorMap<
  62. Eigen::TensorFixedSize<T, Eigen::Sizes<>, MajorType, IndexType>>;
  63. using ConstType = Eigen::TensorMap<
  64. Eigen::TensorFixedSize<const T, Eigen::Sizes<>, MajorType, IndexType>>;
  65. static Type From(FDTensor &tensor) {
  66. return Type(reinterpret_cast<T *>(tensor.Data()));
  67. } // NOLINT
  68. static ConstType From(const FDTensor &tensor) {
  69. return ConstType(reinterpret_cast<const T *>(tensor.Data()));
  70. }
  71. };
  72. template <typename T, int MajorType = Eigen::RowMajor,
  73. typename IndexType = Eigen::DenseIndex>
  74. struct EigenVector : public EigenTensor<T, 1, MajorType, IndexType> {
  75. // Flatten reshapes a Tensor into an EigenVector.
  76. static typename EigenVector::Type Flatten(FDTensor &tensor) { // NOLINT
  77. return EigenVector::From(tensor, {tensor.Numel()});
  78. }
  79. static typename EigenVector::ConstType
  80. Flatten(const FDTensor &tensor) { // NOLINT
  81. return EigenVector::From(tensor, {tensor.Numel()});
  82. }
  83. };
  84. template <typename T, int MajorType = Eigen::RowMajor,
  85. typename IndexType = Eigen::DenseIndex>
  86. struct EigenMatrix : public EigenTensor<T, 2, MajorType, IndexType> {
  87. static typename EigenMatrix::Type Reshape(FDTensor &tensor, // NOLINT
  88. int num_col_dims) {
  89. int rank = tensor.shape.size();
  90. FDASSERT((num_col_dims > 0 && num_col_dims < rank),
  91. "Input dimension number(num_col_dims) must be between 0 and %d, "
  92. "but received number is %d.",
  93. rank, num_col_dims);
  94. const int n = SizeToAxis(num_col_dims, tensor.shape);
  95. const int d = SizeFromAxis(num_col_dims, tensor.shape);
  96. return EigenMatrix::From(tensor, {n, d});
  97. }
  98. static typename EigenMatrix::ConstType Reshape(const FDTensor &tensor,
  99. int num_col_dims) {
  100. int rank = tensor.shape.size();
  101. FDASSERT((num_col_dims > 0 && num_col_dims < rank),
  102. "Input dimension number(num_col_dims) must be between 0 and %d, "
  103. "but received number is %d.",
  104. rank, num_col_dims);
  105. const int n = SizeToAxis(num_col_dims, tensor.shape);
  106. const int d = SizeFromAxis(num_col_dims, tensor.shape);
  107. return EigenMatrix::From(tensor, {n, d});
  108. }
  109. };
  110. class EigenDeviceWrapper {
  111. public:
  112. static std::shared_ptr<EigenDeviceWrapper> GetInstance();
  113. const Eigen::DefaultDevice *GetDevice() const;
  114. private:
  115. Eigen::DefaultDevice device_;
  116. static std::shared_ptr<EigenDeviceWrapper> instance_;
  117. };
  118. } // namespace function
  119. } // namespace ultra_infer