You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

tensor.cpp 9.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /**
  2. * \file lite-c/src/tensor.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2021 Megvii Inc. All rights reserved.
  6. *
  7. * Unless required by applicable law or agreed to in writing,
  8. * software distributed under the License is distributed on an
  9. * "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. */
  11. #include "lite/tensor.h"
  12. #include <set>
  13. #include <string>
  14. #include <unordered_map>
  15. #include "../../src/tensor_impl_base.h"
  16. #include "common.h"
  17. #include "lite-c/tensor_c.h"
  18. const LiteLayout default_layout = {
  19. .shapes = {0, 0, 0, 0, 0}, .ndim = 0, .data_type = LiteDataType::LITE_FLOAT};
  20. const LiteTensorDesc default_desc = {
  21. .is_pinned_host = false,
  22. .layout = default_layout,
  23. .device_type = LiteDeviceType::LITE_CPU,
  24. .device_id = 0};
  25. namespace {
  26. static LITE_MUTEX mtx_tensor;
  27. std::unordered_map<void*, std::shared_ptr<lite::Tensor>>& get_global_tensor_holder() {
  28. static std::unordered_map<void*, std::shared_ptr<lite::Tensor>> global_holder;
  29. return global_holder;
  30. }
  31. static LITE_MUTEX mtx_attr;
  32. std::unordered_map<std::string, lite::LiteAny>& get_global_tensor_attr_holder() {
  33. static std::unordered_map<std::string, lite::LiteAny> global_holder;
  34. return global_holder;
  35. }
  36. } // namespace
  37. //! convert the lite::Layout to Layout
  38. LiteLayout convert_to_clayout(const lite::Layout& layout) {
  39. LiteLayout clayout;
  40. clayout.ndim = layout.ndim;
  41. LITE_ASSERT(layout.ndim < LAYOUT_MAX_DIM, "layout ndim is to large");
  42. for (size_t i = 0; i < layout.ndim; i++) {
  43. clayout.shapes[i] = layout.shapes[i];
  44. }
  45. clayout.data_type = layout.data_type;
  46. return clayout;
  47. }
  48. //! convert the C Layout to lite::Layout
  49. lite::Layout convert_to_layout(const LiteLayout& clayout) {
  50. lite::Layout layout;
  51. layout.ndim = clayout.ndim;
  52. LITE_ASSERT(layout.ndim < LAYOUT_MAX_DIM, "clayout ndim is to large");
  53. for (size_t i = 0; i < layout.ndim; i++) {
  54. layout.shapes[i] = clayout.shapes[i];
  55. }
  56. layout.data_type = clayout.data_type;
  57. return layout;
  58. }
  59. int LITE_make_tensor(const LiteTensorDesc tensor_describe, LiteTensor* tensor) {
  60. LITE_CAPI_BEGIN();
  61. LITE_ASSERT(tensor, "The tensor pass to LITE_make_tensor is null");
  62. lite::Layout layout = convert_to_layout(tensor_describe.layout);
  63. auto lite_tensor = std::make_shared<lite::Tensor>(
  64. tensor_describe.device_id, tensor_describe.device_type, layout,
  65. tensor_describe.is_pinned_host);
  66. LITE_LOCK_GUARD(mtx_tensor);
  67. get_global_tensor_holder()[lite_tensor.get()] = lite_tensor;
  68. *tensor = lite_tensor.get();
  69. LITE_CAPI_END();
  70. }
  71. int LITE_destroy_tensor(LiteTensor tensor) {
  72. LITE_CAPI_BEGIN();
  73. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  74. LITE_LOCK_GUARD(mtx_tensor);
  75. get_global_tensor_holder().erase(tensor);
  76. LITE_CAPI_END();
  77. }
  78. int LITE_set_tensor_layout(LiteTensor tensor, const LiteLayout layout) {
  79. LITE_CAPI_BEGIN();
  80. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  81. auto tensor_ptr = static_cast<lite::Tensor*>(tensor);
  82. tensor_ptr->set_layout(convert_to_layout(layout));
  83. LITE_CAPI_END();
  84. }
  85. int LITE_reset_tensor_memory(
  86. LiteTensor tensor, void* prepared_data, size_t data_length_in_byte) {
  87. LITE_CAPI_BEGIN();
  88. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  89. LITE_ASSERT(prepared_data, "The prepared_data pass to LITE c_api is null");
  90. static_cast<lite::Tensor*>(tensor)->reset(prepared_data, data_length_in_byte);
  91. LITE_CAPI_END();
  92. }
  93. int LITE_reset_tensor(LiteTensor tensor, const LiteLayout layout, void* prepared_data) {
  94. LITE_CAPI_BEGIN();
  95. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  96. LITE_ASSERT(prepared_data, "The prepared_data pass to LITE c_api is null");
  97. static_cast<lite::Tensor*>(tensor)->reset(prepared_data, convert_to_layout(layout));
  98. LITE_CAPI_END();
  99. }
  100. int LITE_tensor_reshape(LiteTensor tensor, const int* shape, int size) {
  101. LITE_CAPI_BEGIN();
  102. LITE_ASSERT(tensor && shape, "The tensor pass to LITE c_api is null");
  103. std::vector<int> shapes;
  104. for (int i = 0; i < size; i++) {
  105. shapes.push_back(shape[i]);
  106. }
  107. static_cast<lite::Tensor*>(tensor)->reshape(shapes);
  108. LITE_CAPI_END();
  109. }
  110. int LITE_tensor_slice(
  111. const LiteTensor tensor, const size_t* start, const size_t* end,
  112. const size_t* step, size_t size, LiteTensor* slice_tensor) {
  113. LITE_CAPI_BEGIN();
  114. LITE_ASSERT(
  115. tensor && start && end && slice_tensor,
  116. "The tensor pass to LITE c_api is null");
  117. std::vector<size_t> starts, ends, steps;
  118. for (size_t i = 0; i < size; i++) {
  119. starts.push_back(start[i]);
  120. ends.push_back(end[i]);
  121. if (step) {
  122. steps.push_back(step[i]);
  123. }
  124. }
  125. auto ret_tensor = static_cast<lite::Tensor*>(tensor)->slice(starts, ends, steps);
  126. LITE_LOCK_GUARD(mtx_tensor);
  127. get_global_tensor_holder()[ret_tensor.get()] = ret_tensor;
  128. *slice_tensor = ret_tensor.get();
  129. LITE_CAPI_END();
  130. }
  131. int LITE_tensor_fill_zero(LiteTensor tensor) {
  132. LITE_CAPI_BEGIN();
  133. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  134. static_cast<lite::Tensor*>(tensor)->fill_zero();
  135. LITE_CAPI_END();
  136. }
  137. int LITE_tensor_copy(LiteTensor dst_tensor, const LiteTensor src_tensor) {
  138. LITE_CAPI_BEGIN();
  139. LITE_ASSERT(dst_tensor && src_tensor, "The tensor pass to LITE c_api is null");
  140. static_cast<lite::Tensor*>(dst_tensor)
  141. ->copy_from(*static_cast<lite::Tensor*>(src_tensor));
  142. LITE_CAPI_END();
  143. }
  144. int LITE_tensor_share_memory_with(LiteTensor dst_tensor, const LiteTensor src_tensor) {
  145. LITE_CAPI_BEGIN();
  146. LITE_ASSERT(dst_tensor && src_tensor, "The tensor pass to LITE c_api is null");
  147. static_cast<lite::Tensor*>(dst_tensor)
  148. ->share_memory_with(*static_cast<lite::Tensor*>(src_tensor));
  149. LITE_CAPI_END();
  150. }
  151. int LITE_get_tensor_memory(const LiteTensor tensor, void** data) {
  152. LITE_CAPI_BEGIN();
  153. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  154. LITE_ASSERT(data, "The data ptr pass to LITE c_api is null");
  155. *data = static_cast<lite::Tensor*>(tensor)->get_memory_ptr();
  156. LITE_CAPI_END();
  157. }
  158. int LITE_get_tensor_memory_with_index(
  159. const LiteTensor tensor, const size_t* index, size_t size, void** data) {
  160. LITE_CAPI_BEGIN();
  161. LITE_ASSERT(tensor && index && data, "The tensor pass to LITE c_api is null");
  162. std::vector<size_t> index_v;
  163. for (size_t i = 0; i < size; i++) {
  164. index_v.push_back(index[i]);
  165. }
  166. *data = static_cast<lite::Tensor*>(tensor)->get_memory_ptr(index_v);
  167. LITE_CAPI_END();
  168. }
  169. int LITE_get_tensor_total_size_in_byte(const LiteTensor tensor, size_t* size) {
  170. LITE_CAPI_BEGIN();
  171. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  172. LITE_ASSERT(size, "The size ptr pass to LITE c_api is null");
  173. *size = static_cast<lite::Tensor*>(tensor)->get_tensor_total_size_in_byte();
  174. LITE_CAPI_END();
  175. }
  176. int LITE_get_tensor_layout(const LiteTensor tensor, LiteLayout* layout) {
  177. LITE_CAPI_BEGIN();
  178. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  179. LITE_ASSERT(layout, "The layout ptr pass to LITE c_api is null");
  180. *layout = convert_to_clayout(static_cast<lite::Tensor*>(tensor)->get_layout());
  181. LITE_CAPI_END();
  182. }
  183. int LITE_get_tensor_device_type(const LiteTensor tensor, LiteDeviceType* device_type) {
  184. LITE_CAPI_BEGIN();
  185. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  186. LITE_ASSERT(device_type, "The device ptr pass to LITE c_api is null");
  187. *device_type = static_cast<lite::Tensor*>(tensor)->get_device_type();
  188. LITE_CAPI_END();
  189. }
  190. int LITE_get_tensor_device_id(const LiteTensor tensor, int* device_id) {
  191. LITE_CAPI_BEGIN();
  192. LITE_ASSERT(tensor && device_id, "The tensor pass to LITE c_api is null");
  193. *device_id = static_cast<lite::Tensor*>(tensor)->get_device_id();
  194. LITE_CAPI_END();
  195. }
  196. int LITE_is_pinned_host(const LiteTensor tensor, int* is_pinned_host) {
  197. LITE_CAPI_BEGIN();
  198. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  199. LITE_ASSERT(is_pinned_host, "The is_pinned_host ptr pass to LITE c_api is null");
  200. *is_pinned_host = static_cast<lite::Tensor*>(tensor)->is_pinned_host();
  201. LITE_CAPI_END();
  202. }
  203. int LITE_is_memory_continue(const LiteTensor tensor, int* is_continue) {
  204. LITE_CAPI_BEGIN();
  205. LITE_ASSERT(tensor, "The tensor pass to LITE c_api is null");
  206. LITE_ASSERT(is_continue, "The is_continue ptr pass to LITE c_api is null");
  207. *is_continue = static_cast<lite::Tensor*>(tensor)->is_continue_memory();
  208. LITE_CAPI_END();
  209. }
  210. int LITE_tensor_concat(
  211. LiteTensor* tensors, int nr_tensor, int dim, LiteDeviceType dst_device,
  212. int device_id, LiteTensor* result_tensor) {
  213. LITE_CAPI_BEGIN();
  214. std::vector<lite::Tensor> v_tensors;
  215. for (int i = 0; i < nr_tensor; i++) {
  216. v_tensors.push_back(*static_cast<lite::Tensor*>(tensors[i]));
  217. }
  218. auto tensor = lite::TensorUtils::concat(v_tensors, dim, dst_device, device_id);
  219. get_global_tensor_holder()[tensor.get()] = tensor;
  220. *result_tensor = tensor.get();
  221. LITE_CAPI_END()
  222. }
  223. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台