Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"DotProductAVX can't be used on Android" while running on Windows #631

Closed
Izaron opened this issue Dec 31, 2016 · 42 comments
Closed

"DotProductAVX can't be used on Android" while running on Windows #631

Izaron opened this issue Dec 31, 2016 · 42 comments
Labels

Comments

@Izaron
Copy link

Izaron commented Dec 31, 2016

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

@stweil
Copy link
Contributor

stweil commented Dec 31, 2016

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.

@Izaron
Copy link
Author

Izaron commented Dec 31, 2016

Thanks, it works!

@Izaron Izaron closed this as completed Dec 31, 2016
@Izaron
Copy link
Author

Izaron commented Dec 31, 2016

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

@amitdo
Copy link
Collaborator

amitdo commented Dec 31, 2016

@stweil
Copy link
Contributor

stweil commented Dec 31, 2016

@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!

@amitdo
Copy link
Collaborator

amitdo commented Jan 1, 2017

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!

@CCM2016
Copy link

CCM2016 commented Jan 2, 2017

@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?

@stweil
Copy link
Contributor

stweil commented Jan 2, 2017

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.

@amitdo
Copy link
Collaborator

amitdo commented Jan 3, 2017

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.

@jbreiden
Copy link
Contributor

jbreiden commented Jan 3, 2017

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.

@stweil
Copy link
Contributor

stweil commented Jan 3, 2017

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.

@amitdo
Copy link
Collaborator

amitdo commented Jan 4, 2017

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

@amitdo
Copy link
Collaborator

amitdo commented Jan 4, 2017

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

@stweil
Copy link
Contributor

stweil commented Jan 4, 2017

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

Which test scenario do you use?

@amitdo
Copy link
Collaborator

amitdo commented Jan 4, 2017

@Shreeshrii
Copy link
Collaborator

Shreeshrii commented Jan 31, 2017

@stweil I am getting the error while using the new binaries provided by you.
Ref #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
[C5,5Ft16]:16, 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

@stweil
Copy link
Contributor

stweil commented Jan 31, 2017

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

@Shreeshrii
Copy link
Collaborator

Shreeshrii commented Feb 1, 2017 via email

@stweil
Copy link
Contributor

stweil commented Feb 2, 2017

This issue is addressed by pull request #698.

@const-volatile
Copy link

@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.

@stweil
Copy link
Contributor

stweil commented Feb 6, 2017

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

@const-volatile
Copy link

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

@nguyenq
Copy link
Contributor

nguyenq commented Feb 24, 2017

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.

@stweil
Copy link
Contributor

stweil commented Feb 24, 2017

@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.

@nguyenq
Copy link
Contributor

nguyenq commented Feb 24, 2017

@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.

@stweil
Copy link
Contributor

stweil commented Feb 24, 2017

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__.

@nguyenq
Copy link
Contributor

nguyenq commented Feb 24, 2017

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?

@stweil
Copy link
Contributor

stweil commented Feb 24, 2017

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()

@stweil
Copy link
Contributor

stweil commented Feb 24, 2017

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

@nguyenq
Copy link
Contributor

nguyenq commented Feb 24, 2017

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.

@EllenSong77
Copy link

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!

@stweil
Copy link
Contributor

stweil commented Aug 16, 2017

@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)?

@EllenSong77
Copy link

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

@amitdo
Copy link
Collaborator

amitdo commented Aug 17, 2017

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

Very strange!

@amitdo
Copy link
Collaborator

amitdo commented Aug 17, 2017

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

@Shreeshrii
Copy link
Collaborator

Shreeshrii commented Aug 17, 2017 via email

@EllenSong77
Copy link

@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

@amitdo
Copy link
Collaborator

amitdo commented Aug 17, 2017

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

@nguyenq
Copy link
Contributor

nguyenq commented Dec 12, 2018

@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.

@stweil
Copy link
Contributor

stweil commented Dec 13, 2018

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.

@nguyenq
Copy link
Contributor

nguyenq commented Dec 14, 2018

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.

@amitdo amitdo added the SIMD label May 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants