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.

utils.cpp 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * \file dnn/src/cuda/utils.cpp
  3. * MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  4. *
  5. * Copyright (c) 2014-2020 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 "src/cuda/utils.cuh"
  12. #include "src/cuda/utils.h"
  13. #include "src/common/utils.h"
  14. #include "src/cuda/handle.h"
  15. #include "src/cuda/int_fastdiv.cuh"
  16. #include <mutex>
  17. using namespace megdnn;
  18. using namespace cuda;
  19. namespace {
  20. struct DevicePropRec {
  21. bool init = false;
  22. cudaDeviceProp prop;
  23. std::mutex mtx;
  24. };
  25. constexpr int MAX_NR_DEVICE = 32;
  26. DevicePropRec device_prop_rec[MAX_NR_DEVICE];
  27. const char *cublasGetErrorString(cublasStatus_t error) {
  28. switch (error)
  29. {
  30. case CUBLAS_STATUS_SUCCESS:
  31. return "CUBLAS_STATUS_SUCCESS";
  32. case CUBLAS_STATUS_NOT_INITIALIZED:
  33. return "CUBLAS_STATUS_NOT_INITIALIZED";
  34. case CUBLAS_STATUS_ALLOC_FAILED:
  35. return "CUBLAS_STATUS_ALLOC_FAILED";
  36. case CUBLAS_STATUS_INVALID_VALUE:
  37. return "CUBLAS_STATUS_INVALID_VALUE";
  38. case CUBLAS_STATUS_ARCH_MISMATCH:
  39. return "CUBLAS_STATUS_ARCH_MISMATCH";
  40. case CUBLAS_STATUS_MAPPING_ERROR:
  41. return "CUBLAS_STATUS_MAPPING_ERROR";
  42. case CUBLAS_STATUS_EXECUTION_FAILED:
  43. return "CUBLAS_STATUS_EXECUTION_FAILED";
  44. case CUBLAS_STATUS_INTERNAL_ERROR:
  45. return "CUBLAS_STATUS_INTERNAL_ERROR";
  46. case CUBLAS_STATUS_LICENSE_ERROR:
  47. return "CUBLAS_STATUS_LICENSE_ERROR";
  48. case CUBLAS_STATUS_NOT_SUPPORTED:
  49. return "CUBLAS_STATUS_NOT_SUPPORTED";
  50. }
  51. return "Unknown CUBLAS error";
  52. }
  53. } // anonymous namespace
  54. void cuda::__throw_cuda_error__(cudaError_t err, const char *msg) {
  55. auto s = ssprintf("cuda error %s(%d) occurred; expr: %s",
  56. cudaGetErrorString(err), int(err), msg);
  57. megdnn_throw(s.c_str());
  58. }
  59. void cuda::__throw_cudnn_error__(cudnnStatus_t err, const char *msg) {
  60. auto s = ssprintf("cudnn error %s(%d) occurred; expr: %s",
  61. cudnnGetErrorString(err), int(err), msg);
  62. megdnn_throw(s.c_str());
  63. }
  64. void cuda::__throw_cublas_error__(cublasStatus_t err, const char *msg) {
  65. auto s = ssprintf("cublas error %s(%d) occurred; expr: %s",
  66. cublasGetErrorString(err), int(err), msg);
  67. megdnn_throw(s.c_str());
  68. }
  69. void cuda::__throw_cusolver_error__(cusolverStatus_t err, const char* msg) {
  70. auto s = ssprintf("cusolver error %d occurred; expr: %s", int(err), msg);
  71. megdnn_throw(s.c_str());
  72. }
  73. void cuda::__throw_cuda_driver_error__(CUresult err, const char* msg) {
  74. auto s = ssprintf("cuda driver error %d occurred; expr: %s", int(err), msg);
  75. megdnn_throw(s.c_str());
  76. }
  77. void cuda::report_error(const char *msg) {
  78. megdnn_throw(msg);
  79. MEGDNN_MARK_USED_VAR(msg);
  80. }
  81. uint32_t cuda::safe_size_in_kern(size_t size) {
  82. if (!size || size > Uint32Fastdiv::MAX_DIVIDEND) {
  83. megdnn_throw(ssprintf(
  84. "invalid size for element-wise kernel: %zu; "
  85. "max supported size is %u",
  86. size, Uint32Fastdiv::MAX_DIVIDEND));
  87. }
  88. return size;
  89. }
  90. cudaDeviceProp cuda::current_device_prop() {
  91. int dev;
  92. cuda_check(cudaGetDevice(&dev));
  93. megdnn_assert(dev < MAX_NR_DEVICE, "device number too large: %d", dev);
  94. auto &&rec = device_prop_rec[dev];
  95. if (!rec.init) {
  96. std::lock_guard<std::mutex> lock(rec.mtx);
  97. if (!rec.init) {
  98. cuda_check(cudaGetDeviceProperties(&rec.prop, dev));
  99. rec.init = true;
  100. }
  101. }
  102. return rec.prop;
  103. }
  104. bool cuda::is_compute_capability_required(int major, int minor) {
  105. auto&& device_prop = cuda::current_device_prop();
  106. return device_prop.major > major ||
  107. (device_prop.major == major && device_prop.minor >= minor);
  108. }
  109. bool cuda::is_compute_capability_equalto(int major, int minor) {
  110. auto&& device_prop = cuda::current_device_prop();
  111. return device_prop.major == major && device_prop.minor == minor;
  112. }
  113. size_t cuda::max_batch_x_channel_size() {
  114. return current_device_prop().maxGridSize[2];
  115. }
  116. const char* cuda::current_device_arch_name() {
  117. auto&& device_prop = current_device_prop();
  118. int cap = 10 * device_prop.major + device_prop.minor;
  119. if (cap >= 50 && cap < 60)
  120. return "maxwell";
  121. else if (cap >= 60 && cap < 70)
  122. return "pascal";
  123. else if (cap >= 70 && cap < 75)
  124. return "volta";
  125. else if (cap >= 75 && cap < 80)
  126. return "turing";
  127. else if (cap >= 80)
  128. return "ampere";
  129. megdnn_throw(
  130. ssprintf("unsupported cuda compute capability %d", cap).c_str());
  131. }
  132. // vim: syntax=cpp.doxygen

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