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.

megbrain_config.cpp 9.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /**
  2. * \file python_module/src/cpp/megbrain_config.cpp
  3. *
  4. * This file is part of MegBrain, a deep learning framework developed by Megvii.
  5. *
  6. * \copyright Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
  7. *
  8. */
  9. #include "./megbrain_config.h"
  10. #include "./python_helper.h"
  11. #include "megbrain/graph/event.h"
  12. #include "megbrain/utils/debug.h"
  13. #include "megbrain/comp_node_env.h"
  14. #include "megbrain/serialization/opr_registry.h"
  15. #include <set>
  16. #include <dlfcn.h>
  17. #if MGB_ENABLE_OPR_MM
  18. #include "megbrain/opr/mm_handler.h"
  19. #endif
  20. #if MGB_CUDA
  21. #include <cuda.h>
  22. #endif
  23. using namespace mgb;
  24. namespace {
  25. std::unordered_map<ComputingGraph*,
  26. SyncEventConnecter::ReceiverHandler>
  27. set_priority_on_opr_inserted_handle;
  28. std::mutex set_priority_on_opr_inserted_handle_mtx;
  29. } // anonymous namespace
  30. bool _config::set_comp_graph_option(
  31. CompGraph &cg, const std::string &name, int val_int) {
  32. #define SET_CG_OPTION(name_chk) \
  33. do { \
  34. static_assert( \
  35. std::is_same<decltype(opt.name_chk), bool>::value || \
  36. std::is_same<decltype(opt.name_chk), uint8_t>::value || \
  37. std::is_same<decltype(opt.name_chk), int16_t>::value || \
  38. std::is_same<decltype(opt.name_chk), uint16_t>::value || \
  39. std::is_same<decltype(opt.name_chk), int32_t>::value, \
  40. "not bool/int opt"); \
  41. if (name == #name_chk) { \
  42. auto ret = opt.name_chk; \
  43. opt.name_chk = val_int; \
  44. return ret; \
  45. } \
  46. } while(0)
  47. auto &&opt = cg.get().options();
  48. SET_CG_OPTION(seq_opt.enable_mem_plan_opt);
  49. SET_CG_OPTION(seq_opt.enable_mem_reuse_alloc);
  50. SET_CG_OPTION(seq_opt.enable_seq_comp_node_opt);
  51. SET_CG_OPTION(force_dynamic_alloc);
  52. SET_CG_OPTION(enable_grad_var_static_reshape);
  53. SET_CG_OPTION(async_exec_level);
  54. SET_CG_OPTION(graph_opt.jit);
  55. SET_CG_OPTION(graph_opt.tensorrt);
  56. SET_CG_OPTION(graph_opt_level);
  57. SET_CG_OPTION(allreduce_pack_max_size);
  58. SET_CG_OPTION(allreduce_pack_ignore_first);
  59. SET_CG_OPTION(var_sanity_check_first_run);
  60. SET_CG_OPTION(no_profiling_on_shape_change);
  61. SET_CG_OPTION(allocate_static_mem_after_graph_compile);
  62. SET_CG_OPTION(log_level);
  63. SET_CG_OPTION(enable_sublinear_memory_opt);
  64. SET_CG_OPTION(sublinear_mem_cofig.lb_memory);
  65. SET_CG_OPTION(sublinear_mem_cofig.genetic_nr_iter);
  66. SET_CG_OPTION(sublinear_mem_cofig.genetic_pool_size);
  67. SET_CG_OPTION(sublinear_mem_cofig.thresh_nr_try);
  68. SET_CG_OPTION(sublinear_mem_cofig.num_worker);
  69. SET_CG_OPTION(enable_var_mem_defragment);
  70. SET_CG_OPTION(eager_evaluation);
  71. SET_CG_OPTION(enable_memory_swap);
  72. throw MegBrainError(ssprintf(
  73. "invalid computing graph option name: %s", name.c_str()));
  74. #undef SET_CG_OPTION
  75. }
  76. bool _config::comp_graph_is_eager(CompGraph &cg) {
  77. return cg.get().options().eager_evaluation;
  78. }
  79. void _config::add_extra_vardep(const SymbolVar &var, const SymbolVar &dep) {
  80. auto og = var.node()->owner_graph();
  81. mgb_assert(og == dep.node()->owner_graph());
  82. og->options().extra_vardeps[var.node()].push_back(dep.node());
  83. }
  84. void _config::begin_set_opr_priority(CompGraph& cg, int priority) {
  85. SyncEventConnecter::ReceiverHandler* handle;
  86. {
  87. MGB_LOCK_GUARD(set_priority_on_opr_inserted_handle_mtx);
  88. handle = &set_priority_on_opr_inserted_handle[&cg.get()];
  89. }
  90. mgb_assert(!*handle, "multiple calls to _begin_set_opr_priority()");
  91. auto on_opr_inserted = [priority](const cg::event::OprInserted& event) {
  92. if (!event.exc && priority) {
  93. int& pri = event.opr->node_prop().attribute().priority;
  94. if (!pri)
  95. pri = priority;
  96. else
  97. pri = std::min(pri, priority);
  98. }
  99. };
  100. *handle = cg.get().event().register_receiver<cg::event::OprInserted>(
  101. on_opr_inserted);
  102. }
  103. void _config::end_set_opr_priority(CompGraph &cg) {
  104. MGB_LOCK_GUARD(set_priority_on_opr_inserted_handle_mtx);
  105. auto nr = set_priority_on_opr_inserted_handle.erase(&cg.get());
  106. mgb_assert(nr, "end_set_opr_priority called "
  107. "before begin_set_opr_priority");
  108. }
  109. void _config::begin_set_exc_opr_tracker(CompGraph &cg, PyObject *tracker) {
  110. OprPyTracker::begin_set_tracker(cg.get(), tracker);
  111. }
  112. void _config::end_set_exc_opr_tracker(CompGraph &cg) {
  113. OprPyTracker::end_set_tracker(cg.get());
  114. }
  115. PyObject* _config::get_opr_tracker(CompGraph &cg, size_t var_id) {
  116. auto var = cg.get().find_var_by_id(var_id);
  117. if (!var)
  118. Py_RETURN_NONE;
  119. return OprPyTracker::get_tracker(var->owner_opr()).as_tuple();
  120. }
  121. void _config::set_opr_sublinear_memory_endpoint(const SymbolVar &var) {
  122. MGB_MARK_USED_VAR(var);
  123. #if MGB_ENABLE_SUBLINEAR
  124. auto opr = var.node()->owner_opr();
  125. opr->owner_graph()->options().opr_attribute.sublinear_memory_endpoint.
  126. insert(opr);
  127. #endif
  128. }
  129. void _config::set_fork_cuda_warning_flag(int flag) {
  130. #if MGB_ENABLE_DEBUG_UTIL
  131. debug::set_fork_cuda_warning_flag(flag);
  132. #else
  133. MGB_MARK_USED_VAR(flag);
  134. #endif
  135. }
  136. bool _config::is_cuda_ctx_set() {
  137. #if MGB_CUDA
  138. CUcontext ctx;
  139. return cuCtxGetCurrent(&ctx) == CUDA_SUCCESS && ctx;
  140. #else
  141. return false;
  142. #endif
  143. }
  144. std::string _config::get_cuda_gencode() {
  145. #if MGB_CUDA
  146. std::set<std::string> used;
  147. int nr_dev;
  148. auto err = cudaGetDeviceCount(&nr_dev);
  149. if (err == cudaErrorNoDevice) {
  150. return {};
  151. }
  152. MGB_CUDA_CHECK(err);
  153. for (int i = 0; i < nr_dev; ++ i) {
  154. cudaDeviceProp prop;
  155. MGB_CUDA_CHECK(cudaGetDeviceProperties(&prop, i));
  156. std::string cur{std::to_string(prop.major)};
  157. cur += std::to_string(prop.minor);
  158. used.insert(cur);
  159. }
  160. std::string ret;
  161. for (auto &&i: used) {
  162. if (!ret.empty())
  163. ret.append(" ");
  164. ret.append(i);
  165. }
  166. return ret;
  167. #else
  168. mgb_throw(MegBrainError, "cuda disabled at compile time");
  169. #endif
  170. }
  171. namespace {
  172. #if MGB_CUDA
  173. std::string get_loaded_shared_lib_path(const char* sl_name) {
  174. char path[PATH_MAX];
  175. auto handle = dlopen(sl_name,
  176. RTLD_GLOBAL | RTLD_LAZY | RTLD_NOLOAD);
  177. mgb_assert(handle != nullptr, "%s", dlerror());
  178. mgb_assert(dlinfo(handle, RTLD_DI_ORIGIN, &path) != -1,
  179. "%s", dlerror());
  180. return path;
  181. }
  182. #endif
  183. }
  184. std::vector<std::string> _config::get_cuda_include_path() {
  185. #if MGB_CUDA
  186. auto cuda_path = getenv("CUDA_BIN_PATH");
  187. if (cuda_path) {
  188. return std::vector<std::string>{cuda_path,
  189. std::string(cuda_path) + "/include"};
  190. } else {
  191. auto cuda_lib_path = get_loaded_shared_lib_path("libcudart.so");
  192. return {cuda_lib_path, cuda_lib_path + "/../",
  193. cuda_lib_path + "/../include"};
  194. }
  195. #else
  196. mgb_throw(MegBrainError, "cuda disabled at compile time");
  197. #endif
  198. }
  199. std::vector<std::string> _config::get_cuda_lib_path() {
  200. #if MGB_CUDA
  201. auto cuda_path = getenv("CUDA_BIN_PATH");
  202. if (cuda_path) {
  203. return std::vector<std::string>{cuda_path,
  204. std::string(cuda_path) + "/lib64"};
  205. } else {
  206. auto cuda_lib_path = get_loaded_shared_lib_path("libcudart.so");
  207. return {cuda_lib_path};
  208. }
  209. #else
  210. mgb_throw(MegBrainError, "cuda disabled at compile time");
  211. #endif
  212. }
  213. int _config::get_cuda_version() {
  214. #if MGB_CUDA
  215. int version;
  216. MGB_CUDA_CHECK(cudaRuntimeGetVersion(&version));
  217. return version;
  218. #else
  219. mgb_throw(MegBrainError, "cuda disabled at compile time");
  220. #endif
  221. }
  222. bool _config::is_compiled_with_cuda() {
  223. #if MGB_CUDA
  224. return true;
  225. #else
  226. return false;
  227. #endif
  228. }
  229. void _config::load_opr_library(const char* self_path, const char* lib_path) {
  230. static bool self_global = false;
  231. static std::mutex self_global_mtx;
  232. {
  233. MGB_LOCK_GUARD(self_global_mtx);
  234. if (!self_global) {
  235. auto hdl = dlopen(self_path, RTLD_LAZY | RTLD_GLOBAL);
  236. mgb_assert(hdl, "failed to set mgb to global: %s", dlerror());
  237. self_global = true;
  238. }
  239. }
  240. if (lib_path) {
  241. auto hdl = dlopen(lib_path, RTLD_LAZY);
  242. mgb_assert(hdl, "failed to load libray %s: %s", lib_path, dlerror());
  243. }
  244. }
  245. std::vector<std::pair<unsigned long int, std::string>>
  246. _config::dump_registered_oprs() {
  247. #if MGB_ENABLE_DEBUG_UTIL
  248. return serialization::OprRegistry::dump_registries();
  249. #else
  250. return {};
  251. #endif
  252. }
  253. #if MGB_ENABLE_OPR_MM
  254. /*! see definition : src/cpp/megbrain_config.h.
  255. * Create mm server. port 0 is permitted, leave zmqrpc to decide which port
  256. * should be used.
  257. */
  258. int _config::create_mm_server(const std::string& server_addr, int port) {
  259. return create_zmqrpc_server(server_addr, port);
  260. }
  261. void _config::group_barrier(const std::string& server_addr,
  262. int port, uint32_t size, uint32_t rank) {
  263. mgb_assert(rank < size, "invalid rank %d", rank);
  264. auto group_mgr = std::make_shared<GroupClientProxy>(
  265. ssprintf("%s:%d", server_addr.c_str(), port));
  266. uint32_t rsp = group_mgr->group_barrier(size, rank);
  267. mgb_assert(rsp != 0, "rank already registered: %d", rank);
  268. mgb_assert(size == rsp, "inconsistent size: %d, expect %d", size, rsp);
  269. }
  270. #else
  271. int _config::create_mm_server(const std::string& server_addr, int port) {
  272. mgb_throw(mgb::MegBrainError, "OPR_MM suppport disable at compile time");
  273. return 0;
  274. }
  275. void _config::group_barrier(const std::string& server_addr,
  276. int port, uint32_t size, uint32_t rank) {
  277. mgb_throw(mgb::MegBrainError, "OPR_MM suppport disable at compile time");
  278. }
  279. #endif
  280. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

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