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.

common.h 7.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /**
  2. * \file src/core/include/megbrain/common.h
  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. #pragma once
  12. #include "megbrain_build_config.h"
  13. #include <memory>
  14. #include <string>
  15. #include <mutex>
  16. #include <exception>
  17. #include <cstdint>
  18. #include <cstddef>
  19. #include <cstdarg>
  20. #include <cstdlib>
  21. namespace mgb {
  22. /* ================ compiler related ================ */
  23. //! comma to be used in macros for template arguments
  24. #define MGB_COMMA ,
  25. //! branch prediction hint: likely to take
  26. #define mgb_likely(v) __builtin_expect(static_cast<bool>(v), 1)
  27. //! branch prediction hint: unlikely to take
  28. #define mgb_unlikely(v) __builtin_expect(static_cast<bool>(v), 0)
  29. //! mark a var to be used
  30. #define MGB_MARK_USED_VAR(var) static_cast<void>(var)
  31. //! remove padding in a struct
  32. #define MGB_PACKED __attribute__((packed))
  33. //! ask the compiler to not inline a function
  34. #define MGB_NOINLINE __attribute__((noinline))
  35. //! warn if result of a function is not used
  36. #define MGB_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
  37. #if __cplusplus >= 201703L || __clang_major__ >= 4
  38. #define MGB_FALLTHRU [[fallthrough]];
  39. #elif __GNUC__ >= 7
  40. #define MGB_FALLTHRU __attribute__((fallthrough));
  41. #else
  42. #define MGB_FALLTHRU
  43. #endif
  44. /* ================ exception and assertion ================ */
  45. #ifndef mgb_trap
  46. #define mgb_trap() __builtin_trap()
  47. #endif
  48. #if MGB_ENABLE_EXCEPTION
  49. //! throw raw exception object
  50. #define mgb_throw_raw(_exc...) throw _exc
  51. //! try block
  52. #define MGB_TRY try
  53. //! catch block
  54. #define MGB_CATCH(_decl, _stmt) \
  55. catch(_decl) _stmt
  56. #else
  57. #if MGB_ENABLE_LOGGING
  58. #define mgb_throw_raw(_exc...) ::mgb::__on_exception_throw__(_exc)
  59. void __on_exception_throw__(const std::exception &exc)
  60. __attribute__((noreturn));
  61. #else
  62. #define mgb_throw_raw(_exc...) mgb_trap()
  63. #endif
  64. #define MGB_TRY
  65. #define MGB_CATCH(_decl, _stmt)
  66. #endif // MGB_ENABLE_EXCEPTION
  67. //! used after try-catch block, like try-finally construct in python
  68. #define MGB_FINALLY(_stmt) \
  69. MGB_CATCH(..., {_stmt; throw; }) \
  70. _stmt
  71. #if MGB_ENABLE_LOGGING
  72. //! throw exception with given message
  73. #define mgb_throw(_exc, _msg...) mgb_throw_raw(_exc(::mgb::ssprintf(_msg)))
  74. #else
  75. //! throw exception with given message
  76. #define mgb_throw(_exc, _msg...) mgb_throw_raw(_exc(""))
  77. #endif
  78. //! throw exception with given message if condition is true
  79. #define mgb_throw_if(_cond, _exc, _msg...) \
  80. do { \
  81. if (mgb_unlikely((_cond))) \
  82. mgb_throw(_exc, _msg); \
  83. } while(0)
  84. // assert
  85. #if MGB_ASSERT_LOC
  86. /*!
  87. * \brief extended assert
  88. * extra diagnostics message (in printf format) could be printed when assertion
  89. * fails; the asserted expression is guaranteed to be evaluated
  90. */
  91. #define mgb_assert(expr, msg...) \
  92. do { \
  93. if (mgb_unlikely(!(expr))) \
  94. ::mgb::__assert_fail__(__FILE__, __LINE__, \
  95. __PRETTY_FUNCTION__, # expr, ##msg); \
  96. } while(0)
  97. void __assert_fail__(
  98. const char *file, int line, const char *func,
  99. const char *expr, const char *msg_fmt = 0, ...)
  100. __attribute__((format(printf, 5, 6), noreturn));
  101. #else
  102. #define mgb_assert(expr, msg...) \
  103. do { \
  104. if (mgb_unlikely(!(expr))) \
  105. ::mgb::__assert_fail__(); \
  106. } while(0)
  107. void __assert_fail__() __attribute__((noreturn));
  108. #endif // MGB_ASSERT_LOC
  109. /* ================ logging ================ */
  110. //! caused by need remve sensitive words at opt release
  111. #if MGB_ENABLE_LOGGING
  112. #define mgb_log_debug(fmt...) \
  113. _mgb_do_log(::mgb::LogLevel::DEBUG, __FILE__, __func__, __LINE__, fmt)
  114. #define mgb_log(fmt...) \
  115. _mgb_do_log(::mgb::LogLevel::INFO, __FILE__, __func__, __LINE__, fmt)
  116. #define mgb_log_warn(fmt...) \
  117. _mgb_do_log(::mgb::LogLevel::WARN, __FILE__, __func__, __LINE__, fmt)
  118. #define mgb_log_error(fmt...) \
  119. _mgb_do_log(::mgb::LogLevel::ERROR, __FILE__, __func__, __LINE__, fmt)
  120. #else
  121. #define mgb_log_debug(fmt...) \
  122. _mgb_do_log(::mgb::LogLevel::DEBUG, "", "", 1, fmt)
  123. #define mgb_log(fmt...) \
  124. _mgb_do_log(::mgb::LogLevel::INFO, "", "", 1, fmt)
  125. #define mgb_log_warn(fmt...) \
  126. _mgb_do_log(::mgb::LogLevel::WARN, "", "", 1, fmt)
  127. #define mgb_log_error(fmt...) \
  128. _mgb_do_log(::mgb::LogLevel::ERROR, "", "", 1, fmt)
  129. #endif
  130. enum class LogLevel { DEBUG, INFO, WARN, ERROR };
  131. typedef void(*LogHandler)(LogLevel level,
  132. const char *file, const char *func, int line, const char *fmt,
  133. va_list ap);
  134. /*!
  135. * \brief set logging level
  136. * messages lower than given level would not be sent to log handler
  137. *
  138. * \return previous log level
  139. */
  140. LogLevel set_log_level(LogLevel level);
  141. /*!
  142. * \brief set callback for receiving log requests
  143. * \return previous log handler
  144. */
  145. LogHandler set_log_handler(LogHandler handler);
  146. #if MGB_ENABLE_LOGGING
  147. void __log__(LogLevel level, const char *file, const char *func, int line,
  148. const char *fmt, ...)
  149. __attribute__((format(printf, 5, 6)));
  150. #define _mgb_do_log ::mgb::__log__
  151. //! make a string used for log
  152. #define mgb_ssprintf_log ::mgb::ssprintf
  153. //! v if log is enabled, and "" if not
  154. #define mgb_cstr_log(v) v
  155. #else
  156. #define _mgb_do_log(...) do{} while(0)
  157. #define mgb_ssprintf_log(...) ::std::string{}
  158. #define mgb_cstr_log(v) ""
  159. #endif // MGB_ENABLE_LOGGING
  160. /* ================ misc ================ */
  161. #if MGB_ENABLE_GETENV
  162. #define MGB_GETENV ::std::getenv
  163. #else
  164. #define MGB_GETENV(_name) static_cast<char*>(nullptr)
  165. #endif
  166. // use some macro tricks to get lock guard with unique variable name
  167. #define MGB_TOKENPASTE(x, y) x ## y
  168. #define MGB_TOKENPASTE2(x, y) MGB_TOKENPASTE(x, y)
  169. #define MGB_LOCK_GUARD_CTOR(mtx) MGB_TOKENPASTE2(__lock_guard_, __LINE__)(mtx)
  170. #define MGB_LOCK_GUARD(mtx) \
  171. std::lock_guard<decltype(mtx)> MGB_LOCK_GUARD_CTOR(mtx)
  172. #define MGB_LOCK_GUARD_UNIQUE(mtx) \
  173. std::unique_lock<decltype(mtx)> MGB_LOCK_GUARD_CTOR(mtx)
  174. #define MGB_LOCK_GUARD_SHARED(mtx) \
  175. std::shared_lock<decltype(mtx)> MGB_LOCK_GUARD_CTOR(mtx)
  176. /*!
  177. * \brief printf-like std::string constructor
  178. */
  179. std::string ssprintf(const char *fmt, ...)
  180. __attribute__((format(printf, 1, 2)));
  181. std::string svsprintf(const char *fmt, va_list ap);
  182. #if 0
  183. // used for win32 with vs prior to 2015
  184. const char* convert_fmt_str(const char *fmt);
  185. static inline const char* operator "" _fmt(const char *fmt, std::size_t) {
  186. return convert_fmt_str(fmt);
  187. }
  188. #else
  189. static inline constexpr const char* convert_fmt_str(const char *fmt) {
  190. return fmt;
  191. }
  192. static inline constexpr const char* operator "" _fmt(
  193. const char *fmt, std::size_t) {
  194. return convert_fmt_str(fmt);
  195. }
  196. inline constexpr std::size_t operator"" _z(unsigned long long n) {
  197. return n;
  198. }
  199. #endif
  200. } // namespace mgb
  201. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

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