Skip to content

How to link OpenBlas for armv7 by CMake in Android Studio? #1280

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

Closed
nannanmath opened this issue Aug 17, 2017 · 28 comments
Closed

How to link OpenBlas for armv7 by CMake in Android Studio? #1280

nannanmath opened this issue Aug 17, 2017 · 28 comments

Comments

@nannanmath
Copy link

I compile OpenBlas according to https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android. I also find a section about linking:https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android#linking-openblas-0219-and-earlier-for-armv7. Howerver, I use cmake in Android Studio, I want to know how to set them in CMakeLists.txt. Thanks.

@brada4
Copy link
Contributor

brada4 commented Aug 17, 2017

Care to mention it is intellij or eclipse android studio?
You need NDK to build anything from CmakeLists.txt included.
In short - two worlds - 0.2.19 and below - you need old NDK and only hardfp abi is supported, 0.2.20 and in future - any ndk, also softfp ABI is supported (not yet completely up to the speed of other).

@xsacha
Copy link
Contributor

xsacha commented Aug 19, 2017

I understand you have already built the library.
Add this to your CMakeLists:

add_library(openblas STATIC IMPORTED)
set_property(TARGET OpenBLAS PROPERTY IMPORTED_LOCATION /path/to/libopenblas.a)
target_link_libraries(${PROJECT_NAME} openblas)

Change STATIC to SHARED if you built OpenBLAS as a shared library.

@martin-frbg
Copy link
Collaborator

@nannanmath did xsacha's suggestion solve the problem for you ?

@abhishek-sehgal
Copy link

Hi @martin-frbg, I followed xsacha's suggestion but i cannot add cblas.h in my android project. The Library gets added but i cannot access any functions

@xsacha
Copy link
Contributor

xsacha commented Mar 7, 2018

target_include_directories(${PROJECT_NAME} PRIVATE /path/to/blasinclude)

@abhishek-sehgal
Copy link

This statement is causing External Native Build Issues. I guess the include path might be incorrect, I've tried the following:

OpenBLAS/ OpenBLAS/lapack-netlib/CBLAS/include OpenBLAS/relapack/src

@xsacha
Copy link
Contributor

xsacha commented Mar 7, 2018

Well you said you weren't able to find cblas.h in the include, so you just need to add that path.

@abhishek-sehgal
Copy link

The following directories have cblas.h in them and I've tried both of them and still the issue persisted
OpenBLAS/

OpenBLAS/lapack-netlib/CBLAS/include

@xsacha
Copy link
Contributor

xsacha commented Mar 7, 2018

What's the issue and what's the #include line?

@xsacha
Copy link
Contributor

xsacha commented Mar 7, 2018

Usually programs that use BLAS keep their own BLAS headers. It shouldn't need to include anything from openblas. It's a standard API.

@abhishek-sehgal
Copy link

In the CMakeLists.txt file I added the target_include_directories as you had mentioned. The path I have added is as follows:

target_include_directories(${PROJECT_NAME} PRIVATE /Users/abhisheksehgal/Desktop/Test/OpenBLAS/lapack-netlib/CBLAS/include)

Now in Android Studio when I try to build the project it causes the gradle sync to fail with the messages saying "External Native Build Issues" at the target_include_directories line in CMakeLists.txt

@Mik-el
Copy link

Mik-el commented Aug 25, 2022

Something is not clear to me guys. (I'm trying to use DLIB with OpenBlas on Android).

  • I resulted to compile OpenBlas for Android. (So now I have OpenBlas built files with a Visual Studio solution file inside, OpenBlAS.sln).
  • in OpenBLASConfig.cmake I set libopenblas.a as "output" file, as suggested here.

I have two questions:

  1. I opened Visual Studio and I fully compiled the OpenBlas solution (ALL_BUILD), but I don't see any generated libopenblas.a file. What am I missing?

  2. Will the Dlib shared library (.so) still be compiled by Android studio, and do I have to only add the libopenblas.a path in the Android project, as suggested by @xsacha here . Right?

Thanks in advance.

@brada4
Copy link
Contributor

brada4 commented Aug 26, 2022

please do not overtake unrelated threads. Dlib still has no use of any BLAS.
davisking/dlib#2202

@martin-frbg
Copy link
Collaborator

hm, I read the old dlib issue as "detecting blas function availability used to be broken in the dlib build but should be fixed now". @Mik-el do you get any compilation errors from Visual Studio, and do you see any libopenblas files built anywhere (maybe it is only doing the shared one by default)?

@Mik-el
Copy link

Mik-el commented Aug 29, 2022

@brada4 Sorry, maybe I posted in the wrong thread. But are you sure DLib can't use BLAS? Because someone resulted to do it, also benchmarking the difference.
I compiled openBLAS for Android but posted my problems in this issue because it's about the last step: linking OpenBLAS in the Android Studio CMake.
(at this point, should I keep posting here or in the other issue?).

@martin-frbg Compiling everything from Visual Studio seems to work since it returns: "Compilation: 25 completed, 0 failed, 0 updated, 0 ignored".
I searched for libopenblas.a and any .so file in the build folder, but there's nothing. There are only some libblasV8.so files in the Android Studio SKD build tools and NDK folders. (but they're unrelated to DLib, I suppose).

@brada4
Copy link
Contributor

brada4 commented Aug 29, 2022

You build cross-build openblas, then use cmake-gui to import that to a cross-build of dlib?

@Mik-el
Copy link

Mik-el commented Aug 29, 2022

Android Studio compiles DLib into libdlib.so for different platforms (armeabi-v7a, arm64-v8a, x86, x86_64).
Visual Studio compiled OpenBLAS.
Are you suggesting using CMake Gui to "import" compiled OpenBLAS to compiled Dlib?
I've never heard something like that, I used CMake GUI to compile from source only, I have to study this.

@brada4
Copy link
Contributor

brada4 commented Aug 30, 2022

You need to build openblas with android NDK to import or link it from other android library. Then dlib build system should be able to detect it. Typically you get openblas as an .a file - static library and .so file - dynamic library, and cmake will try to find compatible functions under these names in there. You can check manually with ar t and nm respectively if it does not.

@Mik-el
Copy link

Mik-el commented Sep 23, 2022

Thank you @brada4.

I was only going off track with Visual Studio!
In the end I switched from Windows to Linux and I ACTUALLY compiled OpenBlas for Android.
(I have the .a and .so files for the different ARM architectures).

That's why the compilation didn't work on Windows:

As you can see it uses make PREFIX=directoryAccordingToAchitecture install. If I give locate libopenblas.so I get nothing, so I tried with a plain sudo make install which installed OpenBlas into usr/local and now locate libopenblas.so returns the .so library.

To make Dlib detect OpenBlas I opened my OpenBLASConfig.cmake and I added SET (OpenBLAS_LIBRARIES /myOpenBlasInstallDir/lib/libopenblas.a) (as suggested here).

I then compiled Dlib with this script, the compilation is OK, but OpenBlas doesn't get detected:

*** No BLAS library found so using dlib's built in BLAS.  However, if you ***
*** install an optimized BLAS such as OpenBLAS or the Intel MKL your code ***
*** will run faster.  On Ubuntu you can install OpenBLAS by executing:    ***
***    sudo apt-get install libopenblas-dev liblapack-dev                 ***
*** Or you can easily install OpenBLAS from source by downloading the     ***
*** source tar file from http://www.openblas.net/, extracting it, and     ***
*** running:

(Basically it just suggests installing OpenBlas compiled .deb packages, but they won't work, since it's not OpenBlas for cross-compilation).

I repeated all the compilation steps on both Ubuntu and a Debian-based distro, but nothing...

How can I make Dlib detect OpenBlas?
You suggested to me to look at these files but I don't know what to do with them...

Thanks for any help

@brada4
Copy link
Contributor

brada4 commented Sep 23, 2022

That is how cmake files of dlib detects BLAS under cross-build scenario.
You can do native build using termux (checking your cross-built OpenBLAS is valid there) and find the point where it starts to break.
Usually ld-some-aarch-triplet + gcc-some-aarch-triplet work fine, but I have some doubts regarding cmake in dlib doing only that. Maybe it does some native test or so down the road.
If linux file says it is aarch library there is nothing more openblas can add to whole picture. If you can link openblas library with cross-gcc to a trivial C file (gcc -L/where/is/openblas -lopenblas something.c -o binary.aarch) we cannot add anything.

@martin-frbg
Copy link
Collaborator

Not sure if cross-build has anything to do with this. From https://github.com/davisking/dlib/blob/dd1ec1fcff9479b00b233755aa673c028004d96d/dlib/cmake_utils/find_blas.cmake#L186
it seems to me dlib may not be looking in /usr/local, but it could also be that OpenBLASConfig.cmake is not working as intended. Perhaps additional information can be obtained by adding -DCMAKE_FIND_DEBUG_MODE=ON to the cmake options when building dlib

@Mik-el
Copy link

Mik-el commented Sep 28, 2022

@martin-frbg thank you. I applied your last 2 suggestions. Still Dlib can't detect OpenBlas.
Everything seems ok to me at this point...
I'm quickly rewriting the steps in chronological order, maybe you guys, can spot some mistakes.

  • My simple script to compile OpenBlas:
export NDK=/home/user/Android/Sdk/ndk/21.4.7075529
echo "Set NDK to $NDK"

export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
echo "Set TOOLCHAIN to $TOOLCHAIN"

echo    
echo " *** make clean"    
echo    
make clean

echo    
echo " *** make for ARMV8"    
echo   

make \
    TARGET=ARMV8 \
    ONLY_CBLAS=1 \
    CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang \
    AR=$TOOLCHAIN/bin/aarch64-linux-android-ar \
    HOSTCC=gcc \
    -j4

echo
echo "*************************"   
echo " *** make install start"    
echo "*************************"    
echo

#sudo make install
sudo make install DESTDIR=/home/user/Downloads/OpenBlasInstall

echo
echo "*************************"   
echo " *** make install finish "    
echo "*************************"    
echo

terminal outputs this: compileOpenBlas.pdf

  • locate libopenblas.so does not return the DESTDIR folder, but I don't care (see next step)
/etc/alternatives/libopenblas.so-x86_64-linux-gnu
/etc/alternatives/libopenblas.so.0-x86_64-linux-gnu
/home/user/Downloads/OpenBLAS/libopenblas.so
/home/user/Downloads/OpenBLAS/libopenblas.so.0
/usr/lib/x86_64-linux-gnu/libopenblas.so
/usr/lib/x86_64-linux-gnu/libopenblas.so.0
/usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblas.so
/usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblas.so.0
/var/lib/dpkg/alternatives/libopenblas.so-x86_64-linux-gnu
/var/lib/dpkg/alternatives/libopenblas.so.0-x86_64-linux-gnu
  • in dlib/cmake_utils I edited find_blas.cmake file ( this section ) adding the absolute path to my OpenBlas lib folder (2 different paths actually, just to be sure):
/home/user/Downloads/OpenBLAS/
/home/user/Downloads/OpenBlasInstall/opt/OpenBLAS/lib/
  • I edited the OpenBlas cmake file in /home/user/Downloads/OpenBlasInstall/opt/OpenBLAS/lib/cmake/openblas/OpenBLASConfigVersion.cmake which now contains this:
SET(OpenBLAS_VERSION "0.3.21.dev")
SET(OpenBLAS_INCLUDE_DIRS /home/user/Downloads/OpenBlasInstall/opt/OpenBLAS/include)
SET(OpenBLAS_LIBRARIES /home/user/Downloads/OpenBlasInstall/opt/OpenBLAS/lib/libopenblas.a)

(Meanwhile, I'm also trying with the Termux approach, just knowing that there's no Make and I'll have to do apt install clang, but I'll probably do a mess trying to rewrite stuff for Clang)

@brada4
Copy link
Contributor

brada4 commented Sep 28, 2022

Can you attach searchable plaintext instead of bitmap in pdf?

@martin-frbg
Copy link
Collaborator

pdf is searchable for me (at least the dlibCompileDebugOn one), but less informative than I had hoped. Search for openblas starts on page 633 but apoears to be restricted to subdirectories of the ndk install path

@brada4
Copy link
Contributor

brada4 commented Sep 28, 2022

On page 541 it finds Openblas 0.3.13ds in NDK paths for x86_64,

-- Checking for module 'cblas'
-- No package 'cblas' found
-- Checking for module 'lapack'
-- Found lapack, version 0.3.13+ds <---------------- !!!!!!!!!!!!!!! OpenBLAS - debian source
CMake Debug Log at /home/user/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/FindPkgConfig.cmake:285 (find_library):
find_library(pkgcfg_lib_LAPACK_REFERENCE_lapack) removed original suffix
/home/user/Android/Sdk/ndk/21.4.7075529/usr/lib/x86_64-linux-gnu/openblas-pthread/

So there is some aarch64 missed somewhere in command lines.

@Mik-el
Copy link

Mik-el commented Sep 29, 2022

Thanks for your replies as always.
All the .pdf files I attached contain text, I'm opening them from Firefox.
I don't know what you mean with missing aarch64.
The only thing I didn't attach in my last post is my edited version of the DLib compile script.
Maybe the error is there.
I just edited it again, (adding some debug messages on to display current dirs etc). Something changed, this time I get a banal Cmake error: CMake Error: The source directory does not exists : it seems that the script is trying to look for the CMake file inside the build folder instead of the source folder.
Usually the fix is to use the -S parameter to specify the source dir ( cmake -S "sources_dir" ) but I don't know how to the equivalent thing from my shell script.

I attached the script as text. (I run it from the source dir /home/user/Downloads/dlib-19.21/dlib)

dlibCompileByMikel.txt

@brada4
Copy link
Contributor

brada4 commented Sep 29, 2022

Dear, cmake with debug on PDF page 541 detects openblas x86_64 debian 0.3.13ds as a valid lapack for your cross-compilation.
That stems from cmake system library detecting totally wrong lapack.
You may temporarily rename that file, maybe it helps maybe not. only cmake with DEBUG=ON is of help, check yourself - less /openblas there if it finds your cross-build.

@brada4
Copy link
Contributor

brada4 commented Dec 3, 2022

It is inherent problem with cmake cross-build. qt or libreoffice minor dependencies (not only BLAS) suffer same way, you need to either disable minor dependency (likely your intent is not dropping OpenBLAS) or uninstall native package. There is nothing openblas could do better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants