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.

gpu_buffer_mgr.cc 6.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /**
  2. * Copyright 2019 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "device/gpu/gpu_buffer_mgr.h"
  17. #include <cuda_runtime_api.h>
  18. #include <utility>
  19. #include "utils/log_adapter.h"
  20. #include "common/utils.h"
  21. namespace mindspore {
  22. namespace device {
  23. unsigned int HandleMgr::AllocHandle() {
  24. for (size_t i = 0; i < MAX_HANDLE_NUM; ++i) {
  25. if (!handle_list_[i]) {
  26. handle_list_[i] = true;
  27. return (unsigned int)i;
  28. }
  29. }
  30. return INVALID_HANDLE;
  31. }
  32. void HandleMgr::FreeHandle(unsigned int handle_id) {
  33. if (handle_id >= MAX_HANDLE_NUM) {
  34. return;
  35. }
  36. handle_list_[handle_id] = false;
  37. }
  38. GpuBufferMgr &GpuBufferMgr::GetInstance() noexcept {
  39. static GpuBufferMgr instance;
  40. return instance;
  41. }
  42. BlockQueueStatus_T GpuBufferMgr::Create(unsigned int device_id, const std::string &channel_name, void *addr,
  43. const std::vector<size_t> &shape, const size_t &capacity) {
  44. std::string name = std::to_string(device_id) + std::string("_") + channel_name;
  45. if (name_queue_map_.count(name)) {
  46. MS_LOG(ERROR) << "Queue not exist " << name;
  47. return QUEUE_NOT_EXIST;
  48. }
  49. std::shared_ptr<BlockingQueue> queue = std::make_shared<BlockingQueue>();
  50. BlockQueueStatus_T rt = queue->Create(addr, shape, capacity);
  51. if (rt != SUCCESS) {
  52. return rt;
  53. }
  54. (void)name_queue_map_.insert(std::make_pair(name, queue));
  55. init_ = true;
  56. return SUCCESS;
  57. }
  58. unsigned int GpuBufferMgr::Open(unsigned int device_id, const std::string &channel_name,
  59. const std::vector<size_t> &shape, const std::function<void(void *)> func) {
  60. set_device();
  61. std::string name = std::to_string(device_id) + std::string("_") + channel_name;
  62. if (!name_queue_map_.count(name)) {
  63. MS_LOG(ERROR) << "Queue not exist " << name;
  64. return HandleMgr::INVALID_HANDLE;
  65. }
  66. unsigned int handle = handle_mgr_.AllocHandle();
  67. if (handle == HandleMgr::INVALID_HANDLE) {
  68. MS_LOG(ERROR) << "handle is invalid";
  69. return HandleMgr::INVALID_HANDLE;
  70. }
  71. (void)handle_queue_map_.insert(std::make_pair(handle, name_queue_map_[name]));
  72. name_queue_map_[name]->RegisterRelease(func);
  73. open_by_dataset_++;
  74. return handle;
  75. }
  76. unsigned int GpuBufferMgr::Open(unsigned int device_id, const std::string &channel_name,
  77. const std::vector<size_t> &shape) {
  78. set_device();
  79. std::string name = std::to_string(device_id) + std::string("_") + channel_name;
  80. if (!name_queue_map_.count(name)) {
  81. MS_LOG(ERROR) << "Queue not exist " << name;
  82. return HandleMgr::INVALID_HANDLE;
  83. }
  84. unsigned int handle = handle_mgr_.AllocHandle();
  85. if (handle == HandleMgr::INVALID_HANDLE) {
  86. MS_LOG(ERROR) << "handle is invalid";
  87. return HandleMgr::INVALID_HANDLE;
  88. }
  89. (void)handle_queue_map_.insert(std::make_pair(handle, name_queue_map_[name]));
  90. return handle;
  91. }
  92. void GpuBufferMgr::set_device_id(int device_id) { cur_dev_id_ = device_id; }
  93. void GpuBufferMgr::set_device() const {
  94. auto ret = cudaSetDevice(cur_dev_id_);
  95. if (ret != cudaSuccess) {
  96. MS_LOG(ERROR) << "cudaSetDevice, ret[" << static_cast<int>(ret) << "]";
  97. }
  98. }
  99. BlockQueueStatus_T GpuBufferMgr::Push(unsigned int handle, const std::vector<DataItemGpu> &data,
  100. unsigned int timeout_in_sec) {
  101. auto iter = handle_queue_map_.find(handle);
  102. if (iter == handle_queue_map_.end()) {
  103. return HANDLE_NOT_EXIST;
  104. }
  105. return iter->second->Push(data, timeout_in_sec);
  106. }
  107. BlockQueueStatus_T GpuBufferMgr::Front(unsigned int handle, void **addr, size_t *len) {
  108. auto iter = handle_queue_map_.find(handle);
  109. if (iter == handle_queue_map_.end()) {
  110. return HANDLE_NOT_EXIST;
  111. }
  112. return iter->second->Front(addr, len);
  113. }
  114. BlockQueueStatus_T GpuBufferMgr::Pop(unsigned int handle) {
  115. auto iter = handle_queue_map_.find(handle);
  116. if (iter == handle_queue_map_.end()) {
  117. return HANDLE_NOT_EXIST;
  118. }
  119. return iter->second->Pop();
  120. }
  121. void GpuBufferMgr::Close(unsigned int handle) noexcept {
  122. if (!handle_queue_map_.count(handle)) {
  123. return;
  124. }
  125. (void)handle_queue_map_.erase(handle);
  126. handle_mgr_.FreeHandle(handle);
  127. return;
  128. }
  129. bool GpuBufferMgr::IsInit() const { return init_; }
  130. bool GpuBufferMgr::IsClosed() const { return closed_; }
  131. bool GpuBufferMgr::Destroy() {
  132. for (auto iter = name_queue_map_.begin(); iter != name_queue_map_.end(); ++iter) {
  133. std::shared_ptr<BlockingQueue> queue = iter->second;
  134. if (queue != nullptr) {
  135. if (!queue->Destroy()) {
  136. return false;
  137. }
  138. queue.reset();
  139. }
  140. }
  141. name_queue_map_.clear();
  142. return true;
  143. }
  144. inline bool GpuBufferMgr::isCreated(unsigned int device_id, const std::string &channel_name) {
  145. std::string name = std::to_string(device_id) + std::string("_") + channel_name;
  146. if (name_queue_map_.count(name) != 0) {
  147. return true;
  148. }
  149. return false;
  150. }
  151. bool GpuBufferMgr::CloseNotify() {
  152. bool result = true;
  153. // lock scope
  154. {
  155. std::lock_guard<std::mutex> lk(close_mutex_);
  156. // set closed_ to be true, all the dataset retry can be jumped out of the while
  157. closed_ = true;
  158. }
  159. // wati for the dataset threads' ack
  160. for (int i = 0; i < open_by_dataset_; i++) {
  161. if (sema.Wait() == false) {
  162. MS_LOG(ERROR) << "time out of receiving signals";
  163. result = false;
  164. }
  165. MS_LOG(DEBUG) << "receive one signal (" << i + 1 << "/" << open_by_dataset_ << ")";
  166. }
  167. return result;
  168. }
  169. void GpuBufferMgr::CloseConfirm() { sema.Signal(); }
  170. } // namespace device
  171. } // namespace mindspore