cnstream_syncmem.hpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*********************************************************************************************************
  2. * All modification made by Cambricon Corporation: © 2018--2019 Cambricon Corporation
  3. * All rights reserved.
  4. * All other contributions:
  5. * Copyright (c) 2014--2018, the respective contributors
  6. * All rights reserved.
  7. * For the list of contributors go to https://github.com/BVLC/caffe/blob/master/CONTRIBUTORS.md
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. * * Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * * Neither the name of Intel Corporation nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *********************************************************************************************************/
  29. #ifndef CNSTREAM_SYNCMEM_HPP_
  30. #define CNSTREAM_SYNCMEM_HPP_
  31. /**
  32. * @file cnstream_syncmem.hpp
  33. *
  34. * This file contains a declaration of the CNSyncedMemory class.
  35. */
  36. #include <cstddef>
  37. #include <mutex>
  38. #include "cnrt.h"
  39. #include "cnstream_common.hpp"
  40. #include "cnstream_logging.hpp"
  41. #define CNS_CNRT_CHECK(__EXPRESSION__) \
  42. do { \
  43. cnrtRet_t ret = (__EXPRESSION__); \
  44. LOGF_IF(FRAME, CNRT_RET_SUCCESS != ret) << "Call [" << #__EXPRESSION__ << "] failed, error code: " << ret; \
  45. } while (0)
  46. #define CALL_CNRT_BY_CONTEXT(__EXPRESSION__, __DEV_ID__, __DDR_CHN__) \
  47. do { \
  48. int dev_id = (__DEV_ID__); \
  49. cnrtDev_t dev; \
  50. cnrtChannelType_t ddr_chn = static_cast<cnrtChannelType_t>((__DDR_CHN__)); \
  51. CNS_CNRT_CHECK(cnrtGetDeviceHandle(&dev, dev_id)); \
  52. CNS_CNRT_CHECK(cnrtSetCurrentDevice(dev)); \
  53. if (ddr_chn >= 0) \
  54. CNS_CNRT_CHECK(cnrtSetCurrentChannel(ddr_chn)); \
  55. CNS_CNRT_CHECK(__EXPRESSION__); \
  56. } while (0)
  57. namespace cnstream {
  58. /**
  59. * @class CNSyncedMemory
  60. *
  61. * @brief CNSyncedMemory is a class synchronizing memory between CPU and MLU.
  62. *
  63. * If the data on MLU is the latest, the data on CPU should be synchronized before processing the data on CPU.
  64. * Vice versa, if the data on CPU is the latest, the data on MLU should be synchronized before processing
  65. * the data on MLU.
  66. *
  67. * @note CNSyncedMemory::Head() always returns SyncedHead::UNINITIALIZED when memory size is 0.
  68. */
  69. class CNSyncedMemory : private NonCopyable {
  70. public:
  71. /**
  72. * @brief Constructor to construct synchronized memory object.
  73. *
  74. * @param[in] size The size of the memory.
  75. *
  76. * @return No return value.
  77. */
  78. explicit CNSyncedMemory(size_t size);
  79. /**
  80. * @brief Constructor to construct synchronized memory object.
  81. *
  82. * @param[in] size The size of the memory.
  83. * @param[in] mlu_dev_id MLU device ID that is incremented from 0.
  84. * @param[in] mlu_ddr_chn The MLU DDR channel that is greater than or equal to 0, and is less
  85. * than 4. It specifies which piece of DDR channel the memory allocated on.
  86. *
  87. * @return No return value.
  88. */
  89. explicit CNSyncedMemory(size_t size, int mlu_dev_id, int mlu_ddr_chn = -1);
  90. /**
  91. * @brief Destructor to destruct synchronized memory object.
  92. *
  93. * @return No return value.
  94. */
  95. ~CNSyncedMemory();
  96. /**
  97. * @brief Gets the CPU data.
  98. *
  99. * @param No return value.
  100. *
  101. * @return Returns the CPU data pointer.
  102. *
  103. * @note If the size is 0, nullptr is always returned.
  104. */
  105. const void* GetCpuData();
  106. /**
  107. * @brief Sets the CPU data.
  108. *
  109. * @param[in] data The data pointer on CPU.
  110. *
  111. * @return Void.
  112. */
  113. void SetCpuData(void* data);
  114. /**
  115. * @brief Gets the MLU data.
  116. *
  117. * @return Returns the MLU data pointer.
  118. *
  119. * @note If the size is 0, nullptr is always returned.
  120. */
  121. const void* GetMluData();
  122. /**
  123. * @brief Sets the MLU data.
  124. *
  125. * @param[out] data The data pointer on MLU.
  126. *
  127. * @return No return value.
  128. */
  129. void SetMluData(void* data);
  130. /**
  131. * @brief Sets the MLU device context.
  132. *
  133. * @param[in] dev_id The MLU device ID that is incremented from 0.
  134. * @param[in] ddr_chn The MLU DDR channel ID that is greater than or equal to 0, and less than
  135. * 4. It specifies which piece of DDR channel the memory is allocated on.
  136. *
  137. * @return No return value.
  138. *
  139. * @note You need to call this API before all getters and setters.
  140. */
  141. void SetMluDevContext(int dev_id, int ddr_chn = -1);
  142. /**
  143. * @brief Gets the MLU device ID.
  144. *
  145. * @return Returns the ID of the device that the MLU memory is allocated on.
  146. */
  147. int GetMluDevId() const;
  148. /**
  149. * @brief Gets the channel ID of the MLU DDR.
  150. *
  151. * @return Returns the DDR channel ID that the MLU memory is allocated on.
  152. */
  153. int GetMluDdrChnId() const;
  154. /**
  155. * @brief Gets the mutable CPU data.
  156. *
  157. * @return Returns the CPU data pointer.
  158. */
  159. void* GetMutableCpuData();
  160. /**
  161. * @brief Gets the mutable MLU data.
  162. *
  163. * @return Returns the MLU data pointer.
  164. */
  165. void* GetMutableMluData();
  166. /**
  167. * @enum SyncedHead
  168. *
  169. * @brief An enumerator describing the synchronization status.
  170. */
  171. enum class SyncedHead {
  172. UNINITIALIZED, ///< The memory is not allocated.
  173. HEAD_AT_CPU, ///< The data is updated to CPU but is not synchronized to MLU yet.
  174. HEAD_AT_MLU, ///< The data is updated to MLU but is not synchronized to CPU yet.
  175. SYNCED ///< The data is synchronized to both CPU and MLU.
  176. };
  177. /**
  178. * @brief Gets synchronization status.
  179. *
  180. * @return Returns synchronization status .
  181. *
  182. * @see SyncedHead.
  183. */
  184. SyncedHead GetHead() const { return head_; }
  185. /**
  186. * @brief Gets data bytes.
  187. *
  188. * @return Returns data bytes.
  189. */
  190. size_t GetSize() const { return size_; }
  191. #ifndef UNIT_TEST
  192. private: // NOLINT
  193. #endif
  194. /**
  195. * Allocates memory by ``CNSyncedMemory`` if a certain condition is true.
  196. */
  197. bool own_cpu_data_ = false; ///< Whether CPU data is allocated by ``SyncedMemory``.
  198. bool own_mlu_data_ = false; ///< Whether MLU data is allocated by ``SyncedMemory``.
  199. private:
  200. /**
  201. * Synchronizes the memory data to CPU.
  202. */
  203. void ToCpu();
  204. /**
  205. * Synchronizes the memory data to MLU.
  206. */
  207. void ToMlu();
  208. void* cpu_ptr_ = nullptr; ///< CPU data pointer.
  209. void* mlu_ptr_ = nullptr; ///< MLU data pointer.
  210. SyncedHead head_ = SyncedHead::UNINITIALIZED; ///< Identifies which device data is synchronized on.
  211. size_t size_ = 0; ///< The data size.
  212. int dev_id_ = -1; ///< Ordinal MLU device ID.
  213. int ddr_chn_ = -1; ///< Ordinal MLU DDR channel ID. The value should be [0, 4).
  214. mutable std::mutex mutex_;
  215. }; // class CNSyncedMemory
  216. } // namespace cnstream
  217. #endif // CNSTREAM_SYNCMEM_HPP_