3

I cloned StockFish from GitHub and did a make inside the src folder and found that supported archs are:

  • x86-64-bmi2 > x86 64-bit with pext support (also enables SSE4)
  • x86-64-modern > x86 64-bit with popcnt support (also enables SSE3)
  • x86-64 > x86 64-bit generic
  • x86-32 > x86 32-bit (also enables SSE)
  • x86-32-old > x86 32-bit fall back for old hardware
  • ppc-64 > PPC 64-bit
  • ppc-32 > PPC 32-bit
  • armv7 > ARMv7 32-bit
  • general-64 > unspecified 64-bit
  • general-32 > unspecified 32-bit

I want to build as optimized as possible for my samsung galaxy s10+ running having an arm64-v8a exynos9820 processor.

Which archs should I choose? Will they be optimized as they could be when I build for x86-64-bmi2 for my 64bits ubuntu? If not, how could I optimize them?

(The rather simple idea is that I want to build it to have it as optimized as possible for my mobile phone.)

0
1

https://forum.armbian.com/topic/9862-info-how-to-compile-the-actual-64bit-version-of-stockfish-chess-engine/

Seems to show that you have to hack it to get it to compile at all.

2
  • 1
    Yeah for sure the makefile will have to be tweaked but in the link that you provide he uses arch = any still which shows that the build won't be optimized at all for arm64-v8a. – Olorin Jan 18 '20 at 11:41
  • agree - it doesn't seem that it can be optimized in this release. I don't see how anyway. – Michael West Jan 18 '20 at 15:37
1

We are going to need the source code : git clone https://github.com/official-stockfish/Stockfish.git (see the right address at Stockfish's github as this address could change) somewhere on your PC. (You need the command line utilities of Tortois Git for instance.) Let's call StockFishDIr the full path to the StockFish folder (that contains src as subfolder) on the PC.

We also need a cross-compiler to ... cross-compile (!) the source-code on the PC into an executable targeting the Android OS, meaning : being executable on the ANdroid OS, i.e. on the phone. We are going to use Android-NDK, which contains toolchains and cross-compilers. We download the "Latest Stable Version" r22 (as of the moment I am writing these lines) and unzip it to a folder on the PC ; I call "AndroidNdkDir" the full path to this directory (containing build, meta, prebuilt, toolchains etc folders) on the PC.

Finally, as in Stockfish's source code there is only a Makefile, we are going to need make under windows. Yes. Just get it from GnuWin32 and note MakeDir the installation directory on you PC, the one containg the bin folder containing make.exe. Analyzing the MakeFile linearly show that the cross-compilation boils down to only one command line provided some file is downloaded, and to another "optimizing" command line.

Now we look at the MakeFile from StockFishDIr\src ; we will modify it slightly.

First we change the executable name by changine the line

EXE = stockfish

into

EXE = stockfish_13_armv8_xcomp_win10x64

to give it a meaningful name.

Second, we locate the occurence of armv8 (it is the ARCH of the Samsung Galaxy S21 Ultra ; if you have another Android phone, maybe you should look for 'armv7' and adapt consequently what follows) concerning the compiler : namely, we replace the bit

    ifeq ($(arch),armv8)
        CXX=aarch64-linux-android21-clang++
        STRIP=aarch64-linux-android-strip
    endif

with

    ifeq ($(arch),armv8)
        CXX=AndroidNdkDir\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android30-clang++.cmd
        STRIP=AndroidNdkDir\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android-strip.exe
endif
    endif

(Note that there was the initial android21 in the CXX line that I replaced with android30. It is because the Samung Galaxy s21 Ultra runs Android 11 whose real version number is android30. If you have an android phone with another android version, adapt the lines consequently.)

Now, before compiling, we need one last piece : the net file (technical, net = networks = neural network = the weights file of the neural network Stockfish operates with). "Normally" (ah ah), under a linux setup (all what I do here works almost mutatis mutandis on Linux), we would just do a "MakeDir\bin\make.exe" profile-build ARCH=x86-64 which would download the net file where needed, and we would not even bother we it. Sadly, running here "MakeDir\bin\make.exe" profile-build ARCH=x86-64 doesn't work for some reason, and we need to download the net file ourselves manually. Hence we have to look in the Makefile to find how the net file is downloaded. The bit that matters in the Makefile is :

# evaluation network (nnue)
net:
    $(eval nnuenet := $(shell grep EvalFileDefaultName evaluate.h | grep define | sed 's/.*\(nn-[a-z0-9]\{12\}.nnue\).*/\1/'))
    @echo "Default net: $(nnuenet)"
    $(eval nnuedownloadurl := https://tests.stockfishchess.org/api/nn/$(nnuenet))
    $(eval curl_or_wget := $(shell if hash curl 2>/dev/null; then echo "curl -skL"; elif hash wget 2>/dev/null; then echo "wget -qO-"; fi))
    @if test -f "$(nnuenet)"; then \
            echo "Already available."; \
        else \
            if [ "x$(curl_or_wget)" = "x" ]; then \
            echo "Automatic download failed: neither curl nor wget is installed. Install one of these tools or download the net manually"; exit 1; \
            else \
            echo "Downloading $(nnuedownloadurl)"; $(curl_or_wget) $(nnuedownloadurl) > $(nnuenet);\
            fi; \
        fi;
    $(eval shasum_command := $(shell if hash shasum 2>/dev/null; then echo "shasum -a 256 "; elif hash sha256sum 2>/dev/null; then echo "sha256sum "; fi))
    @if [ "x$(shasum_command)" != "x" ]; then \
        if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
                echo "Failed download or $(nnuenet) corrupted, please delete!"; exit 1; \
            fi \
        else \
            echo "shasum / sha256sum not found, skipping net validation"; \
        fi

We see that the address of the file is https://tests.stockfishchess.org/api/nn/$(nnuenet)) and that the variable nnuenet is defined by greping the string EvalFileDefaultName inside the header file evaluate.h (which is inside StockFishDIr\src), the line of interest being :

#define EvalFileDefaultName   "nn-62ef826d1a6d.nnue"

Hence the variable nnuenet is equal to the string "nn-62ef826d1a6d.nnue" and the address we are going to download the nets from manually is https://tests.stockfishchess.org/api/nn/nn-62ef826d1a6d.nnue.

Of course, this address may change in the future, but you see the idea. Now we place the net file inside StockFishDIr\src

Now we are ready to cross-compile, with the following command to execute inside StockFishDIr\src :

"MakeDir\bin\make.exe" stockfish_13_armv8_xcomp_win10x64 COMP=ndk COMPCC="AndroidNdkDir\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android30-clang --target=aarch64-linux-android30" ARCH=armv8

(Adapt here also the aarch64-linux-android30 bits according to your Android phone.)

When the preceeding command executes properly it produces the stockfish_13_armv8_xcomp_win10x64 binary inside the StockFishDIr\src folder. This binary is already usuable on you phone (by putting it inside the DroidFish\uci folder of your DroidFish app, for instance) but is not optimal as the size is big and the execution is a little bit slow. Hence we have to "strip" the binary with the following command line, still inside the StockFishDIr\src folder :

"AndroidNdkDir\toolchains\llvm\prebuilt\windows-x86_64\bin\aarch64-linux-android-strip" stockfish_13_armv8_xcomp_win10x64

(There's no android30 anymore but there is still a aarch64 : adapt here also the aarch64-linux-android30 bits according to your Android phone.

Now, your binary file stockfish_13_armv8_xcomp_win10x64 is perfectly usable. You can play chess against StockFish 13 on your phone, and suffer ! ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.