arithmetic.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include <stdexcept>
  2. #include <algorithm>
  3. #include <traph/tensor/tensor.h>
  4. #include <traph/tensor/arithmetic.h>
  5. #include <eigen3/Eigen/Dense>
  6. #ifdef TRAPH_BUILD_MKL
  7. #include <mkl.h>
  8. #include <mkl_blas.h>
  9. #include <mkl_cblas.h>
  10. #elif defined TRAPH_BUILD_OPENBLAS
  11. #include <openBLAS/cblas.h>
  12. #endif
  13. namespace traph
  14. {
  15. std::shared_ptr<Tensor<u8>> matmul_impl(const Tensor<u8>& a, const Tensor<u8>& b)
  16. {
  17. // check
  18. matmul_check(a, b);
  19. // result
  20. DimVector dim;
  21. dim.push_back(a.size()[0]);
  22. dim.push_back(b.size()[1]);
  23. std::shared_ptr<Tensor<u8>> result(new Tensor<u8>(dim));
  24. // copy data
  25. Eigen::Map<const Eigen::Matrix<u8, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  26. Eigen::Map<const Eigen::Matrix<u8, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  27. Eigen::Matrix<u8, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  28. // copy to result
  29. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  30. return result;
  31. }
  32. std::shared_ptr<Tensor<i8>> matmul_impl(const Tensor<i8>& a, const Tensor<i8>& b)
  33. {
  34. // check
  35. matmul_check(a, b);
  36. // result
  37. DimVector dim;
  38. dim.push_back(a.size()[0]);
  39. dim.push_back(b.size()[1]);
  40. std::shared_ptr<Tensor<i8>> result(new Tensor<i8>(dim));
  41. // copy data
  42. Eigen::Map<const Eigen::Matrix<i8, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  43. Eigen::Map<const Eigen::Matrix<i8, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  44. Eigen::Matrix<i8, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  45. // copy to result
  46. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  47. return result;
  48. }
  49. std::shared_ptr<Tensor<i16>> matmul_impl(const Tensor<i16>& a, const Tensor<i16>& b)
  50. {
  51. // check
  52. matmul_check(a, b);
  53. // result
  54. DimVector dim;
  55. dim.push_back(a.size()[0]);
  56. dim.push_back(b.size()[1]);
  57. std::shared_ptr<Tensor<i16>> result(new Tensor<i16>(dim));
  58. // copy data
  59. Eigen::Map<const Eigen::Matrix<i16, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  60. Eigen::Map<const Eigen::Matrix<i16, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  61. Eigen::Matrix<i16, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  62. // copy to result
  63. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  64. return result;
  65. }
  66. std::shared_ptr<Tensor<i32>> matmul_impl(const Tensor<i32>& a, const Tensor<i32>& b)
  67. {
  68. // check
  69. matmul_check(a, b);
  70. // result
  71. DimVector dim;
  72. dim.push_back(a.size()[0]);
  73. dim.push_back(b.size()[1]);
  74. std::shared_ptr<Tensor<i32>> result(new Tensor<i32>(dim));
  75. // copy data
  76. Eigen::Map<const Eigen::Matrix<i32, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  77. Eigen::Map<const Eigen::Matrix<i32, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  78. Eigen::Matrix<i32, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  79. // copy to result
  80. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  81. return result;
  82. }
  83. std::shared_ptr<Tensor<i64>> matmul_impl(const Tensor<i64>& a, const Tensor<i64>& b)
  84. {
  85. // check
  86. matmul_check(a, b);
  87. // result
  88. DimVector dim;
  89. dim.push_back(a.size()[0]);
  90. dim.push_back(b.size()[1]);
  91. std::shared_ptr<Tensor<i64>> result(new Tensor<i64>(dim));
  92. // copy data
  93. Eigen::Map<const Eigen::Matrix<i64, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  94. Eigen::Map<const Eigen::Matrix<i64, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  95. Eigen::Matrix<i64, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  96. // copy to result
  97. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  98. return result;
  99. }
  100. std::shared_ptr<Tensor<f32>> matmul_impl(const Tensor<f32>& a, const Tensor<f32>& b)
  101. {
  102. // check
  103. matmul_check(a, b);
  104. // result
  105. DimVector dim;
  106. dim.push_back(a.size()[0]);
  107. dim.push_back(b.size()[1]);
  108. std::shared_ptr<Tensor<f32>> result(new Tensor<f32>(dim));
  109. #ifdef TRAPH_BUILD_EIGEN
  110. // copy data
  111. Eigen::Map<const Eigen::Matrix<f32, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  112. Eigen::Map<const Eigen::Matrix<f32, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  113. Eigen::Matrix<f32, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  114. // copy to result
  115. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  116. #elif defined TRAPH_BUILD_MKL
  117. CBLAS_LAYOUT a_layout = a.order() == layout_type::column_major ? CBLAS_LAYOUT::CblasColMajor : CBLAS_LAYOUT::CblasRowMajor;
  118. cblas_sgemm(a_layout,
  119. CBLAS_TRANSPOSE::CblasNoTrans,
  120. CBLAS_TRANSPOSE::CblasNoTrans,
  121. a.size()[0],
  122. b.size()[1],
  123. a.size()[1],
  124. 1.f,
  125. a.data_ptr(),
  126. a.size()[0],
  127. b.data_ptr(),
  128. b.size()[0],
  129. 0.f,
  130. result->data_ptr(),
  131. result->size()[0]);
  132. #endif
  133. return result;
  134. }
  135. std::shared_ptr<Tensor<f64>> matmul_impl(const Tensor<f64>& a, const Tensor<f64>& b)
  136. {
  137. // check
  138. matmul_check(a, b);
  139. // result
  140. DimVector dim;
  141. dim.push_back(a.size()[0]);
  142. dim.push_back(b.size()[1]);
  143. std::shared_ptr<Tensor<f64>> result(new Tensor<f64>(dim));
  144. #ifdef TRAPH_BUILD_EIGEN
  145. // copy data
  146. Eigen::Map<const Eigen::Matrix<f64, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  147. Eigen::Map<const Eigen::Matrix<f64, Eigen::Dynamic, Eigen::Dynamic>> eigen_b(b.data_ptr() + b.offset(), b.size()[0], b.size()[1]);
  148. Eigen::Matrix<f64, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a * eigen_b;
  149. // copy to result
  150. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * b.size()[1], result->data_ptr());
  151. #elif defined TRAPH_BUILD_MKL
  152. CBLAS_LAYOUT a_layout = a.order() == layout_type::column_major ? CBLAS_LAYOUT::CblasColMajor : CBLAS_LAYOUT::CblasRowMajor;
  153. cblas_dgemm(a_layout,
  154. CBLAS_TRANSPOSE::CblasNoTrans,
  155. CBLAS_TRANSPOSE::CblasNoTrans,
  156. a.size()[0],
  157. b.size()[1],
  158. a.size()[1],
  159. 1.f,
  160. a.data_ptr(),
  161. a.size()[0],
  162. b.data_ptr(),
  163. b.size()[0],
  164. 0.f,
  165. result->data_ptr(),
  166. result->size()[0]);
  167. #endif
  168. return result;
  169. }
  170. std::shared_ptr<Tensor<f32>> inverse_impl(const Tensor<f32>& a)
  171. {
  172. // result
  173. std::shared_ptr<Tensor<f32>> result(new Tensor<f32>(a.size()[0], a.size()[1]));
  174. // copy data
  175. Eigen::Map<const Eigen::Matrix<f32, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  176. Eigen::Matrix<f32, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a.inverse();
  177. // copy to result
  178. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * a.size()[1], result->data_ptr());
  179. return result;
  180. }
  181. std::shared_ptr<Tensor<f64>> inverse_impl(const Tensor<f64>& a)
  182. {
  183. // result
  184. std::shared_ptr<Tensor<f64>> result(new Tensor<f64>(a.size()[0], a.size()[1]));
  185. // copy data
  186. Eigen::Map<const Eigen::Matrix<f64, Eigen::Dynamic, Eigen::Dynamic>> eigen_a(a.data_ptr() + a.offset(), a.size()[0], a.size()[1]);
  187. Eigen::Matrix<f64, Eigen::Dynamic, Eigen::Dynamic> eigen_c = eigen_a.inverse();
  188. // copy to result
  189. std::copy(eigen_c.data(), eigen_c.data() + a.size()[0] * a.size()[1], result->data_ptr());
  190. return result;
  191. }
  192. }