@@ -15,56 +15,65 @@ limitations under the License. */
1515
1616namespace paddle {
1717
18+ enum simd_t {
19+ SIMD_NONE = 0 , // /< None
20+ SIMD_SSE = 1 << 0 , // /< SSE
21+ SIMD_SSE2 = 1 << 1 , // /< SSE 2
22+ SIMD_SSE3 = 1 << 2 , // /< SSE 3
23+ SIMD_SSSE3 = 1 << 3 , // /< SSSE 3
24+ SIMD_SSE41 = 1 << 4 , // /< SSE 4.1
25+ SIMD_SSE42 = 1 << 5 , // /< SSE 4.2
26+ SIMD_FMA3 = 1 << 6 , // /< FMA 3
27+ SIMD_FMA4 = 1 << 7 , // /< FMA 4
28+ SIMD_AVX = 1 << 8 , // /< AVX
29+ SIMD_AVX2 = 1 << 9 , // /< AVX 2
30+ SIMD_AVX512 = 1 << 10 , // /< AVX 512
31+ };
32+
1833class SIMDFlags final {
1934public:
2035 DISABLE_COPY (SIMDFlags);
21-
2236 SIMDFlags ();
2337
24- static const SIMDFlags* instance ();
25-
26- inline bool isSSE () const { return simd_flags_ & SIMD_SSE; }
27- inline bool isSSE2 () const { return simd_flags_ & SIMD_SSE2; }
28- inline bool isSSE3 () const { return simd_flags_ & SIMD_SSE3; }
29- inline bool isSSSE3 () const { return simd_flags_ & SIMD_SSSE3; }
30- inline bool isSSE41 () const { return simd_flags_ & SIMD_SSE41; }
31- inline bool isSSE42 () const { return simd_flags_ & SIMD_SSE42; }
32- inline bool isFMA3 () const { return simd_flags_ & SIMD_FMA3; }
33- inline bool isFMA4 () const { return simd_flags_ & SIMD_FMA4; }
34- inline bool isAVX () const { return simd_flags_ & SIMD_AVX; }
35- inline bool isAVX2 () const { return simd_flags_ & SIMD_AVX2; }
36- inline bool isAVX512 ()const { return simd_flags_ & SIMD_AVX512;}
38+ static SIMDFlags const * instance ();
39+ bool check (int flags) const ;
3740
3841private:
39- enum simd_t {
40- SIMD_NONE = 0 , // /< None
41- SIMD_SSE = 1 << 0 , // /< SSE
42- SIMD_SSE2 = 1 << 1 , // /< SSE 2
43- SIMD_SSE3 = 1 << 2 , // /< SSE 3
44- SIMD_SSSE3 = 1 << 3 , // /< SSSE 3
45- SIMD_SSE41 = 1 << 4 , // /< SSE 4.1
46- SIMD_SSE42 = 1 << 5 , // /< SSE 4.2
47- SIMD_FMA3 = 1 << 6 , // /< FMA 3
48- SIMD_FMA4 = 1 << 7 , // /< FMA 4
49- SIMD_AVX = 1 << 8 , // /< AVX
50- SIMD_AVX2 = 1 << 9 , // /< AVX 2
51- SIMD_AVX512 = 1 << 10 , // /< AVX 512
52- };
53-
54- // / simd flags
5542 int simd_flags_ = SIMD_NONE;
5643};
5744
58- #define HAS_SSE SIMDFlags::instance ()->isSSE()
59- #define HAS_SSE2 SIMDFlags::instance ()->isSSE2()
60- #define HAS_SSE3 SIMDFlags::instance ()->isSSE3()
61- #define HAS_SSSE3 SIMDFlags::instance ()->isSSSE3()
62- #define HAS_SSE41 SIMDFlags::instance ()->isSSE41()
63- #define HAS_SSE42 SIMDFlags::instance ()->isSSE42()
64- #define HAS_FMA3 SIMDFlags::instance ()->isFMA3()
65- #define HAS_FMA4 SIMDFlags::instance ()->isFMA4()
66- #define HAS_AVX SIMDFlags::instance ()->isAVX()
67- #define HAS_AVX2 SIMDFlags::instance ()->isAVX2()
68- #define HAS_AVX512 SIMDFlags::instance ()->isAVX512()
45+ /* *
46+ * @brief Check SIMD flags at runtime.
47+ *
48+ * For example.
49+ * @code{.cpp}
50+ *
51+ * if (HAS_SIMD(SIMD_AVX2 | SIMD_FMA4)) {
52+ * avx2_fm4_stub();
53+ * } else if (HAS_SIMD(SIMD_AVX)) {
54+ * avx_stub();
55+ * }
56+ *
57+ * @endcode
58+ */
59+ #define HAS_SIMD (__flags ) SIMDFlags::instance()->check (__flags)
60+
61+ /* *
62+ * @brief Check SIMD flags at runtime.
63+ *
64+ * 1. Check all SIMD flags at runtime: HAS_SSE && HAS_SSE2 && HAS_SSE3
65+ * 2. Check one SIMD flags at runtime: HAS_SSE || HAS_SSE2 || HAS_SSE3
66+ */
67+ #define HAS_SSE HAS_SIMD (SIMD_SSE)
68+ #define HAS_SSE2 HAS_SIMD (SIMD_SSE2)
69+ #define HAS_SSE3 HAS_SIMD (SIMD_SSE3)
70+ #define HAS_SSSE3 HAS_SIMD (SIMD_SSSE3)
71+ #define HAS_SSE41 HAS_SIMD (SIMD_SSE41)
72+ #define HAS_SSE42 HAS_SIMD (SIMD_SSE42)
73+ #define HAS_FMA3 HAS_SIMD (SIMD_FMA3)
74+ #define HAS_FMA4 HAS_SIMD (SIMD_FMA4)
75+ #define HAS_AVX HAS_SIMD (SIMD_AVX)
76+ #define HAS_AVX2 HAS_SIMD (SIMD_AVX2)
77+ #define HAS_AVX512 HAS_SIMD (SIMD_AVX512)
6978
7079} // namespace paddle
0 commit comments