Skip to content

Commit d9600cd

Browse files
committed
Fix and simplify SIMD tests
The tests for SSE and AVX must only be done if the correct compiler flags were used. Signed-off-by: Stefan Weil <[email protected]>
1 parent d306552 commit d9600cd

File tree

4 files changed

+43
-68
lines changed

4 files changed

+43
-68
lines changed

src/arch/Makefile.am

+4
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ noinst_LTLIBRARIES += libtesseract_avx.la libtesseract_avx2.la
1919
noinst_LTLIBRARIES += libtesseract_sse.la
2020
noinst_LTLIBRARIES += libtesseract_arch.la
2121

22+
libtesseract_arch_la_CPPFLAGS = $(AM_CPPFLAGS)
2223
if AVX_OPT
24+
libtesseract_arch_la_CPPFLAGS += -DAVX
2325
libtesseract_avx_la_CXXFLAGS = -ffast-math -mavx
2426
endif
2527
if AVX2_OPT
28+
libtesseract_arch_la_CPPFLAGS += -DAVX2
2629
libtesseract_avx2_la_CXXFLAGS = -ffast-math -mavx2
2730
endif
2831
if SSE41_OPT
32+
libtesseract_arch_la_CPPFLAGS += -DSSE4_1
2933
libtesseract_sse_la_CXXFLAGS = -ffast-math -msse4.1
3034
endif
3135

src/arch/dotproductavx.cpp

+2-16
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,7 @@
1616
// limitations under the License.
1717
///////////////////////////////////////////////////////////////////////
1818

19-
#if !defined(__AVX__)
20-
// Implementation for non-avx archs.
21-
22-
#include "dotproductavx.h"
23-
#include <cstdio>
24-
#include <cstdlib>
25-
26-
namespace tesseract {
27-
double DotProductAVX(const double* u, const double* v, int n) {
28-
fprintf(stderr, "DotProductAVX can't be used on Android\n");
29-
abort();
30-
}
31-
} // namespace tesseract
32-
33-
#else // !defined(__AVX__)
19+
#if defined(__AVX__)
3420
// Implementation for avx capable archs.
3521
#include <immintrin.h>
3622
#include <cstdint>
@@ -111,4 +97,4 @@ double DotProductAVX(const double* u, const double* v, int n) {
11197

11298
} // namespace tesseract.
11399

114-
#endif // ANDROID_BUILD
100+
#endif // __AVX__

src/arch/dotproductsse.cpp

+2-21
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,7 @@
1616
// limitations under the License.
1717
///////////////////////////////////////////////////////////////////////
1818

19-
#if !defined(__SSE4_1__)
20-
// This code can't compile with "-msse4.1", so use dummy stubs.
21-
22-
#include "dotproductsse.h"
23-
#include <cstdio>
24-
#include <cstdlib>
25-
26-
namespace tesseract {
27-
double DotProductSSE(const double* u, const double* v, int n) {
28-
fprintf(stderr, "DotProductSSE can't be used on Android\n");
29-
abort();
30-
}
31-
int32_t IntDotProductSSE(const int8_t* u, const int8_t* v, int n) {
32-
fprintf(stderr, "IntDotProductSSE can't be used on Android\n");
33-
abort();
34-
}
35-
} // namespace tesseract
36-
37-
#else // !defined(__SSE4_1__)
38-
// Non-Android code here
19+
#if defined(__SSE4_1__)
3920

4021
#include <emmintrin.h>
4122
#include <smmintrin.h>
@@ -137,4 +118,4 @@ int32_t IntDotProductSSE(const int8_t* u, const int8_t* v, int n) {
137118

138119
} // namespace tesseract.
139120

140-
#endif // ANDROID_BUILD
121+
#endif // __SSE4_1__

src/arch/simddetect.cpp

+35-31
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,10 @@
2222
#include "params.h" // for STRING_VAR
2323
#include "tprintf.h" // for tprintf
2424

25-
#undef X86_BUILD
26-
#if defined(__x86_64__) || defined(__i386__) || defined(_WIN32)
27-
# if !defined(ANDROID_BUILD)
28-
# define X86_BUILD 1
29-
# endif // !ANDROID_BUILD
30-
#endif // x86 target
31-
32-
#if defined(X86_BUILD)
33-
# if defined(__GNUC__)
34-
# include <cpuid.h>
35-
# elif defined(_WIN32)
36-
# include <intrin.h>
37-
# endif
25+
#if defined(__GNUC__)
26+
# include <cpuid.h>
27+
#elif defined(_WIN32)
28+
# include <intrin.h>
3829
#endif
3930

4031
namespace tesseract {
@@ -84,13 +75,15 @@ SIMDDetect::SIMDDetect() {
8475
// The fallback is a generic dot product calculation.
8576
SetDotProduct(DotProductGeneric);
8677

87-
#if defined(X86_BUILD)
88-
# if defined(__GNUC__)
78+
#if defined(__GNUC__)
8979
unsigned int eax, ebx, ecx, edx;
9080
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) != 0) {
9181
// Note that these tests all use hex because the older compilers don't have
9282
// the newer flags.
83+
#if defined(SSE4_1)
9384
sse_available_ = (ecx & 0x00080000) != 0;
85+
#endif
86+
#if defined(AVX)
9487
avx_available_ = (ecx & 0x10000000) != 0;
9588
if (avx_available_) {
9689
// There is supposed to be a __get_cpuid_count function, but this is all
@@ -101,30 +94,38 @@ SIMDDetect::SIMDDetect() {
10194
avx512F_available_ = (ebx & 0x00010000) != 0;
10295
avx512BW_available_ = (ebx & 0x40000000) != 0;
10396
}
97+
#endif
10498
}
10599
# elif defined(_WIN32)
106100
int cpuInfo[4];
107101
__cpuid(cpuInfo, 0);
108102
if (cpuInfo[0] >= 1) {
109103
__cpuid(cpuInfo, 1);
104+
#if defined(SSE4_1)
110105
sse_available_ = (cpuInfo[2] & 0x00080000) != 0;
106+
#endif
107+
#if defined(AVX)
111108
avx_available_ = (cpuInfo[2] & 0x10000000) != 0;
109+
#endif
112110
}
113-
# else
114-
# error "I don't know how to test for SIMD with this compiler"
115-
# endif
116-
#endif // X86_BUILD
111+
#else
112+
#error "I don't know how to test for SIMD with this compiler"
113+
#endif
117114

118-
#if defined(X86_BUILD)
119115
// Select code for calculation of dot product based on autodetection.
120-
if (avx_available_) {
116+
if (false) {
117+
// This is a dummy to support conditional compilation.
118+
#if defined(AVX)
119+
} else if (avx_available_) {
121120
// AVX detected.
122121
SetDotProduct(DotProductAVX);
122+
#endif
123+
#if defined(SSE4_1)
123124
} else if (sse_available_) {
124125
// SSE detected.
125126
SetDotProduct(DotProductSSE);
127+
#endif
126128
}
127-
#endif // X86_BUILD
128129
}
129130

130131
void SIMDDetect::Update() {
@@ -141,26 +142,29 @@ void SIMDDetect::Update() {
141142
// Native optimized code selected by config variable.
142143
SetDotProduct(DotProductNative);
143144
dotproduct_method = "native";
144-
}
145-
#if defined(X86_BUILD)
146-
else if (!strcmp(dotproduct.string(), "avx")) {
145+
#if defined(AVX)
146+
} else if (!strcmp(dotproduct.string(), "avx")) {
147147
// AVX selected by config variable.
148148
SetDotProduct(DotProductAVX);
149149
dotproduct_method = "avx";
150+
#endif
151+
#if defined(SSE4_1)
150152
} else if (!strcmp(dotproduct.string(), "sse")) {
151153
// SSE selected by config variable.
152154
SetDotProduct(DotProductSSE);
153155
dotproduct_method = "sse";
154-
}
155-
#endif // X86_BUILD
156-
else {
156+
#endif
157+
} else {
157158
// Unsupported value of config variable.
158159
tprintf("Warning, ignoring unsupported config variable value: dotproduct=%s\n",
159160
dotproduct.string());
160161
tprintf("Support values for dotproduct: auto generic native"
161-
#if defined(X86_BUILD)
162-
" avx sse"
163-
#endif // X86_BUILD
162+
#if defined(AVX)
163+
" avx"
164+
#endif
165+
#if defined(SSE4_1)
166+
" sse"
167+
#endif
164168
".\n");
165169
}
166170

0 commit comments

Comments
 (0)