1 #include <ATen/Version.h> 2 #include <ATen/Config.h> 3 4 #if AT_MKL_ENABLED() 5 #include <mkl.h> 6 #endif 7 8 #if AT_MKLDNN_ENABLED() 9 #include <dnnl.hpp> 10 #include <ideep.hpp> 11 #endif 12 13 #include <caffe2/core/common.h> 14 15 #include <ATen/native/DispatchStub.h> 16 17 #include <sstream> 18 19 namespace at { 20 get_mkl_version()21std::string get_mkl_version() { 22 std::string version; 23 #if AT_MKL_ENABLED() 24 { 25 // Magic buffer number is from MKL documentation 26 // https://software.intel.com/en-us/mkl-developer-reference-c-mkl-get-version-string 27 char buf[198]; 28 mkl_get_version_string(buf, 198); 29 version = buf; 30 } 31 #else 32 version = "MKL not found"; 33 #endif 34 return version; 35 } 36 get_mkldnn_version()37std::string get_mkldnn_version() { 38 std::ostringstream ss; 39 #if AT_MKLDNN_ENABLED() 40 // Cribbed from mkl-dnn/src/common/verbose.cpp 41 // Too bad: can't get ISA info conveniently :( 42 // Apparently no way to get ideep version? 43 // https://github.com/intel/ideep/issues/29 44 { 45 const dnnl_version_t* ver = dnnl_version(); 46 ss << "Intel(R) MKL-DNN v" << ver->major << "." << ver->minor << "." << ver->patch 47 << " (Git Hash " << ver->hash << ")"; 48 } 49 #else 50 ss << "MKLDNN not found"; 51 #endif 52 return ss.str(); 53 } 54 get_openmp_version()55std::string get_openmp_version() { 56 std::ostringstream ss; 57 #ifdef _OPENMP 58 { 59 ss << "OpenMP " << _OPENMP; 60 // Reference: 61 // https://stackoverflow.com/questions/1304363/how-to-check-the-version-of-openmp-on-linux 62 const char* ver_str = nullptr; 63 switch (_OPENMP) { 64 case 200505: 65 ver_str = "2.5"; 66 break; 67 case 200805: 68 ver_str = "3.0"; 69 break; 70 case 201107: 71 ver_str = "3.1"; 72 break; 73 case 201307: 74 ver_str = "4.0"; 75 break; 76 case 201511: 77 ver_str = "4.5"; 78 break; 79 default: 80 ver_str = nullptr; 81 break; 82 } 83 if (ver_str) { 84 ss << " (a.k.a. OpenMP " << ver_str << ")"; 85 } 86 } 87 #else 88 ss << "OpenMP not found"; 89 #endif 90 return ss.str(); 91 } 92 get_cpu_capability()93std::string get_cpu_capability() { 94 // It is possible that we override the cpu_capability with 95 // environment variable 96 auto capability = native::get_cpu_capability(); 97 switch (capability) { 98 #if defined(HAVE_VSX_CPU_DEFINITION) 99 case native::CPUCapability::DEFAULT: 100 return "DEFAULT"; 101 case native::CPUCapability::VSX: 102 return "VSX"; 103 #elif defined(HAVE_ZVECTOR_CPU_DEFINITION) 104 case native::CPUCapability::DEFAULT: 105 return "DEFAULT"; 106 case native::CPUCapability::ZVECTOR: 107 return "Z VECTOR"; 108 #else 109 case native::CPUCapability::DEFAULT: 110 return "NO AVX"; 111 case native::CPUCapability::AVX2: 112 return "AVX2"; 113 case native::CPUCapability::AVX512: 114 return "AVX512"; 115 #endif 116 default: 117 break; 118 } 119 return ""; 120 } 121 used_cpu_capability()122static std::string used_cpu_capability() { 123 // It is possible that we override the cpu_capability with 124 // environment variable 125 std::ostringstream ss; 126 ss << "CPU capability usage: " << get_cpu_capability(); 127 return ss.str(); 128 } 129 show_config()130std::string show_config() { 131 std::ostringstream ss; 132 ss << "PyTorch built with:\n"; 133 134 // Reference: 135 // https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html 136 137 #if defined(__GNUC__) 138 { 139 ss << " - GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "\n"; 140 } 141 #endif 142 143 #if defined(__cplusplus) 144 { 145 ss << " - C++ Version: " << __cplusplus << "\n"; 146 } 147 #endif 148 149 #if defined(__clang_major__) 150 { 151 ss << " - clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n"; 152 } 153 #endif 154 155 #if defined(_MSC_VER) 156 { 157 ss << " - MSVC " << _MSC_FULL_VER << "\n"; 158 } 159 #endif 160 161 #if AT_MKL_ENABLED() 162 ss << " - " << get_mkl_version() << "\n"; 163 #endif 164 165 #if AT_MKLDNN_ENABLED() 166 ss << " - " << get_mkldnn_version() << "\n"; 167 #endif 168 169 #ifdef _OPENMP 170 ss << " - " << get_openmp_version() << "\n"; 171 #endif 172 173 #if AT_BUILD_WITH_LAPACK() 174 // TODO: Actually record which one we actually picked 175 ss << " - LAPACK is enabled (usually provided by MKL)\n"; 176 #endif 177 178 #if AT_NNPACK_ENABLED() 179 // TODO: No version; c.f. https://github.com/Maratyszcza/NNPACK/issues/165 180 ss << " - NNPACK is enabled\n"; 181 #endif 182 183 #ifdef CROSS_COMPILING_MACOSX 184 ss << " - Cross compiling on MacOSX\n"; 185 #endif 186 187 ss << " - "<< used_cpu_capability() << "\n"; 188 189 if (hasCUDA()) { 190 ss << detail::getCUDAHooks().showConfig(); 191 } 192 193 if (hasMAIA()) { 194 ss << detail::getMAIAHooks().showConfig(); 195 } 196 197 if (hasXPU()) { 198 ss << detail::getXPUHooks().showConfig(); 199 } 200 201 ss << " - Build settings: "; 202 for (const auto& pair : caffe2::GetBuildOptions()) { 203 if (!pair.second.empty()) { 204 ss << pair.first << "=" << pair.second << ", "; 205 } 206 } 207 ss << "\n"; 208 209 // TODO: do HIP 210 // TODO: do XLA 211 // TODO: do MPS 212 213 return ss.str(); 214 } 215 get_cxx_flags()216std::string get_cxx_flags() { 217 #if defined(FBCODE_CAFFE2) 218 TORCH_CHECK( 219 false, 220 "Buck does not populate the `CXX_FLAGS` field of Caffe2 build options. " 221 "As a result, `get_cxx_flags` is OSS only." 222 ); 223 #endif 224 return caffe2::GetBuildOptions().at("CXX_FLAGS"); 225 } 226 227 } 228