Tesseract: "DotProductAVX can't be used on Android" while running on Windows

Created on 31 Dec 2016  Â·  42Comments  Â·  Source: tesseract-ocr/tesseract

I built my project with cppan and then tried to run, and got an error:

Info in pixWriteMemPng: work-around: writing to a temp file
Info in fopenReadFromMemory: work-around: writing to a temp file
DotProductAVX can't be used on Android

After compiling example project - https://github.com/cppan/tesseract_example/tree/master/with_cppan I got same error. Can you please fix it?
OS: Windows 7

SIMD

Most helpful comment

This looks like an error for 32 bit x86 platforms. You can work around it by removing the line # define X86_BUILD 1 from arch/simddetect.cpp.

All 42 comments

This looks like an error for 32 bit x86 platforms. You can work around it by removing the line # define X86_BUILD 1 from arch/simddetect.cpp.

Thanks, it works!

Also, one question: will this built tesseract without this line works also on 64-bit Windows OS?

@Izaron, yes, but it will be much slower.

@amitdo, there are several options:

  • Let the compiler do the optimization (and forget that explicit SSE/AVX code). This is my preferred solution as it also works for ARM and other architectures.

  • Fix the current code, so 32 bit Intel does not use AVX (it could use SSE).

  • Fix the current code, so 32 bit Intel can use AVX, but avoids unavailable 64 bit intrinsics.

No need to fix this this year – for the rest of the year I have other priorities. Happy new year!

No need to fix this this year – for the rest of the year I have other priorities. Happy new year!

Not sure if you were joking here or were serious...
If by "this year" you meant '2016', then you were joking.

Happy new year to you too!

@stweil ,
For your preferred option - "Let the compiler do the optimization (and forget that explicit SSE/AVX code). This is my preferred solution as it also works for ARM and other _architectures.". Could you advise how can it be done?

Yes, sure. You need the compiler option -ftree-vectorize. In addition, the compiler must know which kind of FPU is available. The compiler option -O3 includes -ftree-vectorize. So for an Intel CPU, -O3 -mtune=native -mavx should work. An ARM CPU could use -O3 -mfpu=neon -funsafe-math-optimizations. See https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html for more information.

https://locklessinc.com/articles/vectorize/

https://monoinfinito.wordpress.com/series/vectorization-in-gcc/

The downside to all the black-box magic the compiler does on loop-vectorization is quite big, though: you loose all visibility into how your code actually works. It might work wonderfully one day and then the next it might become the slowest part of your program, because a small change made gcc miss the chance of vectorization.

If (or when) gcc looses the ability to vectorize one of your loops, you’ll be digging around a lot of compiler logs to try and figure out what went wrong. If you were to write the vectorized loop yourself using intrinsics you’d be certain that the loop works and it’s vectorized (duh!) but you’d have to manage the portability, alignment and aliasing yourself. That’s not a trivial task if you are aiming for a portable program.

There's huge variation of SIMD support even in modern processors. For example I have an Intel CPU purchased in 2016 (Pentium G4400 Skylake) that doesn't support AVX instructions at all. Statistically speaking, most Tesseract users run precompiled binaries. Finally, Tesseract ships on more than 20 hardware platforms for Debian GNU/Linux alone, not to mention all those other operating systems.

https://buildd.debian.org/status/package.php?p=tesseract&suite=unstable

This is a tough combination. Ideally a binary will uses the fastest SIMD instructions available for the processor, and determines those instructions at runtime rather than at compile time. There's lots of discussion on the web about this, but it is not clear to me what is best practice.

Yes, binary distributions must support a wide range of hardware and ideally chose the best code at runtime.
That's why we need simddetect.cpp (with extensions for non Intel platforms).

Nevertheless there is also the need for highly optimized Tesseract installations used for training or mass production of OCR on know hardware.

The non-SIMD version of the dotproduct method can be significantly sped up by doing manual loop unrolling.

Also, this version can use OpenMP (with #pragma... above the loop)

The non-SIMD version of the dotproduct method can be significantly sped up by doing manual loop unrolling.

Which test scenario do you use?

@stweil I am getting the error while using the new binaries provided by you.
Ref https://github.com/tesseract-ocr/tesseract/issues/689

PS C:\Users\User\shree\jtess\tesseract-ocr> ./tesseract.exe -v
tesseract 4.00.00alpha
 leptonica-1.74.1
  libgif 4.1.6(?) : libjpeg 8d (libjpeg-turbo 1.5.0) : libpng 1.6.20 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.3 : libo
penjp2 2.1.0

 Found AVX
 Found SSE

Extracting tessdata components from C:\Users\User\shree\tessdata/vie.traineddata
Wrote C:\Users\User\shree\jtess\samples\vie/vie.lstm
Setting unichar properties
Setting properties for script Common
Setting properties for script Latin
Warning: given outputs 105 not equal to unicharset of 227.
Num outputs,weights in serial:
1,36,0,1:1, 0
Num outputs,weights in serial:
C5,5:25, 0
Ft16:16, 416
Total weights = 416
Mp3,3:16, 0
Lfys64:64, 20736
Lfx128:128, 98816
Lrx128:128, 131584
Lfx256:256, 394240
Fc227:227, 58339
Total weights = 704131
Built network:[1,36,0,1[C5,5Ft16]Mp3,3Lfys64Lfx128Lrx128Lfx256Fc227] from request [1,36,0,1 Ct5,5,16 Mp3,3 Lfys64 Lfx128
Lrx128 Lfx256 O1c105]
Training parameters:
Debug interval = -1, weights = 0.1, learning rate = 0.0001, momentum=0.9
Loaded 188/188 pages (1-188) of document C:\Users\User\shree\jtess\samples\vie\vie.Arial.exp0.lstmf
Info in fopenReadFromMemory: work-around: writing to a temp file
DotProductAVX can't be used on Android

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
DotProductAVX can't be used on Android
```

This is again (or still) a bug for 32 bit Intel platforms. I'll have a look how to fix it later.

Thanks!

Maybe we should keep this issue 'open'

  • excuse the brevity, sent from mobile

On 31-Jan-2017 7:05 PM, "Stefan Weil" notifications@github.com wrote:

This is again (or still) a bug for 32 bit Intel platforms. I'll have a look
how to fix it later.

—
You are receiving this because you commented.

Reply to this email directly, view it on GitHub
https://github.com/tesseract-ocr/tesseract/issues/631#issuecomment-276364076,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AE2_o29aVPR_pcI7fEuQKMHzJfOyfzF7ks5rXziIgaJpZM4LYhc-
.

This issue is addressed by pull request #698.

@stweil The pull request #698 seems to solve the problem on x86 not entirely; On Windows 7 x64, VS2015, x86 target using the latest tesseract-ocr:master branch (which includes the merged pull request #698) still results in "DotProductAVX can't be used on Android" for me (Intel i7-4650U). However, the workaround in the comment above to remove # define X86_BUILD 1 from arch/simddetect.cpp resolves this.

@const-volatile, did you use cmake? Then that still needs a fix. PR #698 only addressed builds with configure.

@stweil Ah, I see! Yes, I used cmake - never mind then!
Thank you for the clarification!

I still encounter this error "DotProductAVX can't be used on Android" with the latest source from master. I built the .exe in VS2015 with x86 target. It would work with 3.04 language data but throw exceptions when using 4.00 language data.

The workaround (commenting out the #define directive in simddetect.cpp) works, but a permanent fix is desired. Thanks.

@nguyenq, could you please try replacing #if !defined(__AVX__) || defined(__i386__) in file arch/dotproductavx.cpp by a simple #if !defined(__AVX__) and report whether the resulting tesseract.exe works with AVX? It would also be interesting how the OCR speed compares with your current tesseract.exe.

Recently support for AVX with 32 bit executables was added, but it needs the above modification to get activated.

@stweil, I undid the change to simddetect.cpp and made the change to dotproductavx.cpp. The compiled exe still crashes with the same error.

I'm not sure if I have AVX support. I run Windows 10 64-bit on i7-7500U CPU.

Run tesseract -v to see whether you have a CPU which supports AVX or SSE. The error message which you get indicates that you have AVX support. Please try the even shorter variant #if 0 to enforce that the AVX code is included (and not the _DotProductAVX can't be used on Android_ error message). It looks as if your compiler does not define the macro __AVX__.

Here is output on my machine:

tesseract 4.00.00alpha
 leptonica-1.74.1 (Feb 11 2017, 11:04:30) [MSC v.1900 DLL Release x86]
  libjpeg 9b : libpng 1.6.28 : libtiff 4.0.7 : zlib 1.2.8

 Found AVX
 Found SSE

The shorter variant works! Let me research for how to define a macro in Visual Studio for a C++ project. Do you know, by chance?

This modification might set __AVX__ (I cannot test it because I don't have MSVC):

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d227b7d..1805170 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -220,6 +220,7 @@ if (WIN32)
     if (MSVC)
         set_source_files_properties(
             ${CMAKE_CURRENT_SOURCE_DIR}/arch/dotproductavx.cpp
+            PROPERTIES COMPILE_DEFINITIONS __AVX__)
             PROPERTIES COMPILE_FLAGS "/arch:AVX")
     endif()
 endif()

It's strange that the macro __AVX__ is not set automatically by MSVC. The compiler option /arch:AVX should normally do that (see documentation).

I don't think my VS set up uses CMakeLists.txt, but I found out how to set the flag:

image

With that enabled, I reverted all the code changes. The output .exe now works good. Thank you.

I got the same error when using command line on Ubuntu:

root@ellensong: tesseract chi.jpg chi -l chi_sim
Tesseract Open Source OCR Engine v4.00.00alpha with Leptonica
DotProductAVX can't be used on Android
Aborted (core dumped)

I've never got this error when I set language param as chi_tra or eng.
Could anybody tell me how to fix it?
Thanks a lot!

@EllenSong77, did you use the latest code? Are you running Ubuntu in a virtual machine (if yes: please provide more information on the kind of virtualisation)?

@stweil I clone the code yesterday, and running Ubuntu in a physical machine. What other information could be more helpful that I should provide?

I've never got this error when I set language param as chi_tra or eng.

Very strange!

From where did you get the chi_tra and eng traineddata?
From here:
https://github.com/tesseract-ocr/tessdata/tree/3.04.00
Or from here:
https://github.com/tesseract-ocr/tessdata/tree/master/best

With the latest code, you should point your tessdata_dir to tessdata/best

On 17-Aug-2017 10:41 AM, "Amit D." notifications@github.com wrote:

From where did you get the chi_tra and eng traineddata?
From here:
https://github.com/tesseract-ocr/tessdata/tree/3.04.00
Or from here:
https://github.com/tesseract-ocr/tessdata/tree/master/best

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/tesseract-ocr/tesseract/issues/631#issuecomment-322970548,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AE2_o5gN3GvgUYBBX6NKL_cYbnaZVL2dks5sY8uYgaJpZM4LYhc-
.

@amitdo I got them by command line apt-get install tesseact-ocr-xxx and also cloned from https://github.com/tesseract-ocr/tessdata/tree/master/best
Maybe I should what @Shreeshrii said too.
Do you mean I should export TESS_DATA=......../tesseract/tesseract-ocr.tessdata/best ?
screenshot from 2017-08-17 14-31-56

I got them by command line apt-get install tesseact-ocr-xxx and also cloned from https://github.com/tesseract-ocr/tessdata/tree/master/best

What repo do you use for Tesseract?
This one?
https://launchpad.net/%7Ealex-p/+archive/ubuntu/tesseract-ocr

@stweil A number of tess4j library's users reported that their program cannot load the DLL generated with the compiler option /arch:AVX in Visual Studio IDE. It seems that the DLL loading issue is with older CPUs that do not support AVX. How can I generate an DLL that can run on any Intel/AMD cpu regardless of AVX support? The problem only appears in 4.0.0 version; 3.5.x did not have this issue.

Don't use /arch:AVX for the whole DLL. Use it only for dotproductavx.cpp and the other files with AVX in their name. Tesseract should automatically select AVX if it is supported and use SSE or other code if not.

That flag is applied at the project level (set in the .vcxproj file); I do not know how to apply it at the file level.

I just found that tesseract.exe generated by vcpkg install tesseract:x64-windows-static, as described in the Wiki, runs fine on both AVX and non-AVX CPUs. How can I build an equivalent static DLL?

I'd appreciate all the help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dthrock picture dthrock  Â·  5Comments

royudev picture royudev  Â·  5Comments

spajak picture spajak  Â·  4Comments

Shreeshrii picture Shreeshrii  Â·  4Comments

LaurentBerger picture LaurentBerger  Â·  3Comments