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 | |
21 | std::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 | |
37 | std::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 | |
55 | std::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 | |
93 | std::string used_cpu_capability() { |
94 | // It is possible that we override the cpu_capability with |
95 | // environment variable |
96 | std::ostringstream ss; |
97 | ss << "CPU capability usage: "; |
98 | auto capability = native::get_cpu_capability(); |
99 | switch (capability) { |
100 | #if defined(HAVE_VSX_CPU_DEFINITION) |
101 | case native::CPUCapability::DEFAULT: |
102 | ss << "DEFAULT"; |
103 | break; |
104 | case native::CPUCapability::VSX: |
105 | ss << "VSX"; |
106 | break; |
107 | #elif defined(HAVE_ZVECTOR_CPU_DEFINITION) |
108 | case native::CPUCapability::DEFAULT: |
109 | ss << "DEFAULT"; |
110 | break; |
111 | case native::CPUCapability::ZVECTOR: |
112 | ss << "Z VECTOR"; |
113 | break; |
114 | #else |
115 | case native::CPUCapability::DEFAULT: |
116 | ss << "NO AVX"; |
117 | break; |
118 | case native::CPUCapability::AVX2: |
119 | ss << "AVX2"; |
120 | break; |
121 | case native::CPUCapability::AVX512: |
122 | ss << "AVX512"; |
123 | break; |
124 | #endif |
125 | default: |
126 | break; |
127 | } |
128 | return ss.str(); |
129 | } |
130 | |
131 | std::string show_config() { |
132 | std::ostringstream ss; |
133 | ss << "PyTorch built with:\n"; |
134 | |
135 | // Reference: |
136 | // https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html |
137 | |
138 | #if defined(__GNUC__) |
139 | { |
140 | ss << " - GCC "<< __GNUC__ << "."<< __GNUC_MINOR__ << "\n"; |
141 | } |
142 | #endif |
143 | |
144 | #if defined(__cplusplus) |
145 | { |
146 | ss << " - C++ Version: "<< __cplusplus << "\n"; |
147 | } |
148 | #endif |
149 | |
150 | #if defined(__clang_major__) |
151 | { |
152 | ss << " - clang "<< __clang_major__ << "."<< __clang_minor__ << "."<< __clang_patchlevel__ << "\n"; |
153 | } |
154 | #endif |
155 | |
156 | #if defined(_MSC_VER) |
157 | { |
158 | ss << " - MSVC "<< _MSC_FULL_VER << "\n"; |
159 | } |
160 | #endif |
161 | |
162 | #if AT_MKL_ENABLED() |
163 | ss << " - "<< get_mkl_version() << "\n"; |
164 | #endif |
165 | |
166 | #if AT_MKLDNN_ENABLED() |
167 | ss << " - "<< get_mkldnn_version() << "\n"; |
168 | #endif |
169 | |
170 | #ifdef _OPENMP |
171 | ss << " - "<< get_openmp_version() << "\n"; |
172 | #endif |
173 | |
174 | #if AT_BUILD_WITH_LAPACK() |
175 | // TODO: Actually record which one we actually picked |
176 | ss << " - LAPACK is enabled (usually provided by MKL)\n"; |
177 | #endif |
178 | |
179 | #if AT_NNPACK_ENABLED() |
180 | // TODO: No version; c.f. https://github.com/Maratyszcza/NNPACK/issues/165 |
181 | ss << " - NNPACK is enabled\n"; |
182 | #endif |
183 | |
184 | #ifdef CROSS_COMPILING_MACOSX |
185 | ss << " - Cross compiling on MacOSX\n"; |
186 | #endif |
187 | |
188 | ss << " - "<< used_cpu_capability() << "\n"; |
189 | |
190 | if (hasCUDA()) { |
191 | ss << detail::getCUDAHooks().showConfig(); |
192 | } |
193 | |
194 | if (hasORT()) { |
195 | ss << detail::getORTHooks().showConfig(); |
196 | } |
197 | |
198 | ss << " - Build settings: "; |
199 | for (const auto& pair : caffe2::GetBuildOptions()) { |
200 | if (!pair.second.empty()) { |
201 | ss << pair.first << "="<< pair.second << ", "; |
202 | } |
203 | } |
204 | ss << "\n"; |
205 | |
206 | // TODO: do HIP |
207 | // TODO: do XLA |
208 | // TODO: do MPS |
209 | |
210 | return ss.str(); |
211 | } |
212 | |
213 | std::string get_cxx_flags() { |
214 | #if defined(FBCODE_CAFFE2) |
215 | TORCH_CHECK( |
216 | false, |
217 | "Buck does not populate the `CXX_FLAGS` field of Caffe2 build options. " |
218 | "As a result, `get_cxx_flags` is OSS only." |
219 | ); |
220 | #endif |
221 | return caffe2::GetBuildOptions().at("CXX_FLAGS"); |
222 | } |
223 | |
224 | } |
225 |