CpuId.h 2.5 KB
Newer Older
L
liaogang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#pragma once

L
liaogang 已提交
14
#include "Common.h"
L
liaogang 已提交
15 16 17

namespace paddle {

18
// clang-format off
19
enum simd_t {
20
  SIMD_NONE   = 0,          ///< None
L
Liu Yiqun 已提交
21
#if !defined(__ANDROID__)
22 23 24 25 26 27 28 29 30 31 32
  SIMD_SSE    = 1 << 0,     ///< SSE
  SIMD_SSE2   = 1 << 1,     ///< SSE 2
  SIMD_SSE3   = 1 << 2,     ///< SSE 3
  SIMD_SSSE3  = 1 << 3,     ///< SSSE 3
  SIMD_SSE41  = 1 << 4,     ///< SSE 4.1
  SIMD_SSE42  = 1 << 5,     ///< SSE 4.2
  SIMD_FMA3   = 1 << 6,     ///< FMA 3
  SIMD_FMA4   = 1 << 7,     ///< FMA 4
  SIMD_AVX    = 1 << 8,     ///< AVX
  SIMD_AVX2   = 1 << 9,     ///< AVX 2
  SIMD_AVX512 = 1 << 10,    ///< AVX 512
L
Liu Yiqun 已提交
33 34 35
#else
  SIMD_NEON   = 1 << 0,     ///< NEON
#endif
36
};
37
// clang-format on
38

L
liaogang 已提交
39 40
class SIMDFlags final {
public:
Y
Yu Yang 已提交
41
  DISABLE_COPY(SIMDFlags);
L
liaogang 已提交
42

Y
Yu Yang 已提交
43
  SIMDFlags();
L
liaogang 已提交
44

45
  static SIMDFlags const* instance();
L
liaogang 已提交
46

47 48 49
  inline bool check(int flags) const {
    return !((simd_flags_ & flags) ^ flags);
  }
L
liaogang 已提交
50 51

private:
Y
Yu Yang 已提交
52
  int simd_flags_ = SIMD_NONE;
L
liaogang 已提交
53 54
};

55 56 57 58 59 60 61
/**
 * @brief   Check SIMD flags at runtime.
 *
 * For example.
 * @code{.cpp}
 *
 * if (HAS_SIMD(SIMD_AVX2 | SIMD_FMA4)) {
62
 *      avx2_fm4_stub();
63
 * } else if (HAS_SIMD(SIMD_AVX)) {
64
 *      avx_stub();
65 66 67 68
 * }
 *
 * @endcode
 */
69
#define HAS_SIMD(__flags) SIMDFlags::instance()->check(__flags)
70 71 72 73

/**
 * @brief   Check SIMD flags at runtime.
 *
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
 * 1. Check all SIMD flags at runtime:
 *
 * @code{.cpp}
 * if (HAS_AVX && HAS_AVX2) {
 *      avx2_stub();
 * }
 * @endcod
 *
 * 2. Check one SIMD flag at runtime:
 *
 * @code{.cpp}
 * if (HAS_SSE41 || HAS_SSE42) {
 *      sse4_stub();
 * }
 * @endcode
89
 */
90 91 92 93 94 95 96 97 98 99 100 101 102
// clang-format off
#define HAS_SSE     HAS_SIMD(SIMD_SSE)
#define HAS_SSE2    HAS_SIMD(SIMD_SSE2)
#define HAS_SSE3    HAS_SIMD(SIMD_SSE3)
#define HAS_SSSE3   HAS_SIMD(SIMD_SSSE3)
#define HAS_SSE41   HAS_SIMD(SIMD_SSE41)
#define HAS_SSE42   HAS_SIMD(SIMD_SSE42)
#define HAS_FMA3    HAS_SIMD(SIMD_FMA3)
#define HAS_FMA4    HAS_SIMD(SIMD_FMA4)
#define HAS_AVX     HAS_SIMD(SIMD_AVX)
#define HAS_AVX2    HAS_SIMD(SIMD_AVX2)
#define HAS_AVX512  HAS_SIMD(SIMD_AVX512)
// clang-format on
L
liaogang 已提交
103

Y
Yu Yang 已提交
104
}  // namespace paddle