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.

helper.h 5.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #pragma once
  2. //! helper function like define: lite/src/misc.h, but we need example code just
  3. //! depends on install header, not depends any lite src file
  4. #include <chrono>
  5. #include <cstdio>
  6. #include <stdexcept>
  7. #include <string>
  8. std::string exampe_ssprintf(const char* fmt = 0, ...)
  9. __attribute__((format(printf, 1, 2)));
  10. #define LITE_EXAMPLE_THROW(msg) \
  11. do { \
  12. std::string msg_str(msg); \
  13. printf("%s\n", msg_str.c_str()); \
  14. __builtin_trap(); \
  15. } while (0)
  16. //! branch prediction hint: likely to take
  17. #define lite_example_likely(v) __builtin_expect(static_cast<bool>(v), 1)
  18. //! branch prediction hint: unlikely to take
  19. #define lite_example_unlikely(v) __builtin_expect(static_cast<bool>(v), 0)
  20. #define LITE_EXAMPLE_ASSERT(expr, msg...) \
  21. do { \
  22. if (lite_example_unlikely(!(expr))) { \
  23. auto info = exampe_ssprintf(msg); \
  24. LITE_EXAMPLE_THROW(exampe_ssprintf( \
  25. "Assert \' %s \' failed at file : %s \n" \
  26. "line %d : %s,\nextra " \
  27. "message: %s", \
  28. #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, info.c_str())); \
  29. } \
  30. } while (0)
  31. #define LITE_EXAMPLE_MARK_USED_VAR(var) ((void)var)
  32. namespace lite_example_helper {
  33. class ScopedTimer {
  34. public:
  35. typedef std::chrono::system_clock Clock;
  36. typedef std::chrono::nanoseconds Nsec;
  37. ScopedTimer(std::string name) : m_name(name) { m_start = Clock::now(); }
  38. ~ScopedTimer() {
  39. m_stop = Clock::now();
  40. std::chrono::duration<double> elapsed = m_stop - m_start;
  41. Nsec u = std::chrono::duration_cast<Nsec>(elapsed);
  42. auto msg = exampe_ssprintf(
  43. "%s used time %fms.", m_name.c_str(),
  44. static_cast<double>(u.count()) / 1000000.f);
  45. printf("%s", msg.c_str());
  46. }
  47. private:
  48. std::chrono::time_point<std::chrono::system_clock> m_start, m_stop;
  49. const std::string m_name;
  50. };
  51. class Timer {
  52. public:
  53. typedef std::chrono::system_clock Clock;
  54. typedef std::chrono::nanoseconds Nsec;
  55. Timer(std::string name) : m_name(name) { m_start = Clock::now(); }
  56. double get_used_time() {
  57. m_stop = Clock::now();
  58. std::chrono::duration<double> elapsed = m_stop - m_start;
  59. Nsec u = std::chrono::duration_cast<Nsec>(elapsed);
  60. return static_cast<double>(u.count()) / 1000000.0;
  61. }
  62. void print_used_time(int iter) {
  63. m_stop = Clock::now();
  64. std::chrono::duration<double> elapsed = m_stop - m_start;
  65. Nsec u = std::chrono::duration_cast<Nsec>(elapsed);
  66. printf("%s used time %f ms\n", (m_name + std::to_string(iter)).c_str(),
  67. static_cast<double>(u.count()) / 1000000.0);
  68. }
  69. void reset_start() { m_start = Clock::now(); }
  70. private:
  71. std::chrono::time_point<std::chrono::system_clock> m_start, m_stop;
  72. const std::string m_name;
  73. };
  74. inline void mark_used_variable() {}
  75. template <typename T, typename... Arg>
  76. inline void mark_used_variable(T firstArg, Arg... args) {
  77. LITE_EXAMPLE_MARK_USED_VAR(firstArg);
  78. mark_used_variable(args...);
  79. }
  80. } // namespace lite_example_helper
  81. #if defined(_WIN32)
  82. #include <io.h>
  83. #include <windows.h>
  84. #undef CONST
  85. #define F_OK 0
  86. #define RTLD_LAZY 0
  87. // On the windows platform we use a lib_filename without a full path so
  88. // the win-api "LoadLibrary" would uses a standard search strategy to
  89. // find the lib module. As we cannot access to the lib_filename without a
  90. // full path, we should not use "access(a, b)" to verify it.
  91. #define access(a, b) false
  92. static inline void* dlopen(const char* file, int) {
  93. return static_cast<void*>(LoadLibrary(file));
  94. }
  95. static inline char* dlerror() {
  96. const char* errmsg = "dlerror not aviable in windows";
  97. return const_cast<char*>(errmsg);
  98. }
  99. static inline void* dlsym(void* handle, const char* name) {
  100. FARPROC symbol = GetProcAddress((HMODULE)handle, name);
  101. return reinterpret_cast<void*>(symbol);
  102. }
  103. #elif __linux__ || __unix__ || __APPLE__
  104. #include <dlfcn.h>
  105. #include <unistd.h>
  106. #endif
  107. #if __DEPLOY_ON_XP_SP2__
  108. //! refer to
  109. //! https://docs.microsoft.com/en-us/cpp/build/configuring-programs-for-windows-xp?view=msvc-160
  110. //! xp sp2 do not support vc runtime fully, casused by KERNEL32.dll do not
  111. //! implement some base apis for c++ std function, for example,
  112. //! std::mutex/std::thread/std::condition_variable as a workround, we will
  113. //! disable some MegEngine feature on xp sp2 env, for exampe, multi-thread etc!
  114. #define LITE_MUTEX size_t
  115. #define LITE_RECURSIVE_MUTEX size_t
  116. #define LITE_LOCK_GUARD(mtx) LITE_EXAMPLE_MARK_USED_VAR(mtx)
  117. #define LITE_LOCK_GUARD_UNIQUE(mtx) LITE_EXAMPLE_MARK_USED_VAR(mtx)
  118. #define LITE_LOCK_GUARD_SHARED(mtx) \
  119. LITE_EXAMPLE_MARK_USED_VAR(LITE_EXAMPLE_MARK_USED_VAR)
  120. #else
  121. #define LITE_MUTEX std::mutex
  122. #define LITE_RECURSIVE_MUTEX std::recursive_mutex
  123. #define LITE_LOCK_GUARD(mtx) std::lock_guard<decltype(mtx)> LITE_LOCK_GUARD_CTOR(mtx)
  124. #define LITE_LOCK_GUARD_UNIQUE(mtx) \
  125. std::unique_lock<decltype(mtx)> LITE_LOCK_GUARD_CTOR(mtx)
  126. #define LITE_LOCK_GUARD_SHARED(mtx) \
  127. std::shared_lock<decltype(mtx)> LITE_LOCK_GUARD_CTOR(mtx)
  128. #endif
  129. // vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}