1 ///////////////////////////////////////////////////////////////////////
2 // File:        simddetect.h
3 // Description: Architecture detector.
4 // Author:      Stefan Weil (based on code from Ray Smith)
5 //
6 // (C) Copyright 2014, Google Inc.
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 ///////////////////////////////////////////////////////////////////////
17 #ifndef TESSERACT_ARCH_SIMDDETECT_H_
18 #define TESSERACT_ARCH_SIMDDETECT_H_
19 
20 #include <tesseract/export.h>
21 #include "tesstypes.h"
22 
23 namespace tesseract {
24 
25 // Function pointer for best calculation of dot product.
26 using DotProductFunction = TFloat (*)(const TFloat *, const TFloat *, int);
27 extern DotProductFunction DotProduct;
28 
29 // Architecture detector. Add code here to detect any other architectures for
30 // SIMD-based faster dot product functions. Intended to be a single static
31 // object, but it does no real harm to have more than one.
32 class SIMDDetect {
33 public:
34   // Returns true if AVX is available on this system.
IsAVXAvailable()35   static inline bool IsAVXAvailable() {
36     return detector.avx_available_;
37   }
38   // Returns true if AVX2 (integer support) is available on this system.
IsAVX2Available()39   static inline bool IsAVX2Available() {
40     return detector.avx2_available_;
41   }
42   // Returns true if AVX512 Foundation (float) is available on this system.
IsAVX512FAvailable()43   static inline bool IsAVX512FAvailable() {
44     return detector.avx512F_available_;
45   }
46   // Returns true if AVX512 integer is available on this system.
IsAVX512BWAvailable()47   static inline bool IsAVX512BWAvailable() {
48     return detector.avx512BW_available_;
49   }
50   // Returns true if FMA is available on this system.
IsFMAAvailable()51   static inline bool IsFMAAvailable() {
52     return detector.fma_available_;
53   }
54   // Returns true if SSE4.1 is available on this system.
IsSSEAvailable()55   static inline bool IsSSEAvailable() {
56     return detector.sse_available_;
57   }
58   // Returns true if NEON is available on this system.
IsNEONAvailable()59   static inline bool IsNEONAvailable() {
60     return detector.neon_available_;
61   }
62 
63   // Update settings after config variable was set.
64   static TESS_API void Update();
65 
66 private:
67   // Constructor, must set all static member variables.
68   SIMDDetect();
69 
70 private:
71   // Singleton.
72   static SIMDDetect detector;
73   // If true, then AVX has been detected.
74   static TESS_API bool avx_available_;
75   static TESS_API bool avx2_available_;
76   static TESS_API bool avx512F_available_;
77   static TESS_API bool avx512BW_available_;
78   // If true, then FMA has been detected.
79   static TESS_API bool fma_available_;
80   // If true, then SSe4.1 has been detected.
81   static TESS_API bool sse_available_;
82   // If true, then NEON has been detected.
83   static TESS_API bool neon_available_;
84 };
85 
86 } // namespace tesseract
87 
88 #endif // TESSERACT_ARCH_SIMDDETECT_H_
89