mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 03:57:45 +00:00
Merge branch 'upstream/master' (4c7de9e8ab) into tools
This commit is contained in:
@@ -5,6 +5,7 @@ on:
|
|||||||
- master
|
- master
|
||||||
- tools
|
- tools
|
||||||
- github_ci
|
- github_ci
|
||||||
|
- github_ci_armv7
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
@@ -19,6 +20,12 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
config:
|
config:
|
||||||
|
# set the variable for the required tests:
|
||||||
|
# run_expensive_tests: true
|
||||||
|
# run_32bit_tests: true
|
||||||
|
# run_64bit_tests: true
|
||||||
|
# run_armv8_tests: true
|
||||||
|
# run_armv7_tests: true
|
||||||
- {
|
- {
|
||||||
name: "Ubuntu 20.04 GCC",
|
name: "Ubuntu 20.04 GCC",
|
||||||
os: ubuntu-20.04,
|
os: ubuntu-20.04,
|
||||||
@@ -34,18 +41,31 @@ jobs:
|
|||||||
os: ubuntu-20.04,
|
os: ubuntu-20.04,
|
||||||
compiler: clang++,
|
compiler: clang++,
|
||||||
comp: clang,
|
comp: clang,
|
||||||
run_expensive_tests: false,
|
|
||||||
run_32bit_tests: true,
|
run_32bit_tests: true,
|
||||||
run_64bit_tests: true,
|
run_64bit_tests: true,
|
||||||
shell: 'bash {0}'
|
shell: 'bash {0}'
|
||||||
}
|
}
|
||||||
|
- {
|
||||||
|
name: "Ubuntu 20.04 NDK armv8",
|
||||||
|
os: ubuntu-20.04,
|
||||||
|
compiler: aarch64-linux-android21-clang++,
|
||||||
|
comp: ndk,
|
||||||
|
run_armv8_tests: true,
|
||||||
|
shell: 'bash {0}'
|
||||||
|
}
|
||||||
|
- {
|
||||||
|
name: "Ubuntu 20.04 NDK armv7",
|
||||||
|
os: ubuntu-20.04,
|
||||||
|
compiler: armv7a-linux-androideabi21-clang++,
|
||||||
|
comp: ndk,
|
||||||
|
run_armv7_tests: true,
|
||||||
|
shell: 'bash {0}'
|
||||||
|
}
|
||||||
- {
|
- {
|
||||||
name: "MacOS 10.15 Apple Clang",
|
name: "MacOS 10.15 Apple Clang",
|
||||||
os: macos-10.15,
|
os: macos-10.15,
|
||||||
compiler: clang++,
|
compiler: clang++,
|
||||||
comp: clang,
|
comp: clang,
|
||||||
run_expensive_tests: false,
|
|
||||||
run_32bit_tests: false,
|
|
||||||
run_64bit_tests: true,
|
run_64bit_tests: true,
|
||||||
shell: 'bash {0}'
|
shell: 'bash {0}'
|
||||||
}
|
}
|
||||||
@@ -54,33 +74,37 @@ jobs:
|
|||||||
os: macos-10.15,
|
os: macos-10.15,
|
||||||
compiler: g++-10,
|
compiler: g++-10,
|
||||||
comp: gcc,
|
comp: gcc,
|
||||||
run_expensive_tests: false,
|
|
||||||
run_32bit_tests: false,
|
|
||||||
run_64bit_tests: true,
|
run_64bit_tests: true,
|
||||||
shell: 'bash {0}'
|
shell: 'bash {0}'
|
||||||
}
|
}
|
||||||
- {
|
- {
|
||||||
name: "Windows 2019 Mingw-w64 GCC x86_64",
|
name: "Windows 2022 Mingw-w64 GCC x86_64",
|
||||||
os: windows-2019,
|
os: windows-2022,
|
||||||
compiler: g++,
|
compiler: g++,
|
||||||
comp: gcc,
|
comp: mingw,
|
||||||
run_expensive_tests: false,
|
|
||||||
run_32bit_tests: false,
|
|
||||||
run_64bit_tests: true,
|
run_64bit_tests: true,
|
||||||
msys_sys: 'mingw64',
|
msys_sys: 'mingw64',
|
||||||
msys_env: 'x86_64',
|
msys_env: 'x86_64-gcc',
|
||||||
shell: 'msys2 {0}'
|
shell: 'msys2 {0}'
|
||||||
}
|
}
|
||||||
- {
|
- {
|
||||||
name: "Windows 2019 Mingw-w64 GCC i686",
|
name: "Windows 2022 Mingw-w64 GCC i686",
|
||||||
os: windows-2019,
|
os: windows-2022,
|
||||||
compiler: g++,
|
compiler: g++,
|
||||||
comp: gcc,
|
comp: mingw,
|
||||||
run_expensive_tests: false,
|
|
||||||
run_32bit_tests: true,
|
run_32bit_tests: true,
|
||||||
run_64bit_tests: false,
|
|
||||||
msys_sys: 'mingw32',
|
msys_sys: 'mingw32',
|
||||||
msys_env: 'i686',
|
msys_env: 'i686-gcc',
|
||||||
|
shell: 'msys2 {0}'
|
||||||
|
}
|
||||||
|
- {
|
||||||
|
name: "Windows 2022 Mingw-w64 Clang x86_64",
|
||||||
|
os: windows-2022,
|
||||||
|
compiler: clang++,
|
||||||
|
comp: clang,
|
||||||
|
run_64bit_tests: true,
|
||||||
|
msys_sys: 'clang64',
|
||||||
|
msys_env: 'clang-x86_64-clang',
|
||||||
shell: 'msys2 {0}'
|
shell: 'msys2 {0}'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,14 +121,14 @@ jobs:
|
|||||||
if: runner.os == 'Linux'
|
if: runner.os == 'Linux'
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install expect valgrind g++-multilib
|
sudo apt install expect valgrind g++-multilib qemu-user
|
||||||
|
|
||||||
- name: Setup msys and install required packages
|
- name: Setup msys and install required packages
|
||||||
if: runner.os == 'Windows'
|
if: runner.os == 'Windows'
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@v2
|
||||||
with:
|
with:
|
||||||
msystem: ${{matrix.config.msys_sys}}
|
msystem: ${{matrix.config.msys_sys}}
|
||||||
install: mingw-w64-${{matrix.config.msys_env}}-gcc make git expect
|
install: mingw-w64-${{matrix.config.msys_env}} make git expect
|
||||||
|
|
||||||
- name: Download the used network from the fishtest framework
|
- name: Download the used network from the fishtest framework
|
||||||
run: |
|
run: |
|
||||||
@@ -117,6 +141,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check compiler
|
- name: Check compiler
|
||||||
run: |
|
run: |
|
||||||
|
export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
|
||||||
$COMPILER -v
|
$COMPILER -v
|
||||||
|
|
||||||
- name: Test help target
|
- name: Test help target
|
||||||
@@ -238,6 +263,37 @@ jobs:
|
|||||||
make clean
|
make clean
|
||||||
make -j2 ARCH=x86-64-vnni256 build
|
make -j2 ARCH=x86-64-vnni256 build
|
||||||
|
|
||||||
|
# armv8 tests
|
||||||
|
|
||||||
|
- name: Test armv8 build
|
||||||
|
if: ${{ matrix.config.run_armv8_tests }}
|
||||||
|
run: |
|
||||||
|
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||||
|
export LDFLAGS="-static -Wno-unused-command-line-argument"
|
||||||
|
make clean
|
||||||
|
make -j2 ARCH=armv8 build
|
||||||
|
../tests/signature.sh $benchref
|
||||||
|
|
||||||
|
# armv7 tests
|
||||||
|
|
||||||
|
- name: Test armv7 build
|
||||||
|
if: ${{ matrix.config.run_armv7_tests }}
|
||||||
|
run: |
|
||||||
|
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||||
|
export LDFLAGS="-static -Wno-unused-command-line-argument"
|
||||||
|
make clean
|
||||||
|
make -j2 ARCH=armv7 build
|
||||||
|
../tests/signature.sh $benchref
|
||||||
|
|
||||||
|
- name: Test armv7-neon build
|
||||||
|
if: ${{ matrix.config.run_armv7_tests }}
|
||||||
|
run: |
|
||||||
|
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||||
|
export LDFLAGS="-static -Wno-unused-command-line-argument"
|
||||||
|
make clean
|
||||||
|
make -j2 ARCH=armv7-neon build
|
||||||
|
../tests/signature.sh $benchref
|
||||||
|
|
||||||
# Other tests
|
# Other tests
|
||||||
|
|
||||||
- name: Check perft and search reproducibility
|
- name: Check perft and search reproducibility
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# List of authors for Stockfish, as of June 14, 2021
|
# List of authors for Stockfish
|
||||||
|
|
||||||
# Founders of the Stockfish project and fishtest infrastructure
|
# Founders of the Stockfish project and fishtest infrastructure
|
||||||
Tord Romstad (romstad)
|
Tord Romstad (romstad)
|
||||||
@@ -21,6 +21,7 @@ Alexander Kure
|
|||||||
Alexander Pagel (Lolligerhans)
|
Alexander Pagel (Lolligerhans)
|
||||||
Alfredo Menezes (lonfom169)
|
Alfredo Menezes (lonfom169)
|
||||||
Ali AlZhrani (Cooffe)
|
Ali AlZhrani (Cooffe)
|
||||||
|
Andrei Vetrov (proukornew)
|
||||||
Andrew Grant (AndyGrant)
|
Andrew Grant (AndyGrant)
|
||||||
Andrey Neporada (nepal)
|
Andrey Neporada (nepal)
|
||||||
Andy Duplain
|
Andy Duplain
|
||||||
@@ -30,6 +31,7 @@ Arjun Temurnikar
|
|||||||
Artem Solopiy (EntityFX)
|
Artem Solopiy (EntityFX)
|
||||||
Auguste Pop
|
Auguste Pop
|
||||||
Balint Pfliegel
|
Balint Pfliegel
|
||||||
|
Ben Chaney (Chaneybenjamini)
|
||||||
Ben Koshy (BKSpurgeon)
|
Ben Koshy (BKSpurgeon)
|
||||||
Bill Henry (VoyagerOne)
|
Bill Henry (VoyagerOne)
|
||||||
Bojun Guo (noobpwnftw, Nooby)
|
Bojun Guo (noobpwnftw, Nooby)
|
||||||
@@ -53,6 +55,7 @@ DiscanX
|
|||||||
Dominik Schlösser (domschl)
|
Dominik Schlösser (domschl)
|
||||||
double-beep
|
double-beep
|
||||||
Douglas Matos Gomes (dsmsgms)
|
Douglas Matos Gomes (dsmsgms)
|
||||||
|
Dubslow
|
||||||
Eduardo Cáceres (eduherminio)
|
Eduardo Cáceres (eduherminio)
|
||||||
Eelco de Groot (KingDefender)
|
Eelco de Groot (KingDefender)
|
||||||
Elvin Liu (solarlight2)
|
Elvin Liu (solarlight2)
|
||||||
@@ -102,6 +105,7 @@ jundery
|
|||||||
Justin Blanchard (UncombedCoconut)
|
Justin Blanchard (UncombedCoconut)
|
||||||
Kelly Wilson
|
Kelly Wilson
|
||||||
Ken Takusagawa
|
Ken Takusagawa
|
||||||
|
Kian E (KJE-98)
|
||||||
kinderchocolate
|
kinderchocolate
|
||||||
Kiran Panditrao (Krgp)
|
Kiran Panditrao (Krgp)
|
||||||
Kojirion
|
Kojirion
|
||||||
@@ -122,6 +126,7 @@ marotear
|
|||||||
Matt Ginsberg (mattginsberg)
|
Matt Ginsberg (mattginsberg)
|
||||||
Matthew Lai (matthewlai)
|
Matthew Lai (matthewlai)
|
||||||
Matthew Sullivan (Matt14916)
|
Matthew Sullivan (Matt14916)
|
||||||
|
Max A. (Disservin)
|
||||||
Maxim Molchanov (Maxim)
|
Maxim Molchanov (Maxim)
|
||||||
Michael An (man)
|
Michael An (man)
|
||||||
Michael Byrne (MichaelB7)
|
Michael Byrne (MichaelB7)
|
||||||
@@ -131,6 +136,7 @@ Michael Whiteley (protonspring)
|
|||||||
Michel Van den Bergh (vdbergh)
|
Michel Van den Bergh (vdbergh)
|
||||||
Miguel Lahoz (miguel-l)
|
Miguel Lahoz (miguel-l)
|
||||||
Mikael Bäckman (mbootsector)
|
Mikael Bäckman (mbootsector)
|
||||||
|
Mike Babigian (Farseer)
|
||||||
Mira
|
Mira
|
||||||
Miroslav Fontán (Hexik)
|
Miroslav Fontán (Hexik)
|
||||||
Moez Jellouli (MJZ1977)
|
Moez Jellouli (MJZ1977)
|
||||||
@@ -143,6 +149,7 @@ Nikolay Kostov (NikolayIT)
|
|||||||
Nguyen Pham (nguyenpham)
|
Nguyen Pham (nguyenpham)
|
||||||
Norman Schmidt (FireFather)
|
Norman Schmidt (FireFather)
|
||||||
notruck
|
notruck
|
||||||
|
Ofek Shochat (OfekShochat, ghostway)
|
||||||
Ondrej Mosnáček (WOnder93)
|
Ondrej Mosnáček (WOnder93)
|
||||||
Oskar Werkelin Ahlin
|
Oskar Werkelin Ahlin
|
||||||
Pablo Vazquez
|
Pablo Vazquez
|
||||||
@@ -151,6 +158,7 @@ Pascal Romaret
|
|||||||
Pasquale Pigazzini (ppigazzini)
|
Pasquale Pigazzini (ppigazzini)
|
||||||
Patrick Jansen (mibere)
|
Patrick Jansen (mibere)
|
||||||
pellanda
|
pellanda
|
||||||
|
Peter Schneider (pschneider1968)
|
||||||
Peter Zsifkovits (CoffeeOne)
|
Peter Zsifkovits (CoffeeOne)
|
||||||
Praveen Kumar Tummala (praveentml)
|
Praveen Kumar Tummala (praveentml)
|
||||||
Rahul Dsilva (silversolver1)
|
Rahul Dsilva (silversolver1)
|
||||||
@@ -163,6 +171,7 @@ Rodrigo Exterckötter Tjäder
|
|||||||
Ron Britvich (Britvich)
|
Ron Britvich (Britvich)
|
||||||
Ronald de Man (syzygy1, syzygy)
|
Ronald de Man (syzygy1, syzygy)
|
||||||
rqs
|
rqs
|
||||||
|
Rui Coelho (ruicoelhopedro)
|
||||||
Ryan Schmitt
|
Ryan Schmitt
|
||||||
Ryan Takker
|
Ryan Takker
|
||||||
Sami Kiminki (skiminki)
|
Sami Kiminki (skiminki)
|
||||||
@@ -186,11 +195,13 @@ Tom Truscott
|
|||||||
Tom Vijlbrief (tomtor)
|
Tom Vijlbrief (tomtor)
|
||||||
Tomasz Sobczyk (Sopel97)
|
Tomasz Sobczyk (Sopel97)
|
||||||
Torsten Franz (torfranz, tfranzer)
|
Torsten Franz (torfranz, tfranzer)
|
||||||
|
Torsten Hellwig (Torom)
|
||||||
Tracey Emery (basepr1me)
|
Tracey Emery (basepr1me)
|
||||||
tttak
|
tttak
|
||||||
Unai Corzo (unaiic)
|
Unai Corzo (unaiic)
|
||||||
Uri Blass (uriblass)
|
Uri Blass (uriblass)
|
||||||
Vince Negri (cuddlestmonkey)
|
Vince Negri (cuddlestmonkey)
|
||||||
|
xefoci7612
|
||||||
zz4032
|
zz4032
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
[](https://github.com/official-stockfish/Stockfish/actions)
|
[](https://github.com/official-stockfish/Stockfish/actions)
|
||||||
[](https://ci.appveyor.com/project/mcostalba/stockfish/branch/master)
|
|
||||||
|
|
||||||
[Stockfish](https://stockfishchess.org) is a free, powerful UCI chess engine
|
[Stockfish](https://stockfishchess.org) is a free, powerful UCI chess engine
|
||||||
derived from Glaurung 2.1. Stockfish is not a complete chess program and requires a
|
derived from Glaurung 2.1. Stockfish is not a complete chess program and requires a
|
||||||
@@ -10,24 +9,28 @@ Cute Chess, eboard, Arena, Sigma Chess, Shredder, Chess Partner or Fritz) in ord
|
|||||||
to be used comfortably. Read the documentation for your GUI of choice for information
|
to be used comfortably. Read the documentation for your GUI of choice for information
|
||||||
about how to use Stockfish with it.
|
about how to use Stockfish with it.
|
||||||
|
|
||||||
The Stockfish engine features two evaluation functions for chess, the classical
|
The Stockfish engine features two evaluation functions for chess. The efficiently
|
||||||
evaluation based on handcrafted terms, and the NNUE evaluation based on efficiently
|
updatable neural network (NNUE) based evaluation is the default and by far the strongest.
|
||||||
updatable neural networks. The classical evaluation runs efficiently on almost all
|
The classical evaluation based on handcrafted terms remains available. The strongest
|
||||||
CPU architectures, while the NNUE evaluation benefits from the vector
|
network is integrated in the binary and downloaded automatically during the build process.
|
||||||
intrinsics available on most CPUs (sse2, avx2, neon, or similar).
|
The NNUE evaluation benefits from the vector intrinsics available on most CPUs (sse2,
|
||||||
|
avx2, neon, or similar).
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
|
|
||||||
This distribution of Stockfish consists of the following files:
|
This distribution of Stockfish consists of the following files:
|
||||||
|
|
||||||
* [Readme.md](https://github.com/official-stockfish/Stockfish/blob/master/README.md), the file you are currently reading.
|
* [README.md](https://github.com/official-stockfish/Stockfish/blob/master/README.md),
|
||||||
|
the file you are currently reading.
|
||||||
|
|
||||||
* [Copying.txt](https://github.com/official-stockfish/Stockfish/blob/master/Copying.txt), a text file containing the GNU General Public License version 3.
|
* [Copying.txt](https://github.com/official-stockfish/Stockfish/blob/master/Copying.txt),
|
||||||
|
a text file containing the GNU General Public License version 3.
|
||||||
|
|
||||||
* [AUTHORS](https://github.com/official-stockfish/Stockfish/blob/master/AUTHORS), a text file with the list of authors for the project
|
* [AUTHORS](https://github.com/official-stockfish/Stockfish/blob/master/AUTHORS),
|
||||||
|
a text file with the list of authors for the project
|
||||||
|
|
||||||
* [src](https://github.com/official-stockfish/Stockfish/tree/master/src), a subdirectory containing the full source code, including a Makefile
|
* [src](https://github.com/official-stockfish/Stockfish/tree/master/src),
|
||||||
|
a subdirectory containing the full source code, including a Makefile
|
||||||
that can be used to compile Stockfish on Unix-like systems.
|
that can be used to compile Stockfish on Unix-like systems.
|
||||||
|
|
||||||
* a file with the .nnue extension, storing the neural network for the NNUE
|
* a file with the .nnue extension, storing the neural network for the NNUE
|
||||||
@@ -37,7 +40,7 @@ This distribution of Stockfish consists of the following files:
|
|||||||
|
|
||||||
The Universal Chess Interface (UCI) is a standard protocol used to communicate with
|
The Universal Chess Interface (UCI) is a standard protocol used to communicate with
|
||||||
a chess engine, and is the recommended way to do so for typical graphical user interfaces
|
a chess engine, and is the recommended way to do so for typical graphical user interfaces
|
||||||
(GUI) or chess tools. Stockfish implements the majority of it options as described
|
(GUI) or chess tools. Stockfish implements the majority of its options as described
|
||||||
in [the UCI protocol](https://www.shredderchess.com/download/div/uci.zip).
|
in [the UCI protocol](https://www.shredderchess.com/download/div/uci.zip).
|
||||||
|
|
||||||
Developers can see the default values for UCI options available in Stockfish by typing
|
Developers can see the default values for UCI options available in Stockfish by typing
|
||||||
@@ -68,9 +71,9 @@ change them via a chess GUI. This is a list of available UCI options in Stockfis
|
|||||||
|
|
||||||
* #### EvalFile
|
* #### EvalFile
|
||||||
The name of the file of the NNUE evaluation parameters. Depending on the GUI the
|
The name of the file of the NNUE evaluation parameters. Depending on the GUI the
|
||||||
filename might have to include the full path to the folder/directory that contains the file.
|
filename might have to include the full path to the folder/directory that contains
|
||||||
Other locations, such as the directory that contains the binary and the working directory,
|
the file. Other locations, such as the directory that contains the binary and the
|
||||||
are also searched.
|
working directory, are also searched.
|
||||||
|
|
||||||
* #### UCI_AnalyseMode
|
* #### UCI_AnalyseMode
|
||||||
An option handled by your GUI.
|
An option handled by your GUI.
|
||||||
@@ -103,7 +106,7 @@ change them via a chess GUI. This is a list of available UCI options in Stockfis
|
|||||||
Example: `C:\tablebases\wdl345;C:\tablebases\wdl6;D:\tablebases\dtz345;D:\tablebases\dtz6`
|
Example: `C:\tablebases\wdl345;C:\tablebases\wdl6;D:\tablebases\dtz345;D:\tablebases\dtz6`
|
||||||
|
|
||||||
It is recommended to store .rtbw files on an SSD. There is no loss in storing
|
It is recommended to store .rtbw files on an SSD. There is no loss in storing
|
||||||
the .rtbz files on a regular HD. It is recommended to verify all md5 checksums
|
the .rtbz files on a regular HDD. It is recommended to verify all md5 checksums
|
||||||
of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will
|
of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will
|
||||||
lead to engine crashes.
|
lead to engine crashes.
|
||||||
|
|
||||||
@@ -138,8 +141,9 @@ change them via a chess GUI. This is a list of available UCI options in Stockfis
|
|||||||
For developers the following non-standard commands might be of interest, mainly useful for debugging:
|
For developers the following non-standard commands might be of interest, mainly useful for debugging:
|
||||||
|
|
||||||
* #### bench *ttSize threads limit fenFile limitType evalType*
|
* #### bench *ttSize threads limit fenFile limitType evalType*
|
||||||
Performs a standard benchmark using various options. The signature of a version (standard node
|
Performs a standard benchmark using various options. The signature of a version
|
||||||
count) is obtained using all defaults. `bench` is currently `bench 16 1 13 default depth mixed`.
|
(standard node count) is obtained using all defaults. `bench` is currently
|
||||||
|
`bench 16 1 13 default depth mixed`.
|
||||||
|
|
||||||
* #### compiler
|
* #### compiler
|
||||||
Give information about the compiler and environment used for building a binary.
|
Give information about the compiler and environment used for building a binary.
|
||||||
@@ -210,22 +214,27 @@ on the evaluations of millions of positions at moderate search depth.
|
|||||||
The NNUE evaluation was first introduced in shogi, and ported to Stockfish afterward.
|
The NNUE evaluation was first introduced in shogi, and ported to Stockfish afterward.
|
||||||
It can be evaluated efficiently on CPUs, and exploits the fact that only parts
|
It can be evaluated efficiently on CPUs, and exploits the fact that only parts
|
||||||
of the neural network need to be updated after a typical chess move.
|
of the neural network need to be updated after a typical chess move.
|
||||||
[The nodchip repository](https://github.com/nodchip/Stockfish) provides additional
|
[The nodchip repository](https://github.com/nodchip/Stockfish) provided the first
|
||||||
tools to train and develop the NNUE networks. On CPUs supporting modern vector instructions
|
version of the needed tools to train and develop the NNUE networks. Today, more
|
||||||
(avx2 and similar), the NNUE evaluation results in much stronger playing strength, even
|
advanced training tools are available in
|
||||||
if the nodes per second computed by the engine is somewhat lower (roughly 80% of nps
|
[the nnue-pytorch repository](https://github.com/glinscott/nnue-pytorch/),
|
||||||
is typical).
|
while data generation tools are available in
|
||||||
|
[a dedicated branch](https://github.com/official-stockfish/Stockfish/tree/tools).
|
||||||
|
|
||||||
|
On CPUs supporting modern vector instructions (avx2 and similar), the NNUE evaluation
|
||||||
|
results in much stronger playing strength, even if the nodes per second computed by
|
||||||
|
the engine is somewhat lower (roughly 80% of nps is typical).
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
1) the NNUE evaluation depends on the Stockfish binary and the network parameter
|
1) the NNUE evaluation depends on the Stockfish binary and the network parameter file
|
||||||
file (see the EvalFile UCI option). Not every parameter file is compatible with a given
|
(see the EvalFile UCI option). Not every parameter file is compatible with a given
|
||||||
Stockfish binary, but the default value of the EvalFile UCI option is the name of a network
|
Stockfish binary, but the default value of the EvalFile UCI option is the name of a
|
||||||
that is guaranteed to be compatible with that binary.
|
network that is guaranteed to be compatible with that binary.
|
||||||
|
|
||||||
2) to use the NNUE evaluation, the additional data file with neural network parameters
|
2) to use the NNUE evaluation, the additional data file with neural network parameters
|
||||||
needs to be available. Normally, this file is already embedded in the binary or it
|
needs to be available. Normally, this file is already embedded in the binary or it can
|
||||||
can be downloaded. The filename for the default (recommended) net can be found as the default
|
be downloaded. The filename for the default (recommended) net can be found as the default
|
||||||
value of the `EvalFile` UCI option, with the format `nn-[SHA256 first 12 digits].nnue`
|
value of the `EvalFile` UCI option, with the format `nn-[SHA256 first 12 digits].nnue`
|
||||||
(for instance, `nn-c157e0a5755b.nnue`). This file can be downloaded from
|
(for instance, `nn-c157e0a5755b.nnue`). This file can be downloaded from
|
||||||
```
|
```
|
||||||
@@ -353,10 +362,10 @@ it (either by itself or as part of some bigger software package), or
|
|||||||
using it as the starting point for a software project of your own.
|
using it as the starting point for a software project of your own.
|
||||||
|
|
||||||
The only real limitation is that whenever you distribute Stockfish in
|
The only real limitation is that whenever you distribute Stockfish in
|
||||||
some way, you MUST always include the full source code, or a pointer
|
some way, you MUST always include the license and the full source code
|
||||||
to where the source code can be found, to generate the exact binary
|
(or a pointer to where the source code can be found) to generate the
|
||||||
you are distributing. If you make any changes to the source code,
|
exact binary you are distributing. If you make any changes to the
|
||||||
these changes must also be made available under the GPL.
|
source code, these changes must also be made available under the GPL v3.
|
||||||
|
|
||||||
For full details, read the copy of the GPL v3 found in the file named
|
For full details, read the copy of the GPL v3 found in the file named
|
||||||
[*Copying.txt*](https://github.com/official-stockfish/Stockfish/blob/master/Copying.txt).
|
[*Copying.txt*](https://github.com/official-stockfish/Stockfish/blob/master/Copying.txt).
|
||||||
|
|||||||
+233
-203
@@ -1,205 +1,235 @@
|
|||||||
Contributors to Fishtest with >10,000 CPU hours, as of Jun 29, 2021.
|
Contributors to Fishtest with >10,000 CPU hours, as of 2022-04-14.
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
Username CPU Hours Games played
|
Username CPU Hours Games played
|
||||||
-----------------------------------------------------
|
------------------------------------------------------------------
|
||||||
noobpwnftw 27649494 1834734733
|
noobpwnftw 31714850 2267266129
|
||||||
mlang 1426107 89454622
|
mlang 2954099 198421098
|
||||||
dew 1380910 82831648
|
technologov 2324150 102449398
|
||||||
mibere 703840 46867607
|
dew 1670874 99276012
|
||||||
grandphish2 692707 41737913
|
grandphish2 1134273 68070459
|
||||||
tvijlbrief 669642 42371594
|
okrout 901194 77738874
|
||||||
JojoM 597778 35297180
|
TueRens 821388 50207666
|
||||||
TueRens 519226 31823562
|
tvijlbrief 795993 51894442
|
||||||
cw 458421 30307421
|
pemo 744463 32486677
|
||||||
fastgm 439667 25950040
|
JojoM 724378 43660674
|
||||||
gvreuls 436599 28177460
|
mibere 703840 46867607
|
||||||
crunchy 427035 27344275
|
linrock 626939 17408017
|
||||||
CSU_Dynasty 374765 25106278
|
gvreuls 534079 34352532
|
||||||
Fisherman 326901 21822979
|
cw 507221 34006775
|
||||||
ctoks 325477 21767943
|
fastgm 489749 29344518
|
||||||
velislav 295343 18844324
|
crunchy 427035 27344275
|
||||||
linrock 292789 10624427
|
CSU_Dynasty 424643 28525220
|
||||||
bcross 278584 19488961
|
ctoks 415771 27364603
|
||||||
okrout 262818 13803272
|
oz 369200 27017658
|
||||||
pemo 245982 11376085
|
bcross 342642 23671289
|
||||||
glinscott 217799 13780820
|
Fisherman 327231 21829379
|
||||||
leszek 212346 12959025
|
velislav 325670 20911076
|
||||||
nordlandia 211692 13484886
|
leszek 321295 19874113
|
||||||
bking_US 198894 11876016
|
Dantist 274747 16910258
|
||||||
drabel 196463 13450602
|
mgrabiak 237604 15418700
|
||||||
robal 195473 12375650
|
robal 217959 13840386
|
||||||
mgrabiak 187226 12016564
|
glinscott 217799 13780820
|
||||||
Dantist 183202 10990484
|
nordlandia 211692 13484886
|
||||||
Thanar 179852 12365359
|
drabel 201967 13798360
|
||||||
vdv 175274 9889046
|
bking_US 198894 11876016
|
||||||
spams 157128 10319326
|
mhoram 194862 12261809
|
||||||
marrco 150295 9402141
|
Thanar 179852 12365359
|
||||||
sqrt2 147963 9724586
|
vdv 175544 9904472
|
||||||
mhoram 141278 8901241
|
spams 157128 10319326
|
||||||
CoffeeOne 137100 5024116
|
rpngn 154081 9652139
|
||||||
vdbergh 137041 8926915
|
marrco 150300 9402229
|
||||||
malala 136182 8002293
|
sqrt2 147963 9724586
|
||||||
xoto 133702 9156676
|
vdbergh 137430 8955097
|
||||||
davar 122092 7960001
|
CoffeeOne 137100 5024116
|
||||||
dsmith 122059 7570238
|
malala 136182 8002293
|
||||||
Data 113305 8220352
|
xoto 133759 9159372
|
||||||
BrunoBanani 112960 7436849
|
davar 125240 8117121
|
||||||
MaZePallas 102823 6633619
|
dsmith 122059 7570238
|
||||||
sterni1971 100532 5880772
|
amicic 119659 7937885
|
||||||
ElbertoOne 99028 7023771
|
Data 113305 8220352
|
||||||
brabos 92118 6186135
|
BrunoBanani 112960 7436849
|
||||||
oz 92100 6486640
|
CypressChess 108321 7759588
|
||||||
psk 89957 5984901
|
DesolatedDodo 106811 6776980
|
||||||
amicic 89156 5392305
|
MaZePallas 102823 6633619
|
||||||
sunu 88851 6028873
|
sterni1971 100532 5880772
|
||||||
Vizvezdenec 83761 5344740
|
sunu 100167 7040199
|
||||||
0x3C33 82614 5271253
|
ElbertoOne 99028 7023771
|
||||||
BRAVONE 81239 5054681
|
skiminki 98123 6478402
|
||||||
racerschmacer 80899 5759262
|
brabos 92118 6186135
|
||||||
cuistot 80300 4606144
|
cuistot 90358 5351004
|
||||||
nssy 76497 5259388
|
psk 89957 5984901
|
||||||
teddybaer 75125 5407666
|
racerschmacer 85712 6119648
|
||||||
Pking_cda 73776 5293873
|
Vizvezdenec 83761 5344740
|
||||||
jromang 72192 5057715
|
zeryl 83680 5250995
|
||||||
solarlight 70517 5028306
|
sschnee 83003 4840890
|
||||||
dv8silencer 70287 3883992
|
0x3C33 82614 5271253
|
||||||
Bobo1239 68515 4652287
|
BRAVONE 81239 5054681
|
||||||
manap 66273 4121774
|
nssy 76497 5259388
|
||||||
skiminki 65088 4023328
|
teddybaer 75125 5407666
|
||||||
tinker 64333 4268790
|
jromang 74796 5175825
|
||||||
sschnee 60767 3500800
|
Pking_cda 73776 5293873
|
||||||
qurashee 57344 3168264
|
Calis007 72477 4088576
|
||||||
robnjr 57262 4053117
|
solarlight 70517 5028306
|
||||||
Freja 56938 3733019
|
dv8silencer 70287 3883992
|
||||||
ttruscott 56010 3680085
|
Bobo1239 68515 4652287
|
||||||
rkl 55132 4164467
|
manap 66273 4121774
|
||||||
renouve 53811 3501516
|
yurikvelo 65716 4457300
|
||||||
finfish 51360 3370515
|
tinker 64333 4268790
|
||||||
eva42 51272 3599691
|
Wolfgang 62644 3817410
|
||||||
rap 49985 3219146
|
qurashee 61208 3429862
|
||||||
pb00067 49727 3298270
|
robnjr 57262 4053117
|
||||||
ronaldjerum 47654 3240695
|
Freja 56938 3733019
|
||||||
bigpen0r 47653 3335327
|
ttruscott 56010 3680085
|
||||||
eastorwest 47585 3221629
|
rkl 55132 4164467
|
||||||
biffhero 46564 3111352
|
renouve 53811 3501516
|
||||||
VoyagerOne 45476 3452465
|
megaman7de 52434 3243016
|
||||||
yurikvelo 44834 3034550
|
MaxKlaxxMiner 51977 3153032
|
||||||
speedycpu 43842 3003273
|
finfish 51360 3370515
|
||||||
jbwiebe 43305 2805433
|
eva42 51272 3599691
|
||||||
Spprtr 42279 2680153
|
eastorwest 51058 3451555
|
||||||
DesolatedDodo 42007 2447516
|
rap 49985 3219146
|
||||||
Antihistamine 41788 2761312
|
pb00067 49727 3298270
|
||||||
mhunt 41735 2691355
|
Spprtr 48920 3161711
|
||||||
homyur 39893 2850481
|
bigpen0r 47667 3336927
|
||||||
gri 39871 2515779
|
ronaldjerum 47654 3240695
|
||||||
Fifis 38776 2529121
|
biffhero 46564 3111352
|
||||||
oryx 38724 2966648
|
Fifis 45843 3088497
|
||||||
SC 37290 2731014
|
VoyagerOne 45476 3452465
|
||||||
csnodgrass 36207 2688994
|
speedycpu 43842 3003273
|
||||||
jmdana 36157 2210661
|
jbwiebe 43305 2805433
|
||||||
strelock 34716 2074055
|
Antihistamine 41788 2761312
|
||||||
rpngn 33951 2057395
|
mhunt 41735 2691355
|
||||||
Garf 33922 2751802
|
homyur 39893 2850481
|
||||||
EthanOConnor 33370 2090311
|
gri 39871 2515779
|
||||||
slakovv 32915 2021889
|
armo9494 39064 2832326
|
||||||
manapbk 30987 1810399
|
oryx 38867 2976992
|
||||||
Prcuvu 30377 2170122
|
SC 37299 2731694
|
||||||
anst 30301 2190091
|
Garf 37213 2986270
|
||||||
jkiiski 30136 1904470
|
tolkki963 37059 2154330
|
||||||
hyperbolic.tom 29840 2017394
|
csnodgrass 36207 2688994
|
||||||
Pyafue 29650 1902349
|
jmdana 36157 2210661
|
||||||
Wolfgang 29260 1658936
|
strelock 34716 2074055
|
||||||
zeryl 28156 1579911
|
DMBK 34010 2482916
|
||||||
OuaisBla 27636 1578800
|
EthanOConnor 33370 2090311
|
||||||
DMBK 27051 1999456
|
slakovv 32915 2021889
|
||||||
chriswk 26902 1868317
|
gopeto 30993 2028106
|
||||||
achambord 26582 1767323
|
manapbk 30987 1810399
|
||||||
Patrick_G 26276 1801617
|
Prcuvu 30377 2170122
|
||||||
yorkman 26193 1992080
|
anst 30301 2190091
|
||||||
SFTUser 25182 1675689
|
jkiiski 30136 1904470
|
||||||
nabildanial 24942 1519409
|
hyperbolic.tom 29840 2017394
|
||||||
Sharaf_DG 24765 1786697
|
chuckstablers 29659 2093438
|
||||||
ncfish1 24411 1520927
|
Pyafue 29650 1902349
|
||||||
rodneyc 24227 1409514
|
ncfish1 29105 1704011
|
||||||
agg177 23890 1395014
|
belzedar94 27935 1789106
|
||||||
JanErik 23408 1703875
|
OuaisBla 27636 1578800
|
||||||
Isidor 23388 1680691
|
chriswk 26902 1868317
|
||||||
Norabor 23164 1591830
|
achambord 26582 1767323
|
||||||
cisco2015 22897 1762669
|
Patrick_G 26276 1801617
|
||||||
Zirie 22542 1472937
|
yorkman 26193 1992080
|
||||||
team-oh 22272 1636708
|
SFTUser 25182 1675689
|
||||||
MazeOfGalious 21978 1629593
|
nabildanial 24942 1519409
|
||||||
sg4032 21947 1643265
|
Sharaf_DG 24765 1786697
|
||||||
ianh2105 21725 1632562
|
rodneyc 24275 1410450
|
||||||
xor12 21628 1680365
|
agg177 23890 1395014
|
||||||
dex 21612 1467203
|
JanErik 23408 1703875
|
||||||
nesoneg 21494 1463031
|
Isidor 23388 1680691
|
||||||
sphinx 21211 1384728
|
Norabor 23339 1602636
|
||||||
jjoshua2 21001 1423089
|
Ente 23270 1651432
|
||||||
horst.prack 20878 1465656
|
cisco2015 22897 1762669
|
||||||
Ente 20865 1477066
|
MarcusTullius 22688 1274821
|
||||||
0xB00B1ES 20590 1208666
|
Zirie 22542 1472937
|
||||||
j3corre 20405 941444
|
team-oh 22272 1636708
|
||||||
Adrian.Schmidt123 20316 1281436
|
MazeOfGalious 21978 1629593
|
||||||
wei 19973 1745989
|
sg4032 21947 1643265
|
||||||
MaxKlaxxMiner 19850 1009176
|
ianh2105 21725 1632562
|
||||||
rstoesser 19569 1293588
|
xor12 21628 1680365
|
||||||
gopeto 19491 1174952
|
dex 21612 1467203
|
||||||
eudhan 19274 1283717
|
nesoneg 21494 1463031
|
||||||
jundery 18445 1115855
|
Roady 21323 1433822
|
||||||
megaman7de 18377 1067540
|
sphinx 21211 1384728
|
||||||
iisiraider 18247 1101015
|
user213718 21196 1397710
|
||||||
ville 17883 1384026
|
spcc 21065 1311338
|
||||||
chris 17698 1487385
|
jjoshua2 21001 1423089
|
||||||
purplefishies 17595 1092533
|
horst.prack 20878 1465656
|
||||||
dju 17353 978595
|
0xB00B1ES 20590 1208666
|
||||||
DragonLord 17014 1162790
|
j3corre 20405 941444
|
||||||
IgorLeMasson 16064 1147232
|
kdave 20364 1389254
|
||||||
ako027ako 15671 1173203
|
Adrian.Schmidt123 20316 1281436
|
||||||
chuckstablers 15289 891576
|
Ulysses 20217 1351500
|
||||||
Nikolay.IT 15154 1068349
|
markkulix 19976 1115258
|
||||||
Andrew Grant 15114 895539
|
wei 19973 1745989
|
||||||
OssumOpossum 14857 1007129
|
rstoesser 19569 1293588
|
||||||
Karby 14808 867120
|
eudhan 19274 1283717
|
||||||
enedene 14476 905279
|
fishtester 18995 1238686
|
||||||
bpfliegel 14298 884523
|
vulcan 18871 1729392
|
||||||
mpx86 14019 759568
|
jundery 18445 1115855
|
||||||
jpulman 13982 870599
|
iisiraider 18247 1101015
|
||||||
crocogoat 13803 1117422
|
ville 17883 1384026
|
||||||
joster 13794 950160
|
chris 17698 1487385
|
||||||
Nesa92 13786 1114691
|
purplefishies 17595 1092533
|
||||||
Hjax 13535 915487
|
dju 17353 978595
|
||||||
jsys14 13459 785000
|
Wencey 17125 805964
|
||||||
Dark_wizzie 13422 1007152
|
DragonLord 17014 1162790
|
||||||
mabichito 12903 749391
|
thirdlife 16996 447356
|
||||||
thijsk 12886 722107
|
IgorLeMasson 16064 1147232
|
||||||
AdrianSA 12860 804972
|
ako027ako 15671 1173203
|
||||||
Flopzee 12698 894821
|
AndreasKrug 15550 1194497
|
||||||
fatmurphy 12547 853210
|
Nikolay.IT 15154 1068349
|
||||||
Rudolphous 12520 832340
|
Andrew Grant 15114 895539
|
||||||
scuzzi 12511 845761
|
scuzzi 14928 953313
|
||||||
SapphireBrand 12416 969604
|
OssumOpossum 14857 1007129
|
||||||
modolief 12386 896470
|
Karby 14808 867120
|
||||||
Machariel 12335 810784
|
jsys14 14652 855642
|
||||||
pgontarz 12151 848794
|
enedene 14476 905279
|
||||||
stocky 11954 699440
|
bpfliegel 14298 884523
|
||||||
mschmidt 11941 803401
|
mpx86 14019 759568
|
||||||
Maxim 11543 836024
|
jpulman 13982 870599
|
||||||
infinity 11470 727027
|
crocogoat 13803 1117422
|
||||||
torbjo 11395 729145
|
joster 13794 950160
|
||||||
Thomas A. Anderson 11372 732094
|
Nesa92 13786 1114691
|
||||||
savage84 11358 670860
|
mbeier 13650 1044928
|
||||||
d64 11263 789184
|
Hjax 13535 915487
|
||||||
MooTheCow 11237 720174
|
Dark_wizzie 13422 1007152
|
||||||
snicolet 11106 869170
|
Jopo12321 13367 678852
|
||||||
ali-al-zhrani 11086 767926
|
Rudolphous 13244 883140
|
||||||
AndreasKrug 10875 887457
|
Machariel 13010 863104
|
||||||
pirt 10806 836519
|
mabichito 12903 749391
|
||||||
basepi 10637 744851
|
thijsk 12886 722107
|
||||||
michaelrpg 10508 739039
|
AdrianSA 12860 804972
|
||||||
dzjp 10343 732529
|
infinigon 12807 937332
|
||||||
aga 10302 622975
|
Flopzee 12698 894821
|
||||||
ols 10259 570669
|
fatmurphy 12547 853210
|
||||||
lbraesch 10252 647825
|
SapphireBrand 12416 969604
|
||||||
FormazChar 10059 757283
|
modolief 12386 896470
|
||||||
|
Farseer 12249 694108
|
||||||
|
pgontarz 12151 848794
|
||||||
|
pirt 12008 923149
|
||||||
|
stocky 11954 699440
|
||||||
|
mschmidt 11941 803401
|
||||||
|
dbernier 11609 818636
|
||||||
|
Maxim 11543 836024
|
||||||
|
infinity 11470 727027
|
||||||
|
aga 11409 695071
|
||||||
|
torbjo 11395 729145
|
||||||
|
Thomas A. Anderson 11372 732094
|
||||||
|
savage84 11358 670860
|
||||||
|
FormazChar 11349 850327
|
||||||
|
d64 11263 789184
|
||||||
|
MooTheCow 11237 720174
|
||||||
|
snicolet 11106 869170
|
||||||
|
ali-al-zhrani 11098 768494
|
||||||
|
whelanh 11067 235676
|
||||||
|
Jackfish 10978 720078
|
||||||
|
deflectooor 10886 520116
|
||||||
|
basepi 10637 744851
|
||||||
|
Cubox 10621 826448
|
||||||
|
michaelrpg 10509 739239
|
||||||
|
OIVAS7572 10420 995586
|
||||||
|
dzjp 10343 732529
|
||||||
|
Garruk 10334 704065
|
||||||
|
ols 10259 570669
|
||||||
|
lbraesch 10252 647825
|
||||||
|
qoo_charly_cai 10212 620407
|
||||||
|
Naven94 10069 503192
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
clone_depth: 50
|
|
||||||
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
||||||
# Operating system (build VM template)
|
|
||||||
os: Visual Studio 2019
|
|
||||||
|
|
||||||
# Build platform, i.e. x86, x64, AnyCPU. This setting is optional.
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
# build Configuration, i.e. Debug, Release, etc.
|
|
||||||
configuration:
|
|
||||||
- Debug
|
|
||||||
- Release
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
# The build fail immediately once one of the job fails
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
# Scripts that are called at very beginning, before repo cloning
|
|
||||||
init:
|
|
||||||
- cmake --version
|
|
||||||
- msbuild /version
|
|
||||||
|
|
||||||
before_build:
|
|
||||||
- ps: |
|
|
||||||
# Get sources
|
|
||||||
$src = get-childitem -Path *.cpp -Recurse | select -ExpandProperty FullName
|
|
||||||
$src = $src -join ' '
|
|
||||||
$src = $src.Replace("\", "/")
|
|
||||||
|
|
||||||
# Build CMakeLists.txt
|
|
||||||
$t = 'cmake_minimum_required(VERSION 3.17)',
|
|
||||||
'project(Stockfish)',
|
|
||||||
'set(CMAKE_CXX_STANDARD 17)',
|
|
||||||
'set(CMAKE_CXX_STANDARD_REQUIRED ON)',
|
|
||||||
'set (CMAKE_CXX_EXTENSIONS OFF)',
|
|
||||||
'set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src)',
|
|
||||||
'set(source_files', $src, ')',
|
|
||||||
'add_executable(stockfish ${source_files})'
|
|
||||||
|
|
||||||
# Write CMakeLists.txt withouth BOM
|
|
||||||
$MyPath = (Get-Item -Path "." -Verbose).FullName + '\CMakeLists.txt'
|
|
||||||
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
|
|
||||||
[System.IO.File]::WriteAllLines($MyPath, $t, $Utf8NoBomEncoding)
|
|
||||||
|
|
||||||
# Obtain bench reference from git log
|
|
||||||
$b = git log HEAD | sls "\b[Bb]ench[ :]+[0-9]{7}" | select -first 1
|
|
||||||
$bench = $b -match '\D+(\d+)' | % { $matches[1] }
|
|
||||||
Write-Host "Reference bench:" $bench
|
|
||||||
$g = "Visual Studio 16 2019"
|
|
||||||
If (${env:PLATFORM} -eq 'x64') { $a = "x64" }
|
|
||||||
If (${env:PLATFORM} -eq 'x86') { $a = "Win32" }
|
|
||||||
cmake -G "${g}" -A ${a} .
|
|
||||||
Write-Host "Generated files for: " $g $a
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- cmake --build . --config %CONFIGURATION% -- /verbosity:minimal
|
|
||||||
- ps: |
|
|
||||||
# Download default NNUE net from fishtest
|
|
||||||
$nnuenet = Get-Content -Path src\evaluate.h | Select-String -CaseSensitive -Pattern "EvalFileDefaultName" | Select-String -CaseSensitive -Pattern "nn-[a-z0-9]{12}.nnue"
|
|
||||||
$dummy = $nnuenet -match "(?<nnuenet>nn-[a-z0-9]{12}.nnue)"
|
|
||||||
$nnuenet = $Matches.nnuenet
|
|
||||||
Write-Host "Default net:" $nnuenet
|
|
||||||
$nnuedownloadurl = "https://tests.stockfishchess.org/api/nn/$nnuenet"
|
|
||||||
$nnuefilepath = "src\${env:CONFIGURATION}\$nnuenet"
|
|
||||||
if (Test-Path -Path $nnuefilepath) {
|
|
||||||
Write-Host "Already available."
|
|
||||||
} else {
|
|
||||||
Write-Host "Downloading $nnuedownloadurl to $nnuefilepath"
|
|
||||||
Invoke-WebRequest -Uri $nnuedownloadurl -OutFile $nnuefilepath
|
|
||||||
}
|
|
||||||
|
|
||||||
before_test:
|
|
||||||
- cd src/%CONFIGURATION%
|
|
||||||
- stockfish bench 2> out.txt >NUL
|
|
||||||
- ps: |
|
|
||||||
# Verify bench number
|
|
||||||
$s = (gc "./out.txt" | out-string)
|
|
||||||
$r = ($s -match 'Nodes searched \D+(\d+)' | % { $matches[1] })
|
|
||||||
Write-Host "Engine bench:" $r
|
|
||||||
Write-Host "Reference bench:" $bench
|
|
||||||
If ($r -ne $bench) { exit 1 }
|
|
||||||
+139
-77
@@ -1,5 +1,5 @@
|
|||||||
# Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
# Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
# Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
# Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
#
|
#
|
||||||
# Stockfish is free software: you can redistribute it and/or modify
|
# Stockfish is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,11 +19,29 @@
|
|||||||
### Section 1. General Configuration
|
### Section 1. General Configuration
|
||||||
### ==========================================================================
|
### ==========================================================================
|
||||||
|
|
||||||
|
### Establish the operating system name
|
||||||
|
KERNEL = $(shell uname -s)
|
||||||
|
ifeq ($(KERNEL),Linux)
|
||||||
|
OS = $(shell uname -o)
|
||||||
|
endif
|
||||||
|
|
||||||
|
### Target Windows OS
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
ifneq ($(COMP),ndk)
|
||||||
|
target_windows = yes
|
||||||
|
endif
|
||||||
|
else ifeq ($(COMP),mingw)
|
||||||
|
target_windows = yes
|
||||||
|
ifeq ($(WINE_PATH),)
|
||||||
|
WINE_PATH = $(shell which wine)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
### Executable name
|
### Executable name
|
||||||
ifeq ($(COMP),mingw)
|
ifeq ($(target_windows),yes)
|
||||||
EXE = stockfish.exe
|
EXE = stockfish.exe
|
||||||
else
|
else
|
||||||
EXE = stockfish
|
EXE = stockfish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### Establish the operating system name
|
### Establish the operating system name
|
||||||
@@ -38,11 +56,11 @@ BINDIR = $(PREFIX)/bin
|
|||||||
|
|
||||||
### Built-in benchmark for pgo-builds
|
### Built-in benchmark for pgo-builds
|
||||||
ifeq ($(SDE_PATH),)
|
ifeq ($(SDE_PATH),)
|
||||||
PGOBENCH = ./$(EXE) bench
|
PGOBENCH = $(WINE_PATH) ./$(EXE) bench
|
||||||
PGOGENSFEN = ./$(EXE) gensfen depth 3 loop 1000 sfen_format bin output_file_name $(PGO_TRAINING_DATA_FILE)
|
PGOGENSFEN = $(WINE_PATH) ./$(EXE) gensfen depth 3 loop 1000 sfen_format bin output_file_name $(PGO_TRAINING_DATA_FILE)
|
||||||
else
|
else
|
||||||
PGOBENCH = $(SDE_PATH) -- ./$(EXE) bench
|
PGOBENCH = $(SDE_PATH) -- $(WINE_PATH) ./$(EXE) bench
|
||||||
PGOGENSFEN = $(SDE_PATH) -- ./$(EXE) gensfen depth 3 loop 1000 sfen_format bin output_file_name $(PGO_TRAINING_DATA_FILE)
|
PGOGENSFEN = $(SDE_PATH) -- $(WINE_PATH) ./$(EXE) gensfen depth 3 loop 1000 sfen_format bin output_file_name $(PGO_TRAINING_DATA_FILE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### Source and object files
|
### Source and object files
|
||||||
@@ -89,6 +107,7 @@ VPATH = syzygy:nnue:nnue/features:eval:extra:tools
|
|||||||
# ssse3 = yes/no --- -mssse3 --- Use Intel Supplemental Streaming SIMD Extensions 3
|
# ssse3 = yes/no --- -mssse3 --- Use Intel Supplemental Streaming SIMD Extensions 3
|
||||||
# sse41 = yes/no --- -msse4.1 --- Use Intel Streaming SIMD Extensions 4.1
|
# sse41 = yes/no --- -msse4.1 --- Use Intel Streaming SIMD Extensions 4.1
|
||||||
# avx2 = yes/no --- -mavx2 --- Use Intel Advanced Vector Extensions 2
|
# avx2 = yes/no --- -mavx2 --- Use Intel Advanced Vector Extensions 2
|
||||||
|
# avxvnni = yes/no --- -mavxvnni --- Use Intel Vector Neural Network Instructions AVX
|
||||||
# avx512 = yes/no --- -mavx512bw --- Use Intel Advanced Vector Extensions 512
|
# avx512 = yes/no --- -mavx512bw --- Use Intel Advanced Vector Extensions 512
|
||||||
# vnni256 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 256
|
# vnni256 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 256
|
||||||
# vnni512 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 512
|
# vnni512 = yes/no --- -mavx512vnni --- Use Intel Vector Neural Network Instructions 512
|
||||||
@@ -99,7 +118,7 @@ VPATH = syzygy:nnue:nnue/features:eval:extra:tools
|
|||||||
# at the end of the line for flag values.
|
# at the end of the line for flag values.
|
||||||
#
|
#
|
||||||
# Example of use for these flags:
|
# Example of use for these flags:
|
||||||
# make build ARCH=x86-64-avx512 debug=on sanitize="address undefined"
|
# make build ARCH=x86-64-avx512 debug=yes sanitize="address undefined"
|
||||||
|
|
||||||
|
|
||||||
### 2.1. General and architecture defaults
|
### 2.1. General and architecture defaults
|
||||||
@@ -111,8 +130,8 @@ endif
|
|||||||
# explicitly check for the list of supported architectures (as listed with make help),
|
# explicitly check for the list of supported architectures (as listed with make help),
|
||||||
# the user can override with `make ARCH=x86-32-vnni256 SUPPORTED_ARCH=true`
|
# the user can override with `make ARCH=x86-32-vnni256 SUPPORTED_ARCH=true`
|
||||||
ifeq ($(ARCH), $(filter $(ARCH), \
|
ifeq ($(ARCH), $(filter $(ARCH), \
|
||||||
x86-64-vnni512 x86-64-vnni256 x86-64-avx512 x86-64-bmi2 x86-64-avx2 \
|
x86-64-vnni512 x86-64-vnni256 x86-64-avx512 x86-64-avxvnni x86-64-bmi2 \
|
||||||
x86-64-sse41-popcnt x86-64-modern x86-64-ssse3 x86-64-sse3-popcnt \
|
x86-64-avx2 x86-64-sse41-popcnt x86-64-modern x86-64-ssse3 x86-64-sse3-popcnt \
|
||||||
x86-64 x86-32-sse41-popcnt x86-32-sse2 x86-32 ppc-64 ppc-32 e2k \
|
x86-64 x86-32-sse41-popcnt x86-32-sse2 x86-32 ppc-64 ppc-32 e2k \
|
||||||
armv7 armv7-neon armv8 apple-silicon general-64 general-32))
|
armv7 armv7-neon armv8 apple-silicon general-64 general-32))
|
||||||
SUPPORTED_ARCH=true
|
SUPPORTED_ARCH=true
|
||||||
@@ -133,10 +152,12 @@ sse2 = no
|
|||||||
ssse3 = no
|
ssse3 = no
|
||||||
sse41 = no
|
sse41 = no
|
||||||
avx2 = no
|
avx2 = no
|
||||||
|
avxvnni = no
|
||||||
avx512 = no
|
avx512 = no
|
||||||
vnni256 = no
|
vnni256 = no
|
||||||
vnni512 = no
|
vnni512 = no
|
||||||
neon = no
|
neon = no
|
||||||
|
arm_version = 0
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
|
|
||||||
### 2.2 Architecture specific
|
### 2.2 Architecture specific
|
||||||
@@ -148,7 +169,7 @@ ifeq ($(findstring x86,$(ARCH)),x86)
|
|||||||
ifeq ($(findstring x86-32,$(ARCH)),x86-32)
|
ifeq ($(findstring x86-32,$(ARCH)),x86-32)
|
||||||
arch = i386
|
arch = i386
|
||||||
bits = 32
|
bits = 32
|
||||||
sse = yes
|
sse = no
|
||||||
mmx = yes
|
mmx = yes
|
||||||
else
|
else
|
||||||
arch = x86_64
|
arch = x86_64
|
||||||
@@ -203,6 +224,17 @@ ifeq ($(findstring -avx2,$(ARCH)),-avx2)
|
|||||||
avx2 = yes
|
avx2 = yes
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(findstring -avxvnni,$(ARCH)),-avxvnni)
|
||||||
|
popcnt = yes
|
||||||
|
sse = yes
|
||||||
|
sse2 = yes
|
||||||
|
ssse3 = yes
|
||||||
|
sse41 = yes
|
||||||
|
avx2 = yes
|
||||||
|
avxvnni = yes
|
||||||
|
pext = yes
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(findstring -bmi2,$(ARCH)),-bmi2)
|
ifeq ($(findstring -bmi2,$(ARCH)),-bmi2)
|
||||||
popcnt = yes
|
popcnt = yes
|
||||||
sse = yes
|
sse = yes
|
||||||
@@ -273,6 +305,7 @@ ifeq ($(ARCH),armv7)
|
|||||||
arch = armv7
|
arch = armv7
|
||||||
prefetch = yes
|
prefetch = yes
|
||||||
bits = 32
|
bits = 32
|
||||||
|
arm_version = 7
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH),armv7-neon)
|
ifeq ($(ARCH),armv7-neon)
|
||||||
@@ -281,6 +314,7 @@ ifeq ($(ARCH),armv7-neon)
|
|||||||
popcnt = yes
|
popcnt = yes
|
||||||
neon = yes
|
neon = yes
|
||||||
bits = 32
|
bits = 32
|
||||||
|
arm_version = 7
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH),armv8)
|
ifeq ($(ARCH),armv8)
|
||||||
@@ -288,6 +322,7 @@ ifeq ($(ARCH),armv8)
|
|||||||
prefetch = yes
|
prefetch = yes
|
||||||
popcnt = yes
|
popcnt = yes
|
||||||
neon = yes
|
neon = yes
|
||||||
|
arm_version = 8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH),apple-silicon)
|
ifeq ($(ARCH),apple-silicon)
|
||||||
@@ -295,6 +330,7 @@ ifeq ($(ARCH),apple-silicon)
|
|||||||
prefetch = yes
|
prefetch = yes
|
||||||
popcnt = yes
|
popcnt = yes
|
||||||
neon = yes
|
neon = yes
|
||||||
|
arm_version = 8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(ARCH),ppc-32)
|
ifeq ($(ARCH),ppc-32)
|
||||||
@@ -326,10 +362,16 @@ endif
|
|||||||
### ==========================================================================
|
### ==========================================================================
|
||||||
|
|
||||||
### 3.1 Selecting compiler (default = gcc)
|
### 3.1 Selecting compiler (default = gcc)
|
||||||
|
ifeq ($(MAKELEVEL),0)
|
||||||
|
export ENV_CXXFLAGS := $(CXXFLAGS)
|
||||||
|
export ENV_DEPENDFLAGS := $(DEPENDFLAGS)
|
||||||
|
export ENV_LDFLAGS := $(LDFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
ADDITIONAL_INCLUDE_DIRECTORIES = -I.
|
ADDITIONAL_INCLUDE_DIRECTORIES = -I.
|
||||||
CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -std=c++17 $(ADDITIONAL_INCLUDE_DIRECTORIES) $(EXTRACXXFLAGS)
|
CXXFLAGS = $(ENV_CXXFLAGS) -Wall -Wcast-qual -fno-exceptions -std=c++17 $(ADDITIONAL_INCLUDE_DIRECTORIES) $(EXTRACXXFLAGS)
|
||||||
DEPENDFLAGS += -std=c++17 $(ADDITIONAL_INCLUDE_DIRECTORIES)
|
DEPENDFLAGS = $(ENV_DEPENDFLAGS) -std=c++17 $(ADDITIONAL_INCLUDE_DIRECTORIES)
|
||||||
LDFLAGS += $(EXTRALDFLAGS)
|
LDFLAGS = $(ENV_LDFLAGS) $(EXTRALDFLAGS)
|
||||||
|
|
||||||
ifeq ($(COMP),)
|
ifeq ($(COMP),)
|
||||||
COMP=gcc
|
COMP=gcc
|
||||||
@@ -359,29 +401,27 @@ ifeq ($(COMP),gcc)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(target_windows),yes)
|
||||||
|
LDFLAGS += -static
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(COMP),mingw)
|
ifeq ($(COMP),mingw)
|
||||||
comp=mingw
|
comp=mingw
|
||||||
|
|
||||||
ifeq ($(KERNEL),Linux)
|
ifeq ($(bits),64)
|
||||||
ifeq ($(bits),64)
|
ifeq ($(shell which x86_64-w64-mingw32-c++-posix 2> /dev/null),)
|
||||||
ifeq ($(shell which x86_64-w64-mingw32-c++-posix),)
|
CXX=x86_64-w64-mingw32-c++
|
||||||
CXX=x86_64-w64-mingw32-c++
|
|
||||||
else
|
|
||||||
CXX=x86_64-w64-mingw32-c++-posix
|
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
ifeq ($(shell which i686-w64-mingw32-c++-posix),)
|
CXX=x86_64-w64-mingw32-c++-posix
|
||||||
CXX=i686-w64-mingw32-c++
|
|
||||||
else
|
|
||||||
CXX=i686-w64-mingw32-c++-posix
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
CXX=g++
|
ifeq ($(shell which i686-w64-mingw32-c++-posix 2> /dev/null),)
|
||||||
|
CXX=i686-w64-mingw32-c++
|
||||||
|
else
|
||||||
|
CXX=i686-w64-mingw32-c++-posix
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
CXXFLAGS += -pedantic -Wextra -Wshadow
|
||||||
CXXFLAGS += -Wextra -Wshadow
|
|
||||||
LDFLAGS += -static
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(COMP),icc)
|
ifeq ($(COMP),icc)
|
||||||
@@ -393,17 +433,19 @@ endif
|
|||||||
ifeq ($(COMP),clang)
|
ifeq ($(COMP),clang)
|
||||||
comp=clang
|
comp=clang
|
||||||
CXX=clang++
|
CXX=clang++
|
||||||
|
ifeq ($(target_windows),yes)
|
||||||
|
CXX=x86_64-w64-mingw32-clang++
|
||||||
|
endif
|
||||||
|
|
||||||
CXXFLAGS += -pedantic -Wextra -Wshadow
|
CXXFLAGS += -pedantic -Wextra -Wshadow
|
||||||
|
|
||||||
ifneq ($(KERNEL),Darwin)
|
ifeq ($(filter $(KERNEL),Darwin OpenBSD FreeBSD),)
|
||||||
ifneq ($(KERNEL),OpenBSD)
|
ifeq ($(target_windows),)
|
||||||
ifneq ($(KERNEL),FreeBSD)
|
|
||||||
ifneq ($(RTLIB),compiler-rt)
|
ifneq ($(RTLIB),compiler-rt)
|
||||||
LDFLAGS += -latomic
|
LDFLAGS += -latomic
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(arch),$(filter $(arch),armv7 armv8))
|
ifeq ($(arch),$(filter $(arch),armv7 armv8))
|
||||||
ifeq ($(OS),Android)
|
ifeq ($(OS),Android)
|
||||||
@@ -435,11 +477,19 @@ ifeq ($(COMP),ndk)
|
|||||||
ifeq ($(arch),armv7)
|
ifeq ($(arch),armv7)
|
||||||
CXX=armv7a-linux-androideabi16-clang++
|
CXX=armv7a-linux-androideabi16-clang++
|
||||||
CXXFLAGS += -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon
|
CXXFLAGS += -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon
|
||||||
STRIP=arm-linux-androideabi-strip
|
ifneq ($(shell which arm-linux-androideabi-strip 2>/dev/null),)
|
||||||
|
STRIP=arm-linux-androideabi-strip
|
||||||
|
else
|
||||||
|
STRIP=llvm-strip
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(arch),armv8)
|
ifeq ($(arch),armv8)
|
||||||
CXX=aarch64-linux-android21-clang++
|
CXX=aarch64-linux-android21-clang++
|
||||||
STRIP=aarch64-linux-android-strip
|
ifneq ($(shell which aarch64-linux-android-strip 2>/dev/null),)
|
||||||
|
STRIP=aarch64-linux-android-strip
|
||||||
|
else
|
||||||
|
STRIP=llvm-strip
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
LDFLAGS += -static-libstdc++ -pie -lm -latomic
|
LDFLAGS += -static-libstdc++ -pie -lm -latomic
|
||||||
endif
|
endif
|
||||||
@@ -453,6 +503,9 @@ else ifeq ($(comp),clang)
|
|||||||
else
|
else
|
||||||
profile_make = gcc-profile-make
|
profile_make = gcc-profile-make
|
||||||
profile_use = gcc-profile-use
|
profile_use = gcc-profile-use
|
||||||
|
ifeq ($(KERNEL),Darwin)
|
||||||
|
EXTRAPROFILEFLAGS = -fvisibility=hidden
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### Travis CI script uses COMPILER to overwrite CXX
|
### Travis CI script uses COMPILER to overwrite CXX
|
||||||
@@ -513,10 +566,16 @@ ifeq ($(optimize),yes)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(comp),$(filter $(comp),gcc clang icc))
|
ifeq ($(KERNEL),Darwin)
|
||||||
ifeq ($(KERNEL),Darwin)
|
ifeq ($(comp),$(filter $(comp),clang icc))
|
||||||
CXXFLAGS += -mdynamic-no-pic
|
CXXFLAGS += -mdynamic-no-pic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(comp),gcc)
|
||||||
|
ifneq ($(arch),arm64)
|
||||||
|
CXXFLAGS += -mdynamic-no-pic
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(comp),clang)
|
ifeq ($(comp),clang)
|
||||||
@@ -529,7 +588,7 @@ ifeq ($(bits),64)
|
|||||||
CXXFLAGS += -DIS_64BIT
|
CXXFLAGS += -DIS_64BIT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### 3.5 prefetch
|
### 3.5 prefetch and popcount
|
||||||
ifeq ($(prefetch),yes)
|
ifeq ($(prefetch),yes)
|
||||||
ifeq ($(sse),yes)
|
ifeq ($(sse),yes)
|
||||||
CXXFLAGS += -msse
|
CXXFLAGS += -msse
|
||||||
@@ -538,7 +597,6 @@ else
|
|||||||
CXXFLAGS += -DNO_PREFETCH
|
CXXFLAGS += -DNO_PREFETCH
|
||||||
endif
|
endif
|
||||||
|
|
||||||
### 3.6 popcnt
|
|
||||||
ifeq ($(popcnt),yes)
|
ifeq ($(popcnt),yes)
|
||||||
ifeq ($(arch),$(filter $(arch),ppc64 armv7 armv8 arm64))
|
ifeq ($(arch),$(filter $(arch),ppc64 armv7 armv8 arm64))
|
||||||
CXXFLAGS += -DUSE_POPCNT
|
CXXFLAGS += -DUSE_POPCNT
|
||||||
@@ -549,6 +607,7 @@ ifeq ($(popcnt),yes)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
### 3.6 SIMD architectures
|
||||||
ifeq ($(avx2),yes)
|
ifeq ($(avx2),yes)
|
||||||
CXXFLAGS += -DUSE_AVX2
|
CXXFLAGS += -DUSE_AVX2
|
||||||
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
||||||
@@ -556,6 +615,13 @@ ifeq ($(avx2),yes)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(avxvnni),yes)
|
||||||
|
CXXFLAGS += -DUSE_VNNI -DUSE_AVXVNNI
|
||||||
|
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
||||||
|
CXXFLAGS += -mavxvnni
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(avx512),yes)
|
ifeq ($(avx512),yes)
|
||||||
CXXFLAGS += -DUSE_AVX512
|
CXXFLAGS += -DUSE_AVX512
|
||||||
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
ifeq ($(comp),$(filter $(comp),gcc clang mingw))
|
||||||
@@ -606,7 +672,7 @@ ifeq ($(mmx),yes)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(neon),yes)
|
ifeq ($(neon),yes)
|
||||||
CXXFLAGS += -DUSE_NEON
|
CXXFLAGS += -DUSE_NEON=$(arm_version)
|
||||||
ifeq ($(KERNEL),Linux)
|
ifeq ($(KERNEL),Linux)
|
||||||
ifneq ($(COMP),ndk)
|
ifneq ($(COMP),ndk)
|
||||||
ifneq ($(arch),armv8)
|
ifneq ($(arch),armv8)
|
||||||
@@ -631,9 +697,7 @@ ifeq ($(optimize),yes)
|
|||||||
ifeq ($(debug), no)
|
ifeq ($(debug), no)
|
||||||
ifeq ($(comp),clang)
|
ifeq ($(comp),clang)
|
||||||
CXXFLAGS += -flto
|
CXXFLAGS += -flto
|
||||||
ifneq ($(findstring MINGW,$(KERNEL)),)
|
ifeq ($(target_windows),yes)
|
||||||
CXXFLAGS += -fuse-ld=lld
|
|
||||||
else ifneq ($(findstring MSYS,$(KERNEL)),)
|
|
||||||
CXXFLAGS += -fuse-ld=lld
|
CXXFLAGS += -fuse-ld=lld
|
||||||
endif
|
endif
|
||||||
LDFLAGS += $(CXXFLAGS)
|
LDFLAGS += $(CXXFLAGS)
|
||||||
@@ -644,25 +708,17 @@ ifeq ($(debug), no)
|
|||||||
ifeq ($(gccisclang),)
|
ifeq ($(gccisclang),)
|
||||||
CXXFLAGS += -flto
|
CXXFLAGS += -flto
|
||||||
LDFLAGS += $(CXXFLAGS) -flto=jobserver
|
LDFLAGS += $(CXXFLAGS) -flto=jobserver
|
||||||
ifneq ($(findstring MINGW,$(KERNEL)),)
|
|
||||||
LDFLAGS += -save-temps
|
|
||||||
else ifneq ($(findstring MSYS,$(KERNEL)),)
|
|
||||||
LDFLAGS += -save-temps
|
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
CXXFLAGS += -flto
|
CXXFLAGS += -flto
|
||||||
LDFLAGS += $(CXXFLAGS)
|
LDFLAGS += $(CXXFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# To use LTO and static linking on windows, the tool chain requires a recent gcc:
|
# To use LTO and static linking on Windows,
|
||||||
# gcc version 10.1 in msys2 or TDM-GCC version 9.2 are known to work, older might not.
|
# the tool chain requires gcc version 10.1 or later.
|
||||||
# So, only enable it for a cross from Linux by default.
|
|
||||||
else ifeq ($(comp),mingw)
|
else ifeq ($(comp),mingw)
|
||||||
ifeq ($(KERNEL),Linux)
|
|
||||||
ifneq ($(arch),i386)
|
ifneq ($(arch),i386)
|
||||||
CXXFLAGS += -flto
|
CXXFLAGS += -flto
|
||||||
LDFLAGS += $(CXXFLAGS) -flto=jobserver
|
LDFLAGS += $(CXXFLAGS) -save-temps
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -701,6 +757,7 @@ help:
|
|||||||
@echo "x86-64-vnni512 > x86 64-bit with vnni support 512bit wide"
|
@echo "x86-64-vnni512 > x86 64-bit with vnni support 512bit wide"
|
||||||
@echo "x86-64-vnni256 > x86 64-bit with vnni support 256bit wide"
|
@echo "x86-64-vnni256 > x86 64-bit with vnni support 256bit wide"
|
||||||
@echo "x86-64-avx512 > x86 64-bit with avx512 support"
|
@echo "x86-64-avx512 > x86 64-bit with avx512 support"
|
||||||
|
@echo "x86-64-avxvnni > x86 64-bit with avxvnni support"
|
||||||
@echo "x86-64-bmi2 > x86 64-bit with bmi2 support"
|
@echo "x86-64-bmi2 > x86 64-bit with bmi2 support"
|
||||||
@echo "x86-64-avx2 > x86 64-bit with avx2 support"
|
@echo "x86-64-avx2 > x86 64-bit with avx2 support"
|
||||||
@echo "x86-64-sse41-popcnt > x86 64-bit with sse41 and popcnt support"
|
@echo "x86-64-sse41-popcnt > x86 64-bit with sse41 and popcnt support"
|
||||||
@@ -763,8 +820,8 @@ profile-build: net config-sanity objclean profileclean
|
|||||||
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) $(profile_make)
|
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) $(profile_make)
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 2/4. Running benchmark for pgo-build ..."
|
@echo "Step 2/4. Running benchmark for pgo-build ..."
|
||||||
$(PGOBENCH) > /dev/null
|
$(PGOBENCH) 2>&1 | tail -n 4
|
||||||
$(PGOGENSFEN) > /dev/null
|
$(PGOGENSFEN) 2>&1 | tail -n 4
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 3/4. Building optimized executable ..."
|
@echo "Step 3/4. Building optimized executable ..."
|
||||||
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) objclean
|
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) objclean
|
||||||
@@ -779,7 +836,7 @@ strip:
|
|||||||
install:
|
install:
|
||||||
-mkdir -p -m 755 $(BINDIR)
|
-mkdir -p -m 755 $(BINDIR)
|
||||||
-cp $(EXE) $(BINDIR)
|
-cp $(EXE) $(BINDIR)
|
||||||
-strip $(BINDIR)/$(EXE)
|
$(STRIP) $(BINDIR)/$(EXE)
|
||||||
|
|
||||||
# clean all
|
# clean all
|
||||||
clean: objclean profileclean
|
clean: objclean profileclean
|
||||||
@@ -792,22 +849,22 @@ net:
|
|||||||
$(eval nnuedownloadurl := https://tests.stockfishchess.org/api/nn/$(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))
|
$(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 \
|
@if test -f "$(nnuenet)"; then \
|
||||||
echo "Already available."; \
|
echo "Already available."; \
|
||||||
else \
|
else \
|
||||||
if [ "x$(curl_or_wget)" = "x" ]; then \
|
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; \
|
echo "Automatic download failed: neither curl nor wget is installed. Install one of these tools or download the net manually"; exit 1; \
|
||||||
else \
|
else \
|
||||||
echo "Downloading $(nnuedownloadurl)"; $(curl_or_wget) $(nnuedownloadurl) > $(nnuenet);\
|
echo "Downloading $(nnuedownloadurl)"; $(curl_or_wget) $(nnuedownloadurl) > $(nnuenet);\
|
||||||
fi; \
|
fi; \
|
||||||
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))
|
$(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 [ "x$(shasum_command)" != "x" ]; then \
|
||||||
if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
|
if [ "$(nnuenet)" != "nn-"`$(shasum_command) $(nnuenet) | cut -c1-12`".nnue" ]; then \
|
||||||
echo "Failed download or $(nnuenet) corrupted, please delete!"; exit 1; \
|
echo "Failed download or $(nnuenet) corrupted, please delete!"; exit 1; \
|
||||||
fi \
|
fi \
|
||||||
else \
|
else \
|
||||||
echo "shasum / sha256sum not found, skipping net validation"; \
|
echo "shasum / sha256sum not found, skipping net validation"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# clean binaries and objects
|
# clean binaries and objects
|
||||||
objclean:
|
objclean:
|
||||||
@@ -818,8 +875,9 @@ profileclean:
|
|||||||
@rm -rf profdir
|
@rm -rf profdir
|
||||||
@rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s ./tools/*.gcda ./extra/*.gcda ./eval/*.gcda
|
@rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s ./tools/*.gcda ./extra/*.gcda ./eval/*.gcda
|
||||||
@rm -f stockfish.profdata *.profraw
|
@rm -f stockfish.profdata *.profraw
|
||||||
@rm -f stockfish.exe.lto_wrapper_args
|
@rm -f stockfish.*args*
|
||||||
@rm -f stockfish.exe.ltrans.out
|
@rm -f stockfish.*lt*
|
||||||
|
@rm -f stockfish.res
|
||||||
@rm -f ./-lstdc++.res
|
@rm -f ./-lstdc++.res
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -850,10 +908,12 @@ config-sanity: net
|
|||||||
@echo "ssse3: '$(ssse3)'"
|
@echo "ssse3: '$(ssse3)'"
|
||||||
@echo "sse41: '$(sse41)'"
|
@echo "sse41: '$(sse41)'"
|
||||||
@echo "avx2: '$(avx2)'"
|
@echo "avx2: '$(avx2)'"
|
||||||
|
@echo "avxvnni: '$(avxvnni)'"
|
||||||
@echo "avx512: '$(avx512)'"
|
@echo "avx512: '$(avx512)'"
|
||||||
@echo "vnni256: '$(vnni256)'"
|
@echo "vnni256: '$(vnni256)'"
|
||||||
@echo "vnni512: '$(vnni512)'"
|
@echo "vnni512: '$(vnni512)'"
|
||||||
@echo "neon: '$(neon)'"
|
@echo "neon: '$(neon)'"
|
||||||
|
@echo "arm_version: '$(arm_version)'"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Flags:"
|
@echo "Flags:"
|
||||||
@echo "CXX: $(CXX)"
|
@echo "CXX: $(CXX)"
|
||||||
@@ -905,12 +965,14 @@ gcc-profile-make:
|
|||||||
@mkdir -p profdir
|
@mkdir -p profdir
|
||||||
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
||||||
EXTRACXXFLAGS='-fprofile-generate=profdir' \
|
EXTRACXXFLAGS='-fprofile-generate=profdir' \
|
||||||
|
EXTRACXXFLAGS+=$(EXTRAPROFILEFLAGS) \
|
||||||
EXTRALDFLAGS='-lgcov' \
|
EXTRALDFLAGS='-lgcov' \
|
||||||
all
|
all
|
||||||
|
|
||||||
gcc-profile-use:
|
gcc-profile-use:
|
||||||
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
$(MAKE) ARCH=$(ARCH) COMP=$(COMP) \
|
||||||
EXTRACXXFLAGS='-fprofile-use=profdir -fno-peel-loops -fno-tracer' \
|
EXTRACXXFLAGS='-fprofile-use=profdir -fno-peel-loops -fno-tracer' \
|
||||||
|
EXTRACXXFLAGS+=$(EXTRAPROFILEFLAGS) \
|
||||||
EXTRALDFLAGS='-lgcov' \
|
EXTRALDFLAGS='-lgcov' \
|
||||||
all
|
all
|
||||||
|
|
||||||
@@ -925,7 +987,7 @@ icc-profile-use:
|
|||||||
EXTRACXXFLAGS='-prof_use -prof_dir ./profdir' \
|
EXTRACXXFLAGS='-prof_use -prof_dir ./profdir' \
|
||||||
all
|
all
|
||||||
|
|
||||||
.depend:
|
.depend: $(SRCS)
|
||||||
-@$(CXX) $(DEPENDFLAGS) -MM $(SRCS) > $@
|
-@$(CXX) $(DEPENDFLAGS) -MM $(SRCS) > $@ 2> /dev/null
|
||||||
|
|
||||||
-include .depend
|
-include .depend
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -87,6 +87,7 @@ const vector<string> Defaults = {
|
|||||||
// Chess 960
|
// Chess 960
|
||||||
"setoption name UCI_Chess960 value true",
|
"setoption name UCI_Chess960 value true",
|
||||||
"bbqnnrkr/pppppppp/8/8/8/8/PPPPPPPP/BBQNNRKR w HFhf - 0 1 moves g2g3 d7d5 d2d4 c8h3 c1g5 e8d6 g5e7 f7f6",
|
"bbqnnrkr/pppppppp/8/8/8/8/PPPPPPPP/BBQNNRKR w HFhf - 0 1 moves g2g3 d7d5 d2d4 c8h3 c1g5 e8d6 g5e7 f7f6",
|
||||||
|
"nqbnrkrb/pppppppp/8/8/8/8/PPPPPPPP/NQBNRKRB w KQkq - 0 1",
|
||||||
"setoption name UCI_Chess960 value false"
|
"setoption name UCI_Chess960 value false"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+74
-66
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -61,7 +61,7 @@ namespace Stockfish {
|
|||||||
namespace Eval {
|
namespace Eval {
|
||||||
|
|
||||||
namespace NNUE {
|
namespace NNUE {
|
||||||
string eval_file_loaded = "None";
|
string currentEvalFileName = "None";
|
||||||
UseNNUEMode useNNUE;
|
UseNNUEMode useNNUE;
|
||||||
|
|
||||||
static UseNNUEMode nnue_mode_from_option(const UCI::Option& mode)
|
static UseNNUEMode nnue_mode_from_option(const UCI::Option& mode)
|
||||||
@@ -92,6 +92,8 @@ namespace Eval {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
string eval_file = string(Options["EvalFile"]);
|
string eval_file = string(Options["EvalFile"]);
|
||||||
|
if (eval_file.empty())
|
||||||
|
eval_file = EvalFileDefaultName;
|
||||||
|
|
||||||
#if defined(DEFAULT_NNUE_DIRECTORY)
|
#if defined(DEFAULT_NNUE_DIRECTORY)
|
||||||
#define stringify2(x) #x
|
#define stringify2(x) #x
|
||||||
@@ -102,13 +104,13 @@ namespace Eval {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (string directory : dirs)
|
for (string directory : dirs)
|
||||||
if (eval_file_loaded != eval_file)
|
if (currentEvalFileName != eval_file)
|
||||||
{
|
{
|
||||||
if (directory != "<internal>")
|
if (directory != "<internal>")
|
||||||
{
|
{
|
||||||
ifstream stream(directory + eval_file, ios::binary);
|
ifstream stream(directory + eval_file, ios::binary);
|
||||||
if (load_eval(eval_file, stream))
|
if (load_eval(eval_file, stream))
|
||||||
eval_file_loaded = eval_file;
|
currentEvalFileName = eval_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (directory == "<internal>" && eval_file == EvalFileDefaultName)
|
if (directory == "<internal>" && eval_file == EvalFileDefaultName)
|
||||||
@@ -120,10 +122,11 @@ namespace Eval {
|
|||||||
|
|
||||||
MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
|
MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
|
||||||
size_t(gEmbeddedNNUESize));
|
size_t(gEmbeddedNNUESize));
|
||||||
|
(void) gEmbeddedNNUEEnd; // Silence warning on unused variable
|
||||||
|
|
||||||
istream stream(&buffer);
|
istream stream(&buffer);
|
||||||
if (load_eval(eval_file, stream))
|
if (load_eval(eval_file, stream))
|
||||||
eval_file_loaded = eval_file;
|
currentEvalFileName = eval_file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,16 +135,16 @@ namespace Eval {
|
|||||||
void NNUE::verify() {
|
void NNUE::verify() {
|
||||||
|
|
||||||
string eval_file = string(Options["EvalFile"]);
|
string eval_file = string(Options["EvalFile"]);
|
||||||
|
if (eval_file.empty())
|
||||||
|
eval_file = EvalFileDefaultName;
|
||||||
|
|
||||||
if (useNNUE != UseNNUEMode::False && eval_file_loaded != eval_file)
|
if (useNNUE != UseNNUEMode::False && currentEvalFileName != eval_file)
|
||||||
{
|
{
|
||||||
UCI::OptionsMap defaults;
|
|
||||||
UCI::init(defaults);
|
|
||||||
|
|
||||||
string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
|
string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
|
||||||
string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
|
string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
|
||||||
string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
|
string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
|
||||||
string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
|
string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + std::string(EvalFileDefaultName);
|
||||||
string msg5 = "The engine will be terminated now.";
|
string msg5 = "The engine will be terminated now.";
|
||||||
|
|
||||||
sync_cout << "info string ERROR: " << msg1 << sync_endl;
|
sync_cout << "info string ERROR: " << msg1 << sync_endl;
|
||||||
@@ -204,17 +207,17 @@ using namespace Trace;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Threshold for lazy and space evaluation
|
// Threshold for lazy and space evaluation
|
||||||
constexpr Value LazyThreshold1 = Value(3130);
|
constexpr Value LazyThreshold1 = Value(3631);
|
||||||
constexpr Value LazyThreshold2 = Value(2204);
|
constexpr Value LazyThreshold2 = Value(2084);
|
||||||
constexpr Value SpaceThreshold = Value(11551);
|
constexpr Value SpaceThreshold = Value(11551);
|
||||||
|
|
||||||
// KingAttackWeights[PieceType] contains king attack weights by piece type
|
// KingAttackWeights[PieceType] contains king attack weights by piece type
|
||||||
constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
|
constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 76, 46, 45, 14 };
|
||||||
|
|
||||||
// SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
|
// SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
|
||||||
// higher if multiple safe checks are possible for that piece type.
|
// higher if multiple safe checks are possible for that piece type.
|
||||||
constexpr int SafeCheck[][2] = {
|
constexpr int SafeCheck[][2] = {
|
||||||
{}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
|
{}, {}, {805, 1292}, {650, 984}, {1071, 1886}, {730, 1128}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define S(mg, eg) make_score(mg, eg)
|
#define S(mg, eg) make_score(mg, eg)
|
||||||
@@ -240,58 +243,58 @@ namespace {
|
|||||||
// BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
|
// BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
|
||||||
// squares of the same color as our bishop.
|
// squares of the same color as our bishop.
|
||||||
constexpr Score BishopPawns[int(FILE_NB) / 2] = {
|
constexpr Score BishopPawns[int(FILE_NB) / 2] = {
|
||||||
S(3, 8), S(3, 9), S(2, 8), S(3, 8)
|
S(3, 8), S(3, 9), S(2, 7), S(3, 7)
|
||||||
};
|
};
|
||||||
|
|
||||||
// KingProtector[knight/bishop] contains penalty for each distance unit to own king
|
// KingProtector[knight/bishop] contains penalty for each distance unit to own king
|
||||||
constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
|
constexpr Score KingProtector[] = { S(9, 9), S(7, 9) };
|
||||||
|
|
||||||
// Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
|
// Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
|
||||||
// pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
|
// pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
|
||||||
constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
|
constexpr Score Outpost[] = { S(54, 34), S(31, 25) };
|
||||||
|
|
||||||
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
||||||
constexpr Score PassedRank[RANK_NB] = {
|
constexpr Score PassedRank[RANK_NB] = {
|
||||||
S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
|
S(0, 0), S(2, 38), S(15, 36), S(22, 50), S(64, 81), S(166, 184), S(284, 269)
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr Score RookOnClosedFile = S(10, 5);
|
constexpr Score RookOnClosedFile = S(10, 5);
|
||||||
constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
|
constexpr Score RookOnOpenFile[] = { S(18, 8), S(49, 26) };
|
||||||
|
|
||||||
// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
|
// ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
|
||||||
// which piece type attacks which one. Attacks on lesser pieces which are
|
// which piece type attacks which one. Attacks on lesser pieces which are
|
||||||
// pawn-defended are not considered.
|
// pawn-defended are not considered.
|
||||||
constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
|
constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
|
||||||
S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
|
S(0, 0), S(6, 37), S(64, 50), S(82, 57), S(103, 130), S(81, 163)
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
|
constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
|
||||||
S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
|
S(0, 0), S(3, 44), S(36, 71), S(44, 59), S(0, 39), S(60, 39)
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr Value CorneredBishop = Value(50);
|
constexpr Value CorneredBishop = Value(50);
|
||||||
|
|
||||||
// Assorted bonuses and penalties
|
// Assorted bonuses and penalties
|
||||||
constexpr Score UncontestedOutpost = S( 1, 10);
|
constexpr Score UncontestedOutpost = S( 0, 10);
|
||||||
constexpr Score BishopOnKingRing = S( 24, 0);
|
constexpr Score BishopOnKingRing = S( 24, 0);
|
||||||
constexpr Score BishopXRayPawns = S( 4, 5);
|
constexpr Score BishopXRayPawns = S( 4, 5);
|
||||||
constexpr Score FlankAttacks = S( 8, 0);
|
constexpr Score FlankAttacks = S( 8, 0);
|
||||||
constexpr Score Hanging = S( 69, 36);
|
constexpr Score Hanging = S( 72, 40);
|
||||||
constexpr Score KnightOnQueen = S( 16, 11);
|
constexpr Score KnightOnQueen = S( 16, 11);
|
||||||
constexpr Score LongDiagonalBishop = S( 45, 0);
|
constexpr Score LongDiagonalBishop = S( 45, 0);
|
||||||
constexpr Score MinorBehindPawn = S( 18, 3);
|
constexpr Score MinorBehindPawn = S( 18, 3);
|
||||||
constexpr Score PassedFile = S( 11, 8);
|
constexpr Score PassedFile = S( 13, 8);
|
||||||
constexpr Score PawnlessFlank = S( 17, 95);
|
constexpr Score PawnlessFlank = S( 19, 97);
|
||||||
constexpr Score ReachableOutpost = S( 31, 22);
|
constexpr Score ReachableOutpost = S( 33, 19);
|
||||||
constexpr Score RestrictedPiece = S( 7, 7);
|
constexpr Score RestrictedPiece = S( 6, 7);
|
||||||
constexpr Score RookOnKingRing = S( 16, 0);
|
constexpr Score RookOnKingRing = S( 16, 0);
|
||||||
constexpr Score SliderOnQueen = S( 60, 18);
|
constexpr Score SliderOnQueen = S( 62, 21);
|
||||||
constexpr Score ThreatByKing = S( 24, 89);
|
constexpr Score ThreatByKing = S( 24, 87);
|
||||||
constexpr Score ThreatByPawnPush = S( 48, 39);
|
constexpr Score ThreatByPawnPush = S( 48, 39);
|
||||||
constexpr Score ThreatBySafePawn = S(173, 94);
|
constexpr Score ThreatBySafePawn = S(167, 99);
|
||||||
constexpr Score TrappedRook = S( 55, 13);
|
constexpr Score TrappedRook = S( 55, 13);
|
||||||
constexpr Score WeakQueenProtection = S( 14, 0);
|
constexpr Score WeakQueenProtection = S( 14, 0);
|
||||||
constexpr Score WeakQueen = S( 56, 15);
|
constexpr Score WeakQueen = S( 57, 19);
|
||||||
|
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
@@ -1000,7 +1003,9 @@ namespace {
|
|||||||
|
|
||||||
// Early exit if score is high
|
// Early exit if score is high
|
||||||
auto lazy_skip = [&](Value lazyThreshold) {
|
auto lazy_skip = [&](Value lazyThreshold) {
|
||||||
return abs(mg_value(score) + eg_value(score)) > lazyThreshold + pos.non_pawn_material() / 32;
|
return abs(mg_value(score) + eg_value(score)) > lazyThreshold
|
||||||
|
+ std::abs(pos.this_thread()->bestValue) * 5 / 4
|
||||||
|
+ pos.non_pawn_material() / 32;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (lazy_skip(LazyThreshold1))
|
if (lazy_skip(LazyThreshold1))
|
||||||
@@ -1065,26 +1070,22 @@ make_v:
|
|||||||
|
|
||||||
if ( pos.piece_on(SQ_A1) == W_BISHOP
|
if ( pos.piece_on(SQ_A1) == W_BISHOP
|
||||||
&& pos.piece_on(SQ_B2) == W_PAWN)
|
&& pos.piece_on(SQ_B2) == W_PAWN)
|
||||||
correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
|
correction -= CorneredBishop;
|
||||||
: -CorneredBishop * 3;
|
|
||||||
|
|
||||||
if ( pos.piece_on(SQ_H1) == W_BISHOP
|
if ( pos.piece_on(SQ_H1) == W_BISHOP
|
||||||
&& pos.piece_on(SQ_G2) == W_PAWN)
|
&& pos.piece_on(SQ_G2) == W_PAWN)
|
||||||
correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
|
correction -= CorneredBishop;
|
||||||
: -CorneredBishop * 3;
|
|
||||||
|
|
||||||
if ( pos.piece_on(SQ_A8) == B_BISHOP
|
if ( pos.piece_on(SQ_A8) == B_BISHOP
|
||||||
&& pos.piece_on(SQ_B7) == B_PAWN)
|
&& pos.piece_on(SQ_B7) == B_PAWN)
|
||||||
correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
|
correction += CorneredBishop;
|
||||||
: CorneredBishop * 3;
|
|
||||||
|
|
||||||
if ( pos.piece_on(SQ_H8) == B_BISHOP
|
if ( pos.piece_on(SQ_H8) == B_BISHOP
|
||||||
&& pos.piece_on(SQ_G7) == B_PAWN)
|
&& pos.piece_on(SQ_G7) == B_PAWN)
|
||||||
correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
|
correction += CorneredBishop;
|
||||||
: CorneredBishop * 3;
|
|
||||||
|
|
||||||
return pos.side_to_move() == WHITE ? Value(correction)
|
return pos.side_to_move() == WHITE ? Value(3 * correction)
|
||||||
: -Value(correction);
|
: -Value(3 * correction);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Eval
|
} // namespace Eval
|
||||||
@@ -1107,37 +1108,39 @@ Value Eval::evaluate(const Position& pos) {
|
|||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
else if (NNUE::useNNUE == NNUE::UseNNUEMode::False)
|
|
||||||
v = Evaluation<NO_TRACE>(pos).value();
|
// Deciding between classical and NNUE eval (~10 Elo): for high PSQ imbalance we use classical,
|
||||||
else
|
// but we switch to NNUE during long shuffling or with high material on the board.
|
||||||
|
bool useClassical = (pos.this_thread()->depth > 9 || pos.count<ALL_PIECES>() > 7) &&
|
||||||
|
abs(eg_value(pos.psq_score())) * 5 > (856 + pos.non_pawn_material() / 64) * (10 + pos.rule50_count());
|
||||||
|
|
||||||
|
// Deciding between classical and NNUE eval (~10 Elo): for high PSQ imbalance we use classical,
|
||||||
|
// but we switch to NNUE during long shuffling or with high material on the board.
|
||||||
|
if (NNUE::useNNUE == NNUE::UseNNUEMode::False || useClassical)
|
||||||
{
|
{
|
||||||
// Scale and shift NNUE for compatibility with search and classical evaluation
|
v = Evaluation<NO_TRACE>(pos).value(); // classical
|
||||||
auto adjusted_NNUE = [&]()
|
useClassical = abs(v) >= 297;
|
||||||
{
|
}
|
||||||
int scale = 883
|
|
||||||
+ 32 * pos.count<PAWN>()
|
|
||||||
+ 32 * pos.non_pawn_material() / 1024;
|
|
||||||
|
|
||||||
Value nnue = NNUE::evaluate(pos, true) * scale / 1024;
|
// If result of a classical evaluation is much lower than threshold fall back to NNUE
|
||||||
|
if (NNUE::useNNUE != NNUE::UseNNUEMode::False && !useClassical)
|
||||||
|
{
|
||||||
|
Value nnue = NNUE::evaluate(pos, true); // NNUE
|
||||||
|
int scale = 1080 + 110 * pos.non_pawn_material() / 5120;
|
||||||
|
Color stm = pos.side_to_move();
|
||||||
|
Value optimism = pos.this_thread()->optimism[stm];
|
||||||
|
Value psq = (stm == WHITE ? 1 : -1) * eg_value(pos.psq_score());
|
||||||
|
int complexity = (278 * abs(nnue - psq)) / 256;
|
||||||
|
|
||||||
if (pos.is_chess960())
|
optimism = optimism * (251 + complexity) / 256;
|
||||||
nnue += fix_FRC(pos);
|
v = (nnue * scale + optimism * (scale - 852)) / 1024;
|
||||||
|
|
||||||
return nnue;
|
if (pos.is_chess960())
|
||||||
};
|
v += fix_FRC(pos);
|
||||||
|
|
||||||
// If there is PSQ imbalance we use the classical eval, but we switch to
|
|
||||||
// NNUE eval faster when shuffling or if the material on the board is high.
|
|
||||||
int r50 = pos.rule50_count();
|
|
||||||
Value psq = Value(abs(eg_value(pos.psq_score())));
|
|
||||||
bool classical = psq * 5 > (850 + pos.non_pawn_material() / 64) * (5 + r50);
|
|
||||||
|
|
||||||
v = classical ? Evaluation<NO_TRACE>(pos).value() // classical
|
|
||||||
: adjusted_NNUE(); // NNUE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Damp down the evaluation linearly when shuffling
|
// Damp down the evaluation linearly when shuffling
|
||||||
v = v * (100 - pos.rule50_count()) / 100;
|
v = v * (195 - pos.rule50_count()) / 211;
|
||||||
|
|
||||||
// Guarantee evaluation does not hit the tablebase range
|
// Guarantee evaluation does not hit the tablebase range
|
||||||
v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
||||||
@@ -1162,7 +1165,12 @@ std::string Eval::trace(Position& pos) {
|
|||||||
|
|
||||||
std::memset(scores, 0, sizeof(scores));
|
std::memset(scores, 0, sizeof(scores));
|
||||||
|
|
||||||
pos.this_thread()->trend = SCORE_ZERO; // Reset any dynamic contempt
|
// Reset any global variable used in eval
|
||||||
|
pos.this_thread()->depth = 0;
|
||||||
|
pos.this_thread()->trend = SCORE_ZERO;
|
||||||
|
pos.this_thread()->bestValue = VALUE_ZERO;
|
||||||
|
pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
|
||||||
|
pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
|
||||||
|
|
||||||
v = Evaluation<TRACE>(pos).value();
|
v = Evaluation<TRACE>(pos).value();
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -36,7 +36,7 @@ namespace Eval {
|
|||||||
// The default net name MUST follow the format nn-[SHA256 first 12 digits].nnue
|
// The default net name MUST follow the format nn-[SHA256 first 12 digits].nnue
|
||||||
// for the build process (profile-build and fishtest) to work. Do not change the
|
// for the build process (profile-build and fishtest) to work. Do not change the
|
||||||
// name of the macro, as it is used in the Makefile.
|
// name of the macro, as it is used in the Makefile.
|
||||||
#define EvalFileDefaultName "nn-e8321e467bf6.nnue"
|
#define EvalFileDefaultName "nn-3c0aa92af1da.nnue"
|
||||||
|
|
||||||
namespace NNUE {
|
namespace NNUE {
|
||||||
enum struct UseNNUEMode
|
enum struct UseNNUEMode
|
||||||
@@ -47,7 +47,7 @@ namespace Eval {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern UseNNUEMode useNNUE;
|
extern UseNNUEMode useNNUE;
|
||||||
extern std::string eval_file_loaded;
|
extern std::string currentEvalFileName;
|
||||||
|
|
||||||
std::string trace(Position& pos);
|
std::string trace(Position& pos);
|
||||||
Value evaluate(const Position& pos, bool adjusted = false);
|
Value evaluate(const Position& pos, bool adjusted = false);
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+38
-18
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -36,6 +36,8 @@ typedef bool(*fun1_t)(LOGICAL_PROCESSOR_RELATIONSHIP,
|
|||||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
|
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
|
||||||
typedef bool(*fun2_t)(USHORT, PGROUP_AFFINITY);
|
typedef bool(*fun2_t)(USHORT, PGROUP_AFFINITY);
|
||||||
typedef bool(*fun3_t)(HANDLE, CONST GROUP_AFFINITY*, PGROUP_AFFINITY);
|
typedef bool(*fun3_t)(HANDLE, CONST GROUP_AFFINITY*, PGROUP_AFFINITY);
|
||||||
|
typedef bool(*fun4_t)(USHORT, PGROUP_AFFINITY, USHORT, PUSHORT);
|
||||||
|
typedef WORD(*fun5_t)();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -112,7 +114,14 @@ public:
|
|||||||
|
|
||||||
static Logger l;
|
static Logger l;
|
||||||
|
|
||||||
if (!fname.empty() && !l.file.is_open())
|
if (l.file.is_open())
|
||||||
|
{
|
||||||
|
cout.rdbuf(l.out.buf);
|
||||||
|
cin.rdbuf(l.in.buf);
|
||||||
|
l.file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fname.empty())
|
||||||
{
|
{
|
||||||
l.file.open(fname, ifstream::out);
|
l.file.open(fname, ifstream::out);
|
||||||
|
|
||||||
@@ -125,12 +134,6 @@ public:
|
|||||||
cin.rdbuf(&l.in);
|
cin.rdbuf(&l.in);
|
||||||
cout.rdbuf(&l.out);
|
cout.rdbuf(&l.out);
|
||||||
}
|
}
|
||||||
else if (fname.empty() && l.file.is_open())
|
|
||||||
{
|
|
||||||
cout.rdbuf(l.out.buf);
|
|
||||||
cin.rdbuf(l.in.buf);
|
|
||||||
l.file.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -496,11 +499,11 @@ void bindThisThread(size_t) {}
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/// best_group() retrieves logical processor information using Windows specific
|
/// best_node() retrieves logical processor information using Windows specific
|
||||||
/// API and returns the best group id for the thread with index idx. Original
|
/// API and returns the best node id for the thread with index idx. Original
|
||||||
/// code from Texel by Peter Österlund.
|
/// code from Texel by Peter Österlund.
|
||||||
|
|
||||||
int best_group(size_t idx) {
|
int best_node(size_t idx) {
|
||||||
|
|
||||||
int threads = 0;
|
int threads = 0;
|
||||||
int nodes = 0;
|
int nodes = 0;
|
||||||
@@ -514,7 +517,8 @@ int best_group(size_t idx) {
|
|||||||
if (!fun1)
|
if (!fun1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// First call to get returnLength. We expect it to fail due to null buffer
|
// First call to GetLogicalProcessorInformationEx() to get returnLength.
|
||||||
|
// We expect the call to fail due to null buffer.
|
||||||
if (fun1(RelationAll, nullptr, &returnLength))
|
if (fun1(RelationAll, nullptr, &returnLength))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -522,7 +526,7 @@ int best_group(size_t idx) {
|
|||||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buffer, *ptr;
|
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buffer, *ptr;
|
||||||
ptr = buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(returnLength);
|
ptr = buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(returnLength);
|
||||||
|
|
||||||
// Second call, now we expect to succeed
|
// Second call to GetLogicalProcessorInformationEx(), now we expect to succeed
|
||||||
if (!fun1(RelationAll, buffer, &returnLength))
|
if (!fun1(RelationAll, buffer, &returnLength))
|
||||||
{
|
{
|
||||||
free(buffer);
|
free(buffer);
|
||||||
@@ -572,22 +576,38 @@ int best_group(size_t idx) {
|
|||||||
void bindThisThread(size_t idx) {
|
void bindThisThread(size_t idx) {
|
||||||
|
|
||||||
// Use only local variables to be thread-safe
|
// Use only local variables to be thread-safe
|
||||||
int group = best_group(idx);
|
int node = best_node(idx);
|
||||||
|
|
||||||
if (group == -1)
|
if (node == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Early exit if the needed API are not available at runtime
|
// Early exit if the needed API are not available at runtime
|
||||||
HMODULE k32 = GetModuleHandle("Kernel32.dll");
|
HMODULE k32 = GetModuleHandle("Kernel32.dll");
|
||||||
auto fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx");
|
auto fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx");
|
||||||
auto fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity");
|
auto fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity");
|
||||||
|
auto fun4 = (fun4_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMask2");
|
||||||
|
auto fun5 = (fun5_t)(void(*)())GetProcAddress(k32, "GetMaximumProcessorGroupCount");
|
||||||
|
|
||||||
if (!fun2 || !fun3)
|
if (!fun2 || !fun3)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GROUP_AFFINITY affinity;
|
if (!fun4 || !fun5)
|
||||||
if (fun2(group, &affinity))
|
{
|
||||||
fun3(GetCurrentThread(), &affinity, nullptr);
|
GROUP_AFFINITY affinity;
|
||||||
|
if (fun2(node, &affinity)) // GetNumaNodeProcessorMaskEx
|
||||||
|
fun3(GetCurrentThread(), &affinity, nullptr); // SetThreadGroupAffinity
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If a numa node has more than one processor group, we assume they are
|
||||||
|
// sized equal and we spread threads evenly across the groups.
|
||||||
|
USHORT elements, returnedElements;
|
||||||
|
elements = fun5(); // GetMaximumProcessorGroupCount
|
||||||
|
GROUP_AFFINITY *affinity = (GROUP_AFFINITY*)malloc(elements * sizeof(GROUP_AFFINITY));
|
||||||
|
if (fun4(node, affinity, elements, &returnedElements)) // GetNumaNodeProcessorMask2
|
||||||
|
fun3(GetCurrentThread(), &affinity[idx % returnedElements], nullptr); // SetThreadGroupAffinity
|
||||||
|
free(affinity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+50
-14
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -108,19 +108,30 @@ static inline const union { uint32_t i; char c[4]; } Le = { 0x01020304 };
|
|||||||
static inline const bool IsLittleEndian = (Le.c[0] == 4);
|
static inline const bool IsLittleEndian = (Le.c[0] == 4);
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
// RunningAverage : a class to calculate a running average of a series of values.
|
||||||
class ValueListInserter {
|
// For efficiency, all computations are done with integers.
|
||||||
public:
|
class RunningAverage {
|
||||||
ValueListInserter(T* v, std::size_t& s) :
|
public:
|
||||||
values(v),
|
|
||||||
size(&s)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(const T& value) { values[(*size)++] = value; }
|
// Reset the running average to rational value p / q
|
||||||
private:
|
void set(int64_t p, int64_t q)
|
||||||
T* values;
|
{ average = p * PERIOD * RESOLUTION / q; }
|
||||||
std::size_t* size;
|
|
||||||
|
// Update average with value v
|
||||||
|
void update(int64_t v)
|
||||||
|
{ average = RESOLUTION * v + (PERIOD - 1) * average / PERIOD; }
|
||||||
|
|
||||||
|
// Test if average is strictly greater than rational a / b
|
||||||
|
bool is_greater(int64_t a, int64_t b) const
|
||||||
|
{ return b * average > a * (PERIOD * RESOLUTION); }
|
||||||
|
|
||||||
|
int64_t value() const
|
||||||
|
{ return average / (PERIOD * RESOLUTION); }
|
||||||
|
|
||||||
|
private :
|
||||||
|
static constexpr int64_t PERIOD = 4096;
|
||||||
|
static constexpr int64_t RESOLUTION = 1024;
|
||||||
|
int64_t average;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, std::size_t MaxSize>
|
template <typename T, std::size_t MaxSize>
|
||||||
@@ -136,7 +147,6 @@ public:
|
|||||||
const T& operator[](std::size_t index) const { return values_[index]; }
|
const T& operator[](std::size_t index) const { return values_[index]; }
|
||||||
const T* begin() const { return values_; }
|
const T* begin() const { return values_; }
|
||||||
const T* end() const { return values_ + size_; }
|
const T* end() const { return values_ + size_; }
|
||||||
operator ValueListInserter<T>() { return ValueListInserter(values_, size_); }
|
|
||||||
|
|
||||||
void swap(ValueList& other) {
|
void swap(ValueList& other) {
|
||||||
const std::size_t maxSize = std::max(size_, other.size_);
|
const std::size_t maxSize = std::max(size_, other.size_);
|
||||||
@@ -365,6 +375,32 @@ public:
|
|||||||
|
|
||||||
extern SynchronizedRegionLogger sync_region_cout;
|
extern SynchronizedRegionLogger sync_region_cout;
|
||||||
|
|
||||||
|
/// sigmoid(t, x0, y0, C, P, Q) implements a sigmoid-like function using only integers,
|
||||||
|
/// with the following properties:
|
||||||
|
///
|
||||||
|
/// - sigmoid is centered in (x0, y0)
|
||||||
|
/// - sigmoid has amplitude [-P/Q , P/Q] instead of [-1 , +1]
|
||||||
|
/// - limit is (y0 - P/Q) when t tends to -infinity
|
||||||
|
/// - limit is (y0 + P/Q) when t tends to +infinity
|
||||||
|
/// - the slope can be adjusted using C > 0, smaller C giving a steeper sigmoid
|
||||||
|
/// - the slope of the sigmoid when t = x0 is P/(Q*C)
|
||||||
|
/// - sigmoid is increasing with t when P > 0 and Q > 0
|
||||||
|
/// - to get a decreasing sigmoid, change sign of P
|
||||||
|
/// - mean value of the sigmoid is y0
|
||||||
|
///
|
||||||
|
/// Use <https://www.desmos.com/calculator/jhh83sqq92> to draw the sigmoid
|
||||||
|
|
||||||
|
inline int64_t sigmoid(int64_t t, int64_t x0,
|
||||||
|
int64_t y0,
|
||||||
|
int64_t C,
|
||||||
|
int64_t P,
|
||||||
|
int64_t Q)
|
||||||
|
{
|
||||||
|
assert(C > 0);
|
||||||
|
assert(Q != 0);
|
||||||
|
return y0 + P * (t-x0) / (Q * (std::abs(t-x0) + C)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// xorshift64star Pseudo-Random Number Generator
|
/// xorshift64star Pseudo-Random Number Generator
|
||||||
/// This class is based on original code written and dedicated
|
/// This class is based on original code written and dedicated
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -52,9 +52,9 @@ namespace {
|
|||||||
constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
|
constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
|
||||||
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
|
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
|
||||||
|
|
||||||
const Bitboard emptySquares = Type == QUIETS || Type == QUIET_CHECKS ? target : ~pos.pieces();
|
const Bitboard emptySquares = ~pos.pieces();
|
||||||
const Bitboard enemies = Type == EVASIONS ? pos.checkers()
|
const Bitboard enemies = Type == EVASIONS ? pos.checkers()
|
||||||
: Type == CAPTURES ? target : pos.pieces(Them);
|
: pos.pieces(Them);
|
||||||
|
|
||||||
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
|
Bitboard pawnsOn7 = pos.pieces(Us, PAWN) & TRank7BB;
|
||||||
Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
|
Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+55
-18
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "bitboard.h"
|
||||||
#include "movepick.h"
|
#include "movepick.h"
|
||||||
|
|
||||||
namespace Stockfish {
|
namespace Stockfish {
|
||||||
@@ -56,11 +57,14 @@ namespace {
|
|||||||
/// ordering is at the current node.
|
/// ordering is at the current node.
|
||||||
|
|
||||||
/// MovePicker constructor for the main search
|
/// MovePicker constructor for the main search
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, const LowPlyHistory* lp,
|
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
|
||||||
const CapturePieceToHistory* cph, const PieceToHistory** ch, Move cm, const Move* killers, int pl)
|
const CapturePieceToHistory* cph,
|
||||||
: pos(p), mainHistory(mh), lowPlyHistory(lp), captureHistory(cph), continuationHistory(ch),
|
const PieceToHistory** ch,
|
||||||
ttMove(ttm), refutations{{killers[0], 0}, {killers[1], 0}, {cm, 0}}, depth(d), ply(pl) {
|
Move cm,
|
||||||
|
const Move* killers)
|
||||||
|
: pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch),
|
||||||
|
ttMove(ttm), refutations{{killers[0], 0}, {killers[1], 0}, {cm, 0}}, depth(d)
|
||||||
|
{
|
||||||
assert(d > 0);
|
assert(d > 0);
|
||||||
|
|
||||||
stage = (pos.checkers() ? EVASION_TT : MAIN_TT) +
|
stage = (pos.checkers() ? EVASION_TT : MAIN_TT) +
|
||||||
@@ -69,9 +73,11 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHist
|
|||||||
|
|
||||||
/// MovePicker constructor for quiescence search
|
/// MovePicker constructor for quiescence search
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
|
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
|
||||||
const CapturePieceToHistory* cph, const PieceToHistory** ch, Square rs)
|
const CapturePieceToHistory* cph,
|
||||||
: pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch), ttMove(ttm), recaptureSquare(rs), depth(d) {
|
const PieceToHistory** ch,
|
||||||
|
Square rs)
|
||||||
|
: pos(p), mainHistory(mh), captureHistory(cph), continuationHistory(ch), ttMove(ttm), recaptureSquare(rs), depth(d)
|
||||||
|
{
|
||||||
assert(d <= 0);
|
assert(d <= 0);
|
||||||
|
|
||||||
stage = (pos.checkers() ? EVASION_TT : QSEARCH_TT) +
|
stage = (pos.checkers() ? EVASION_TT : QSEARCH_TT) +
|
||||||
@@ -82,9 +88,9 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHist
|
|||||||
|
|
||||||
/// MovePicker constructor for ProbCut: we generate captures with SEE greater
|
/// MovePicker constructor for ProbCut: we generate captures with SEE greater
|
||||||
/// than or equal to the given threshold.
|
/// than or equal to the given threshold.
|
||||||
MovePicker::MovePicker(const Position& p, Move ttm, Value th, const CapturePieceToHistory* cph)
|
MovePicker::MovePicker(const Position& p, Move ttm, Value th, Depth d, const CapturePieceToHistory* cph)
|
||||||
: pos(p), captureHistory(cph), ttMove(ttm), threshold(th) {
|
: pos(p), captureHistory(cph), ttMove(ttm), threshold(th), depth(d)
|
||||||
|
{
|
||||||
assert(!pos.checkers());
|
assert(!pos.checkers());
|
||||||
|
|
||||||
stage = PROBCUT_TT + !(ttm && pos.capture(ttm)
|
stage = PROBCUT_TT + !(ttm && pos.capture(ttm)
|
||||||
@@ -100,10 +106,35 @@ void MovePicker::score() {
|
|||||||
|
|
||||||
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
|
static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
|
||||||
|
|
||||||
|
Bitboard threatened, threatenedByPawn, threatenedByMinor, threatenedByRook;
|
||||||
|
if constexpr (Type == QUIETS)
|
||||||
|
{
|
||||||
|
Color us = pos.side_to_move();
|
||||||
|
// squares threatened by pawns
|
||||||
|
threatenedByPawn = pos.attacks_by<PAWN>(~us);
|
||||||
|
// squares threatened by minors or pawns
|
||||||
|
threatenedByMinor = pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
|
||||||
|
// squares threatened by rooks, minors or pawns
|
||||||
|
threatenedByRook = pos.attacks_by<ROOK>(~us) | threatenedByMinor;
|
||||||
|
|
||||||
|
// pieces threatened by pieces of lesser material value
|
||||||
|
threatened = (pos.pieces(us, QUEEN) & threatenedByRook)
|
||||||
|
| (pos.pieces(us, ROOK) & threatenedByMinor)
|
||||||
|
| (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Silence unused variable warnings
|
||||||
|
(void) threatened;
|
||||||
|
(void) threatenedByPawn;
|
||||||
|
(void) threatenedByMinor;
|
||||||
|
(void) threatenedByRook;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& m : *this)
|
for (auto& m : *this)
|
||||||
if constexpr (Type == CAPTURES)
|
if constexpr (Type == CAPTURES)
|
||||||
m.value = int(PieceValue[MG][pos.piece_on(to_sq(m))]) * 6
|
m.value = 6 * int(PieceValue[MG][pos.piece_on(to_sq(m))])
|
||||||
+ (*captureHistory)[pos.moved_piece(m)][to_sq(m)][type_of(pos.piece_on(to_sq(m)))];
|
+ (*captureHistory)[pos.moved_piece(m)][to_sq(m)][type_of(pos.piece_on(to_sq(m)))];
|
||||||
|
|
||||||
else if constexpr (Type == QUIETS)
|
else if constexpr (Type == QUIETS)
|
||||||
m.value = (*mainHistory)[pos.side_to_move()][from_to(m)]
|
m.value = (*mainHistory)[pos.side_to_move()][from_to(m)]
|
||||||
@@ -111,7 +142,12 @@ void MovePicker::score() {
|
|||||||
+ (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)]
|
+ (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)]
|
||||||
+ (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)]
|
+ (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)]
|
||||||
+ (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)]
|
+ (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)]
|
||||||
+ (ply < MAX_LPH ? 6 * (*lowPlyHistory)[ply][from_to(m)] : 0);
|
+ (threatened & from_sq(m) ?
|
||||||
|
(type_of(pos.moved_piece(m)) == QUEEN && !(to_sq(m) & threatenedByRook) ? 50000
|
||||||
|
: type_of(pos.moved_piece(m)) == ROOK && !(to_sq(m) & threatenedByMinor) ? 25000
|
||||||
|
: !(to_sq(m) & threatenedByPawn) ? 15000
|
||||||
|
: 0)
|
||||||
|
: 0);
|
||||||
|
|
||||||
else // Type == EVASIONS
|
else // Type == EVASIONS
|
||||||
{
|
{
|
||||||
@@ -165,11 +201,12 @@ top:
|
|||||||
endMoves = generate<CAPTURES>(pos, cur);
|
endMoves = generate<CAPTURES>(pos, cur);
|
||||||
|
|
||||||
score<CAPTURES>();
|
score<CAPTURES>();
|
||||||
|
partial_insertion_sort(cur, endMoves, -3000 * depth);
|
||||||
++stage;
|
++stage;
|
||||||
goto top;
|
goto top;
|
||||||
|
|
||||||
case GOOD_CAPTURE:
|
case GOOD_CAPTURE:
|
||||||
if (select<Best>([&](){
|
if (select<Next>([&](){
|
||||||
return pos.see_ge(*cur, Value(-69 * cur->value / 1024)) ?
|
return pos.see_ge(*cur, Value(-69 * cur->value / 1024)) ?
|
||||||
// Move losing capture to endBadCaptures to be tried later
|
// Move losing capture to endBadCaptures to be tried later
|
||||||
true : (*endBadCaptures++ = *cur, false); }))
|
true : (*endBadCaptures++ = *cur, false); }))
|
||||||
@@ -237,10 +274,10 @@ top:
|
|||||||
return select<Best>([](){ return true; });
|
return select<Best>([](){ return true; });
|
||||||
|
|
||||||
case PROBCUT:
|
case PROBCUT:
|
||||||
return select<Best>([&](){ return pos.see_ge(*cur, threshold); });
|
return select<Next>([&](){ return pos.see_ge(*cur, threshold); });
|
||||||
|
|
||||||
case QCAPTURE:
|
case QCAPTURE:
|
||||||
if (select<Best>([&](){ return depth > DEPTH_QS_RECAPTURES
|
if (select<Next>([&](){ return depth > DEPTH_QS_RECAPTURES
|
||||||
|| to_sq(*cur) == recaptureSquare; }))
|
|| to_sq(*cur) == recaptureSquare; }))
|
||||||
return *(cur - 1);
|
return *(cur - 1);
|
||||||
|
|
||||||
|
|||||||
+8
-18
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -86,13 +86,7 @@ enum StatsType { NoCaptures, Captures };
|
|||||||
/// unsuccessful during the current search, and is used for reduction and move
|
/// unsuccessful during the current search, and is used for reduction and move
|
||||||
/// ordering decisions. It uses 2 tables (one for each color) indexed by
|
/// ordering decisions. It uses 2 tables (one for each color) indexed by
|
||||||
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
|
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
|
||||||
typedef Stats<int16_t, 13365, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory;
|
typedef Stats<int16_t, 14365, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory;
|
||||||
|
|
||||||
/// At higher depths LowPlyHistory records successful quiet moves near the root
|
|
||||||
/// and quiet moves which are/were in the PV (ttPv). It is cleared with each new
|
|
||||||
/// search and filled during iterative deepening.
|
|
||||||
constexpr int MAX_LPH = 4;
|
|
||||||
typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB) * int(SQUARE_NB)> LowPlyHistory;
|
|
||||||
|
|
||||||
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
|
/// CounterMoveHistory stores counter moves indexed by [piece][to] of the previous
|
||||||
/// move, see www.chessprogramming.org/Countermove_Heuristic
|
/// move, see www.chessprogramming.org/Countermove_Heuristic
|
||||||
@@ -123,18 +117,16 @@ class MovePicker {
|
|||||||
public:
|
public:
|
||||||
MovePicker(const MovePicker&) = delete;
|
MovePicker(const MovePicker&) = delete;
|
||||||
MovePicker& operator=(const MovePicker&) = delete;
|
MovePicker& operator=(const MovePicker&) = delete;
|
||||||
MovePicker(const Position&, Move, Value, const CapturePieceToHistory*);
|
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
||||||
|
const CapturePieceToHistory*,
|
||||||
|
const PieceToHistory**,
|
||||||
|
Move,
|
||||||
|
const Move*);
|
||||||
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
||||||
const CapturePieceToHistory*,
|
const CapturePieceToHistory*,
|
||||||
const PieceToHistory**,
|
const PieceToHistory**,
|
||||||
Square);
|
Square);
|
||||||
MovePicker(const Position&, Move, Depth, const ButterflyHistory*,
|
MovePicker(const Position&, Move, Value, Depth, const CapturePieceToHistory*);
|
||||||
const LowPlyHistory*,
|
|
||||||
const CapturePieceToHistory*,
|
|
||||||
const PieceToHistory**,
|
|
||||||
Move,
|
|
||||||
const Move*,
|
|
||||||
int);
|
|
||||||
Move next_move(bool skipQuiets = false);
|
Move next_move(bool skipQuiets = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -145,7 +137,6 @@ private:
|
|||||||
|
|
||||||
const Position& pos;
|
const Position& pos;
|
||||||
const ButterflyHistory* mainHistory;
|
const ButterflyHistory* mainHistory;
|
||||||
const LowPlyHistory* lowPlyHistory;
|
|
||||||
const CapturePieceToHistory* captureHistory;
|
const CapturePieceToHistory* captureHistory;
|
||||||
const PieceToHistory** continuationHistory;
|
const PieceToHistory** continuationHistory;
|
||||||
Move ttMove;
|
Move ttMove;
|
||||||
@@ -154,7 +145,6 @@ private:
|
|||||||
Square recaptureSquare;
|
Square recaptureSquare;
|
||||||
Value threshold;
|
Value threshold;
|
||||||
Depth depth;
|
Depth depth;
|
||||||
int ply;
|
|
||||||
ExtMove moves[MAX_MOVES];
|
ExtMove moves[MAX_MOVES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+15
-32
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -109,7 +109,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
{
|
{
|
||||||
write_little_endian<std::uint32_t>(stream, Version);
|
write_little_endian<std::uint32_t>(stream, Version);
|
||||||
write_little_endian<std::uint32_t>(stream, hashValue);
|
write_little_endian<std::uint32_t>(stream, hashValue);
|
||||||
write_little_endian<std::uint32_t>(stream, desc.size());
|
write_little_endian<std::uint32_t>(stream, (std::uint32_t)desc.size());
|
||||||
stream.write(&desc[0], desc.size());
|
stream.write(&desc[0], desc.size());
|
||||||
return !stream.fail();
|
return !stream.fail();
|
||||||
}
|
}
|
||||||
@@ -143,39 +143,29 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
// overaligning stack variables with alignas() doesn't work correctly.
|
// overaligning stack variables with alignas() doesn't work correctly.
|
||||||
|
|
||||||
constexpr uint64_t alignment = CacheLineSize;
|
constexpr uint64_t alignment = CacheLineSize;
|
||||||
|
int delta = 10 - pos.non_pawn_material() / 1515;
|
||||||
|
|
||||||
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
||||||
TransformedFeatureType transformedFeaturesUnaligned[
|
TransformedFeatureType transformedFeaturesUnaligned[
|
||||||
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
||||||
char bufferUnaligned[Network::BufferSize + alignment];
|
|
||||||
|
|
||||||
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
||||||
auto* buffer = align_ptr_up<alignment>(&bufferUnaligned[0]);
|
|
||||||
#else
|
#else
|
||||||
alignas(alignment)
|
alignas(alignment)
|
||||||
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
||||||
alignas(alignment) char buffer[Network::BufferSize];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT_ALIGNED(transformedFeatures, alignment);
|
ASSERT_ALIGNED(transformedFeatures, alignment);
|
||||||
ASSERT_ALIGNED(buffer, alignment);
|
|
||||||
|
|
||||||
const std::size_t bucket = (pos.count<ALL_PIECES>() - 1) / 4;
|
const int bucket = (pos.count<ALL_PIECES>() - 1) / 4;
|
||||||
const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
|
const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
|
||||||
const auto output = network[bucket]->propagate(transformedFeatures, buffer);
|
const auto positional = network[bucket]->propagate(transformedFeatures);
|
||||||
|
|
||||||
int materialist = psqt;
|
// Give more value to positional evaluation when adjusted flag is set
|
||||||
int positional = output[0];
|
if (adjusted)
|
||||||
|
return static_cast<Value>(((128 - delta) * psqt + (128 + delta) * positional) / 128 / OutputScale);
|
||||||
int delta_npm = abs(pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK));
|
else
|
||||||
int entertainment = (adjusted && delta_npm <= BishopValueMg - KnightValueMg ? 7 : 0);
|
return static_cast<Value>((psqt + positional) / OutputScale);
|
||||||
|
|
||||||
int A = 128 - entertainment;
|
|
||||||
int B = 128 + entertainment;
|
|
||||||
|
|
||||||
int sum = (A * materialist + B * positional) / 128;
|
|
||||||
|
|
||||||
return static_cast<Value>( sum / OutputScale );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NnueEvalTrace {
|
struct NnueEvalTrace {
|
||||||
@@ -196,27 +186,20 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
#if defined(ALIGNAS_ON_STACK_VARIABLES_BROKEN)
|
||||||
TransformedFeatureType transformedFeaturesUnaligned[
|
TransformedFeatureType transformedFeaturesUnaligned[
|
||||||
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
FeatureTransformer::BufferSize + alignment / sizeof(TransformedFeatureType)];
|
||||||
char bufferUnaligned[Network::BufferSize + alignment];
|
|
||||||
|
|
||||||
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
auto* transformedFeatures = align_ptr_up<alignment>(&transformedFeaturesUnaligned[0]);
|
||||||
auto* buffer = align_ptr_up<alignment>(&bufferUnaligned[0]);
|
|
||||||
#else
|
#else
|
||||||
alignas(alignment)
|
alignas(alignment)
|
||||||
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
TransformedFeatureType transformedFeatures[FeatureTransformer::BufferSize];
|
||||||
alignas(alignment) char buffer[Network::BufferSize];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT_ALIGNED(transformedFeatures, alignment);
|
ASSERT_ALIGNED(transformedFeatures, alignment);
|
||||||
ASSERT_ALIGNED(buffer, alignment);
|
|
||||||
|
|
||||||
NnueEvalTrace t{};
|
NnueEvalTrace t{};
|
||||||
t.correctBucket = (pos.count<ALL_PIECES>() - 1) / 4;
|
t.correctBucket = (pos.count<ALL_PIECES>() - 1) / 4;
|
||||||
for (std::size_t bucket = 0; bucket < LayerStacks; ++bucket) {
|
for (IndexType bucket = 0; bucket < LayerStacks; ++bucket) {
|
||||||
const auto psqt = featureTransformer->transform(pos, transformedFeatures, bucket);
|
const auto materialist = featureTransformer->transform(pos, transformedFeatures, bucket);
|
||||||
const auto output = network[bucket]->propagate(transformedFeatures, buffer);
|
const auto positional = network[bucket]->propagate(transformedFeatures);
|
||||||
|
|
||||||
int materialist = psqt;
|
|
||||||
int positional = output[0];
|
|
||||||
|
|
||||||
t.psqt[bucket] = static_cast<Value>( materialist / OutputScale );
|
t.psqt[bucket] = static_cast<Value>( materialist / OutputScale );
|
||||||
t.positional[bucket] = static_cast<Value>( positional / OutputScale );
|
t.positional[bucket] = static_cast<Value>( positional / OutputScale );
|
||||||
@@ -239,7 +222,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
{
|
{
|
||||||
buffer[1] = '0' + cp / 10000; cp %= 10000;
|
buffer[1] = '0' + cp / 10000; cp %= 10000;
|
||||||
buffer[2] = '0' + cp / 1000; cp %= 1000;
|
buffer[2] = '0' + cp / 1000; cp %= 1000;
|
||||||
buffer[3] = '0' + cp / 100; cp %= 100;
|
buffer[3] = '0' + cp / 100;
|
||||||
buffer[4] = ' ';
|
buffer[4] = ' ';
|
||||||
}
|
}
|
||||||
else if (cp >= 1000)
|
else if (cp >= 1000)
|
||||||
@@ -396,7 +379,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
actualFilename = filename.value();
|
actualFilename = filename.value();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (eval_file_loaded != EvalFileDefaultName)
|
if (currentEvalFileName != EvalFileDefaultName)
|
||||||
{
|
{
|
||||||
msg = "Failed to export a net. A non-embedded net can only be saved if the filename is specified";
|
msg = "Failed to export a net. A non-embedded net can only be saved if the filename is specified";
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,7 +39,7 @@ namespace Stockfish::Eval::NNUE::Features {
|
|||||||
void HalfKAv2_hm::append_active_indices(
|
void HalfKAv2_hm::append_active_indices(
|
||||||
const Position& pos,
|
const Position& pos,
|
||||||
Color perspective,
|
Color perspective,
|
||||||
ValueListInserter<IndexType> active
|
IndexList& active
|
||||||
) {
|
) {
|
||||||
Square ksq = pos.square<KING>(perspective);
|
Square ksq = pos.square<KING>(perspective);
|
||||||
Bitboard bb = pos.pieces();
|
Bitboard bb = pos.pieces();
|
||||||
@@ -55,22 +55,20 @@ namespace Stockfish::Eval::NNUE::Features {
|
|||||||
|
|
||||||
void HalfKAv2_hm::append_changed_indices(
|
void HalfKAv2_hm::append_changed_indices(
|
||||||
Square ksq,
|
Square ksq,
|
||||||
StateInfo* st,
|
const DirtyPiece& dp,
|
||||||
Color perspective,
|
Color perspective,
|
||||||
ValueListInserter<IndexType> removed,
|
IndexList& removed,
|
||||||
ValueListInserter<IndexType> added
|
IndexList& added
|
||||||
) {
|
) {
|
||||||
const auto& dp = st->dirtyPiece;
|
|
||||||
for (int i = 0; i < dp.dirty_num; ++i) {
|
for (int i = 0; i < dp.dirty_num; ++i) {
|
||||||
Piece pc = dp.piece[i];
|
|
||||||
if (dp.from[i] != SQ_NONE)
|
if (dp.from[i] != SQ_NONE)
|
||||||
removed.push_back(make_index(perspective, dp.from[i], pc, ksq));
|
removed.push_back(make_index(perspective, dp.from[i], dp.piece[i], ksq));
|
||||||
if (dp.to[i] != SQ_NONE)
|
if (dp.to[i] != SQ_NONE)
|
||||||
added.push_back(make_index(perspective, dp.to[i], pc, ksq));
|
added.push_back(make_index(perspective, dp.to[i], dp.piece[i], ksq));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int HalfKAv2_hm::update_cost(StateInfo* st) {
|
int HalfKAv2_hm::update_cost(const StateInfo* st) {
|
||||||
return st->dirtyPiece.dirty_num;
|
return st->dirtyPiece.dirty_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +76,7 @@ namespace Stockfish::Eval::NNUE::Features {
|
|||||||
return pos.count<ALL_PIECES>();
|
return pos.count<ALL_PIECES>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HalfKAv2_hm::requires_refresh(StateInfo* st, Color perspective) {
|
bool HalfKAv2_hm::requires_refresh(const StateInfo* st, Color perspective) {
|
||||||
return st->dirtyPiece.piece[0] == make_piece(perspective, KING);
|
return st->dirtyPiece.piece[0] == make_piece(perspective, KING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -50,7 +50,7 @@ namespace Stockfish::Eval::NNUE::Features {
|
|||||||
PS_W_QUEEN = 8 * SQUARE_NB,
|
PS_W_QUEEN = 8 * SQUARE_NB,
|
||||||
PS_B_QUEEN = 9 * SQUARE_NB,
|
PS_B_QUEEN = 9 * SQUARE_NB,
|
||||||
PS_KING = 10 * SQUARE_NB,
|
PS_KING = 10 * SQUARE_NB,
|
||||||
PS_NB = 11 * SQUARE_NB
|
PS_NB = 11 * SQUARE_NB
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr IndexType PieceSquareIndex[COLOR_NB][PIECE_NB] = {
|
static constexpr IndexType PieceSquareIndex[COLOR_NB][PIECE_NB] = {
|
||||||
@@ -85,36 +85,38 @@ namespace Stockfish::Eval::NNUE::Features {
|
|||||||
-1, -1, -1, -1, 23, 22, 21, 20,
|
-1, -1, -1, -1, 23, 22, 21, 20,
|
||||||
-1, -1, -1, -1, 19, 18, 17, 16,
|
-1, -1, -1, -1, 19, 18, 17, 16,
|
||||||
-1, -1, -1, -1, 15, 14, 13, 12,
|
-1, -1, -1, -1, 15, 14, 13, 12,
|
||||||
-1, -1, -1, -1, 11, 10, 9, 8,
|
-1, -1, -1, -1, 11, 10, 9, 8,
|
||||||
-1, -1, -1, -1, 7, 6, 5, 4,
|
-1, -1, -1, -1, 7, 6, 5, 4,
|
||||||
-1, -1, -1, -1, 3, 2, 1, 0
|
-1, -1, -1, -1, 3, 2, 1, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Maximum number of simultaneously active features.
|
// Maximum number of simultaneously active features.
|
||||||
static constexpr IndexType MaxActiveDimensions = 32;
|
static constexpr IndexType MaxActiveDimensions = 32;
|
||||||
|
using IndexList = ValueList<IndexType, MaxActiveDimensions>;
|
||||||
|
|
||||||
// Get a list of indices for active features
|
// Get a list of indices for active features
|
||||||
static void append_active_indices(
|
static void append_active_indices(
|
||||||
const Position& pos,
|
const Position& pos,
|
||||||
Color perspective,
|
Color perspective,
|
||||||
ValueListInserter<IndexType> active);
|
IndexList& active);
|
||||||
|
|
||||||
// Get a list of indices for recently changed features
|
// Get a list of indices for recently changed features
|
||||||
static void append_changed_indices(
|
static void append_changed_indices(
|
||||||
Square ksq,
|
Square ksq,
|
||||||
StateInfo* st,
|
const DirtyPiece& dp,
|
||||||
Color perspective,
|
Color perspective,
|
||||||
ValueListInserter<IndexType> removed,
|
IndexList& removed,
|
||||||
ValueListInserter<IndexType> added);
|
IndexList& added
|
||||||
|
);
|
||||||
|
|
||||||
// Returns the cost of updating one perspective, the most costly one.
|
// Returns the cost of updating one perspective, the most costly one.
|
||||||
// Assumes no refresh needed.
|
// Assumes no refresh needed.
|
||||||
static int update_cost(StateInfo* st);
|
static int update_cost(const StateInfo* st);
|
||||||
static int refresh_cost(const Position& pos);
|
static int refresh_cost(const Position& pos);
|
||||||
|
|
||||||
// Returns whether the change stored in this StateInfo means that
|
// Returns whether the change stored in this StateInfo means that
|
||||||
// a full accumulator refresh is required.
|
// a full accumulator refresh is required.
|
||||||
static bool requires_refresh(StateInfo* st, Color perspective);
|
static bool requires_refresh(const StateInfo* st, Color perspective);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Stockfish::Eval::NNUE::Features
|
} // namespace Stockfish::Eval::NNUE::Features
|
||||||
|
|||||||
+440
-534
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,50 +26,41 @@
|
|||||||
namespace Stockfish::Eval::NNUE::Layers {
|
namespace Stockfish::Eval::NNUE::Layers {
|
||||||
|
|
||||||
// Clipped ReLU
|
// Clipped ReLU
|
||||||
template <typename PreviousLayer>
|
template <IndexType InDims>
|
||||||
class ClippedReLU {
|
class ClippedReLU {
|
||||||
public:
|
public:
|
||||||
// Input/output type
|
// Input/output type
|
||||||
using InputType = typename PreviousLayer::OutputType;
|
using InputType = std::int32_t;
|
||||||
using OutputType = std::uint8_t;
|
using OutputType = std::uint8_t;
|
||||||
static_assert(std::is_same<InputType, std::int32_t>::value, "");
|
|
||||||
|
|
||||||
// Number of input/output dimensions
|
// Number of input/output dimensions
|
||||||
static constexpr IndexType InputDimensions =
|
static constexpr IndexType InputDimensions = InDims;
|
||||||
PreviousLayer::OutputDimensions;
|
|
||||||
static constexpr IndexType OutputDimensions = InputDimensions;
|
static constexpr IndexType OutputDimensions = InputDimensions;
|
||||||
|
static constexpr IndexType PaddedOutputDimensions =
|
||||||
|
ceil_to_multiple<IndexType>(OutputDimensions, 32);
|
||||||
|
|
||||||
// Size of forward propagation buffer used in this layer
|
using OutputBuffer = OutputType[PaddedOutputDimensions];
|
||||||
static constexpr std::size_t SelfBufferSize =
|
|
||||||
ceil_to_multiple(OutputDimensions * sizeof(OutputType), CacheLineSize);
|
|
||||||
|
|
||||||
// Size of the forward propagation buffer used from the input layer to this layer
|
|
||||||
static constexpr std::size_t BufferSize =
|
|
||||||
PreviousLayer::BufferSize + SelfBufferSize;
|
|
||||||
|
|
||||||
// Hash value embedded in the evaluation file
|
// Hash value embedded in the evaluation file
|
||||||
static constexpr std::uint32_t get_hash_value() {
|
static constexpr std::uint32_t get_hash_value(std::uint32_t prevHash) {
|
||||||
std::uint32_t hashValue = 0x538D24C7u;
|
std::uint32_t hashValue = 0x538D24C7u;
|
||||||
hashValue += PreviousLayer::get_hash_value();
|
hashValue += prevHash;
|
||||||
return hashValue;
|
return hashValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read network parameters
|
// Read network parameters
|
||||||
bool read_parameters(std::istream& stream) {
|
bool read_parameters(std::istream&) {
|
||||||
return previousLayer.read_parameters(stream);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write network parameters
|
// Write network parameters
|
||||||
bool write_parameters(std::ostream& stream) const {
|
bool write_parameters(std::ostream&) const {
|
||||||
return previousLayer.write_parameters(stream);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward propagation
|
// Forward propagation
|
||||||
const OutputType* propagate(
|
const OutputType* propagate(
|
||||||
const TransformedFeatureType* transformedFeatures, char* buffer) const {
|
const InputType* input, OutputType* output) const {
|
||||||
const auto input = previousLayer.propagate(
|
|
||||||
transformedFeatures, buffer + SelfBufferSize);
|
|
||||||
const auto output = reinterpret_cast<OutputType*>(buffer);
|
|
||||||
|
|
||||||
#if defined(USE_AVX2)
|
#if defined(USE_AVX2)
|
||||||
if constexpr (InputDimensions % SimdWidth == 0) {
|
if constexpr (InputDimensions % SimdWidth == 0) {
|
||||||
@@ -179,11 +170,9 @@ namespace Stockfish::Eval::NNUE::Layers {
|
|||||||
output[i] = static_cast<OutputType>(
|
output[i] = static_cast<OutputType>(
|
||||||
std::max(0, std::min(127, input[i] >> WeightScaleBits)));
|
std::max(0, std::min(127, input[i] >> WeightScaleBits)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
PreviousLayer previousLayer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Stockfish::Eval::NNUE::Layers
|
} // namespace Stockfish::Eval::NNUE::Layers
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Stockfish is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// NNUE evaluation function layer InputSlice definition
|
|
||||||
|
|
||||||
#ifndef NNUE_LAYERS_INPUT_SLICE_H_INCLUDED
|
|
||||||
#define NNUE_LAYERS_INPUT_SLICE_H_INCLUDED
|
|
||||||
|
|
||||||
#include "../nnue_common.h"
|
|
||||||
|
|
||||||
namespace Stockfish::Eval::NNUE::Layers {
|
|
||||||
|
|
||||||
// Input layer
|
|
||||||
template <IndexType OutDims, IndexType Offset = 0>
|
|
||||||
class InputSlice {
|
|
||||||
public:
|
|
||||||
// Need to maintain alignment
|
|
||||||
static_assert(Offset % MaxSimdWidth == 0, "");
|
|
||||||
|
|
||||||
// Output type
|
|
||||||
using OutputType = TransformedFeatureType;
|
|
||||||
|
|
||||||
// Output dimensionality
|
|
||||||
static constexpr IndexType OutputDimensions = OutDims;
|
|
||||||
|
|
||||||
// Size of forward propagation buffer used from the input layer to this layer
|
|
||||||
static constexpr std::size_t BufferSize = 0;
|
|
||||||
|
|
||||||
// Hash value embedded in the evaluation file
|
|
||||||
static constexpr std::uint32_t get_hash_value() {
|
|
||||||
std::uint32_t hashValue = 0xEC42E90Du;
|
|
||||||
hashValue ^= OutputDimensions ^ (Offset << 10);
|
|
||||||
return hashValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read network parameters
|
|
||||||
bool read_parameters(std::istream& /*stream*/) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write network parameters
|
|
||||||
bool write_parameters(std::ostream& /*stream*/) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Forward propagation
|
|
||||||
const OutputType* propagate(
|
|
||||||
const TransformedFeatureType* transformedFeatures,
|
|
||||||
char* /*buffer*/) const {
|
|
||||||
return transformedFeatures + Offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Stockfish::Eval::NNUE::Layers
|
|
||||||
|
|
||||||
#endif // #ifndef NNUE_LAYERS_INPUT_SLICE_H_INCLUDED
|
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Stockfish is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Definition of layer ClippedReLU of NNUE evaluation function
|
||||||
|
|
||||||
|
#ifndef NNUE_LAYERS_SQR_CLIPPED_RELU_H_INCLUDED
|
||||||
|
#define NNUE_LAYERS_SQR_CLIPPED_RELU_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../nnue_common.h"
|
||||||
|
|
||||||
|
namespace Stockfish::Eval::NNUE::Layers {
|
||||||
|
|
||||||
|
// Clipped ReLU
|
||||||
|
template <IndexType InDims>
|
||||||
|
class SqrClippedReLU {
|
||||||
|
public:
|
||||||
|
// Input/output type
|
||||||
|
using InputType = std::int32_t;
|
||||||
|
using OutputType = std::uint8_t;
|
||||||
|
|
||||||
|
// Number of input/output dimensions
|
||||||
|
static constexpr IndexType InputDimensions = InDims;
|
||||||
|
static constexpr IndexType OutputDimensions = InputDimensions;
|
||||||
|
static constexpr IndexType PaddedOutputDimensions =
|
||||||
|
ceil_to_multiple<IndexType>(OutputDimensions, 32);
|
||||||
|
|
||||||
|
using OutputBuffer = OutputType[PaddedOutputDimensions];
|
||||||
|
|
||||||
|
// Hash value embedded in the evaluation file
|
||||||
|
static constexpr std::uint32_t get_hash_value(std::uint32_t prevHash) {
|
||||||
|
std::uint32_t hashValue = 0x538D24C7u;
|
||||||
|
hashValue += prevHash;
|
||||||
|
return hashValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read network parameters
|
||||||
|
bool read_parameters(std::istream&) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write network parameters
|
||||||
|
bool write_parameters(std::ostream&) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward propagation
|
||||||
|
const OutputType* propagate(
|
||||||
|
const InputType* input, OutputType* output) const {
|
||||||
|
|
||||||
|
#if defined(USE_SSE2)
|
||||||
|
constexpr IndexType NumChunks = InputDimensions / 16;
|
||||||
|
|
||||||
|
#ifdef USE_SSE41
|
||||||
|
const __m128i Zero = _mm_setzero_si128();
|
||||||
|
#else
|
||||||
|
const __m128i k0x80s = _mm_set1_epi8(-128);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(WeightScaleBits == 6);
|
||||||
|
const auto in = reinterpret_cast<const __m128i*>(input);
|
||||||
|
const auto out = reinterpret_cast<__m128i*>(output);
|
||||||
|
for (IndexType i = 0; i < NumChunks; ++i) {
|
||||||
|
__m128i words0 = _mm_packs_epi32(
|
||||||
|
_mm_load_si128(&in[i * 4 + 0]),
|
||||||
|
_mm_load_si128(&in[i * 4 + 1]));
|
||||||
|
__m128i words1 = _mm_packs_epi32(
|
||||||
|
_mm_load_si128(&in[i * 4 + 2]),
|
||||||
|
_mm_load_si128(&in[i * 4 + 3]));
|
||||||
|
|
||||||
|
// Not sure if
|
||||||
|
words0 = _mm_srli_epi16(_mm_mulhi_epi16(words0, words0), 3);
|
||||||
|
words1 = _mm_srli_epi16(_mm_mulhi_epi16(words1, words1), 3);
|
||||||
|
|
||||||
|
const __m128i packedbytes = _mm_packs_epi16(words0, words1);
|
||||||
|
|
||||||
|
_mm_store_si128(&out[i],
|
||||||
|
|
||||||
|
#ifdef USE_SSE41
|
||||||
|
_mm_max_epi8(packedbytes, Zero)
|
||||||
|
#else
|
||||||
|
_mm_subs_epi8(_mm_adds_epi8(packedbytes, k0x80s), k0x80s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
constexpr IndexType Start = NumChunks * 16;
|
||||||
|
|
||||||
|
#else
|
||||||
|
constexpr IndexType Start = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (IndexType i = Start; i < InputDimensions; ++i) {
|
||||||
|
output[i] = static_cast<OutputType>(
|
||||||
|
// realy should be /127 but we need to make it fast
|
||||||
|
// needs to be accounted for in the trainer
|
||||||
|
std::max(0ll, std::min(127ll, (((long long)input[i] * input[i]) >> (2 * WeightScaleBits)) / 128)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Stockfish::Eval::NNUE::Layers
|
||||||
|
|
||||||
|
#endif // NNUE_LAYERS_SQR_CLIPPED_RELU_H_INCLUDED
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,39 +21,117 @@
|
|||||||
#ifndef NNUE_ARCHITECTURE_H_INCLUDED
|
#ifndef NNUE_ARCHITECTURE_H_INCLUDED
|
||||||
#define NNUE_ARCHITECTURE_H_INCLUDED
|
#define NNUE_ARCHITECTURE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "nnue_common.h"
|
#include "nnue_common.h"
|
||||||
|
|
||||||
#include "features/half_ka_v2_hm.h"
|
#include "features/half_ka_v2_hm.h"
|
||||||
|
|
||||||
#include "layers/input_slice.h"
|
|
||||||
#include "layers/affine_transform.h"
|
#include "layers/affine_transform.h"
|
||||||
#include "layers/clipped_relu.h"
|
#include "layers/clipped_relu.h"
|
||||||
|
#include "layers/sqr_clipped_relu.h"
|
||||||
|
|
||||||
|
#include "../misc.h"
|
||||||
|
|
||||||
namespace Stockfish::Eval::NNUE {
|
namespace Stockfish::Eval::NNUE {
|
||||||
|
|
||||||
// Input features used in evaluation function
|
// Input features used in evaluation function
|
||||||
using FeatureSet = Features::HalfKAv2_hm;
|
using FeatureSet = Features::HalfKAv2_hm;
|
||||||
|
|
||||||
// Number of input feature dimensions after conversion
|
// Number of input feature dimensions after conversion
|
||||||
constexpr IndexType TransformedFeatureDimensions = 1024;
|
constexpr IndexType TransformedFeatureDimensions = 1024;
|
||||||
constexpr IndexType PSQTBuckets = 8;
|
constexpr IndexType PSQTBuckets = 8;
|
||||||
constexpr IndexType LayerStacks = 8;
|
constexpr IndexType LayerStacks = 8;
|
||||||
|
|
||||||
namespace Layers {
|
struct Network
|
||||||
|
{
|
||||||
|
static constexpr int FC_0_OUTPUTS = 15;
|
||||||
|
static constexpr int FC_1_OUTPUTS = 32;
|
||||||
|
|
||||||
// Define network structure
|
Layers::AffineTransform<TransformedFeatureDimensions, FC_0_OUTPUTS + 1> fc_0;
|
||||||
using InputLayer = InputSlice<TransformedFeatureDimensions * 2>;
|
Layers::SqrClippedReLU<FC_0_OUTPUTS + 1> ac_sqr_0;
|
||||||
using HiddenLayer1 = ClippedReLU<AffineTransform<InputLayer, 8>>;
|
Layers::ClippedReLU<FC_0_OUTPUTS + 1> ac_0;
|
||||||
using HiddenLayer2 = ClippedReLU<AffineTransform<HiddenLayer1, 32>>;
|
Layers::AffineTransform<FC_0_OUTPUTS * 2, FC_1_OUTPUTS> fc_1;
|
||||||
using OutputLayer = AffineTransform<HiddenLayer2, 1>;
|
Layers::ClippedReLU<FC_1_OUTPUTS> ac_1;
|
||||||
|
Layers::AffineTransform<FC_1_OUTPUTS, 1> fc_2;
|
||||||
|
|
||||||
} // namespace Layers
|
// Hash value embedded in the evaluation file
|
||||||
|
static constexpr std::uint32_t get_hash_value() {
|
||||||
|
// input slice hash
|
||||||
|
std::uint32_t hashValue = 0xEC42E90Du;
|
||||||
|
hashValue ^= TransformedFeatureDimensions * 2;
|
||||||
|
|
||||||
using Network = Layers::OutputLayer;
|
hashValue = decltype(fc_0)::get_hash_value(hashValue);
|
||||||
|
hashValue = decltype(ac_0)::get_hash_value(hashValue);
|
||||||
|
hashValue = decltype(fc_1)::get_hash_value(hashValue);
|
||||||
|
hashValue = decltype(ac_1)::get_hash_value(hashValue);
|
||||||
|
hashValue = decltype(fc_2)::get_hash_value(hashValue);
|
||||||
|
|
||||||
static_assert(TransformedFeatureDimensions % MaxSimdWidth == 0, "");
|
return hashValue;
|
||||||
static_assert(Network::OutputDimensions == 1, "");
|
}
|
||||||
static_assert(std::is_same<Network::OutputType, std::int32_t>::value, "");
|
|
||||||
|
// Read network parameters
|
||||||
|
bool read_parameters(std::istream& stream) {
|
||||||
|
if (!fc_0.read_parameters(stream)) return false;
|
||||||
|
if (!ac_0.read_parameters(stream)) return false;
|
||||||
|
if (!fc_1.read_parameters(stream)) return false;
|
||||||
|
if (!ac_1.read_parameters(stream)) return false;
|
||||||
|
if (!fc_2.read_parameters(stream)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read network parameters
|
||||||
|
bool write_parameters(std::ostream& stream) const {
|
||||||
|
if (!fc_0.write_parameters(stream)) return false;
|
||||||
|
if (!ac_0.write_parameters(stream)) return false;
|
||||||
|
if (!fc_1.write_parameters(stream)) return false;
|
||||||
|
if (!ac_1.write_parameters(stream)) return false;
|
||||||
|
if (!fc_2.write_parameters(stream)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int32_t propagate(const TransformedFeatureType* transformedFeatures)
|
||||||
|
{
|
||||||
|
struct alignas(CacheLineSize) Buffer
|
||||||
|
{
|
||||||
|
alignas(CacheLineSize) decltype(fc_0)::OutputBuffer fc_0_out;
|
||||||
|
alignas(CacheLineSize) decltype(ac_sqr_0)::OutputType ac_sqr_0_out[ceil_to_multiple<IndexType>(FC_0_OUTPUTS * 2, 32)];
|
||||||
|
alignas(CacheLineSize) decltype(ac_0)::OutputBuffer ac_0_out;
|
||||||
|
alignas(CacheLineSize) decltype(fc_1)::OutputBuffer fc_1_out;
|
||||||
|
alignas(CacheLineSize) decltype(ac_1)::OutputBuffer ac_1_out;
|
||||||
|
alignas(CacheLineSize) decltype(fc_2)::OutputBuffer fc_2_out;
|
||||||
|
|
||||||
|
Buffer()
|
||||||
|
{
|
||||||
|
std::memset(this, 0, sizeof(*this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__clang__) && (__APPLE__)
|
||||||
|
// workaround for a bug reported with xcode 12
|
||||||
|
static thread_local auto tlsBuffer = std::make_unique<Buffer>();
|
||||||
|
// Access TLS only once, cache result.
|
||||||
|
Buffer& buffer = *tlsBuffer;
|
||||||
|
#else
|
||||||
|
alignas(CacheLineSize) static thread_local Buffer buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fc_0.propagate(transformedFeatures, buffer.fc_0_out);
|
||||||
|
ac_sqr_0.propagate(buffer.fc_0_out, buffer.ac_sqr_0_out);
|
||||||
|
ac_0.propagate(buffer.fc_0_out, buffer.ac_0_out);
|
||||||
|
std::memcpy(buffer.ac_sqr_0_out + FC_0_OUTPUTS, buffer.ac_0_out, FC_0_OUTPUTS * sizeof(decltype(ac_0)::OutputType));
|
||||||
|
fc_1.propagate(buffer.ac_sqr_0_out, buffer.fc_1_out);
|
||||||
|
ac_1.propagate(buffer.fc_1_out, buffer.ac_1_out);
|
||||||
|
fc_2.propagate(buffer.ac_1_out, buffer.fc_2_out);
|
||||||
|
|
||||||
|
// buffer.fc_0_out[FC_0_OUTPUTS] is such that 1.0 is equal to 127*(1<<WeightScaleBits) in quantized form
|
||||||
|
// but we want 1.0 to be equal to 600*OutputScale
|
||||||
|
std::int32_t fwdOut = int(buffer.fc_0_out[FC_0_OUTPUTS]) * (600*OutputScale) / (127*(1<<WeightScaleBits));
|
||||||
|
std::int32_t outputValue = buffer.fc_2_out[0] + fwdOut;
|
||||||
|
|
||||||
|
return outputValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Stockfish::Eval::NNUE
|
} // namespace Stockfish::Eval::NNUE
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -111,7 +111,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
|
|
||||||
// write_little_endian() is our utility to write an integer (signed or unsigned, any size)
|
// write_little_endian() is our utility to write an integer (signed or unsigned, any size)
|
||||||
// to a stream in little-endian order. We swap the byte order before the write if
|
// to a stream in little-endian order. We swap the byte order before the write if
|
||||||
// necessary to always write in little endian order, independantly of the byte
|
// necessary to always write in little endian order, independently of the byte
|
||||||
// ordering of the compiling machine.
|
// ordering of the compiling machine.
|
||||||
template <typename IntType>
|
template <typename IntType>
|
||||||
inline void write_little_endian(std::ostream& stream, IntType value) {
|
inline void write_little_endian(std::ostream& stream, IntType value) {
|
||||||
@@ -129,11 +129,11 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
{
|
{
|
||||||
for (; i + 1 < sizeof(IntType); ++i)
|
for (; i + 1 < sizeof(IntType); ++i)
|
||||||
{
|
{
|
||||||
u[i] = v;
|
u[i] = (std::uint8_t)v;
|
||||||
v >>= 8;
|
v >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u[i] = v;
|
u[i] = (std::uint8_t)v;
|
||||||
|
|
||||||
stream.write(reinterpret_cast<char*>(u), sizeof(IntType));
|
stream.write(reinterpret_cast<char*>(u), sizeof(IntType));
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-129
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -50,12 +50,22 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#define vec_store(a,b) _mm512_store_si512(a,b)
|
#define vec_store(a,b) _mm512_store_si512(a,b)
|
||||||
#define vec_add_16(a,b) _mm512_add_epi16(a,b)
|
#define vec_add_16(a,b) _mm512_add_epi16(a,b)
|
||||||
#define vec_sub_16(a,b) _mm512_sub_epi16(a,b)
|
#define vec_sub_16(a,b) _mm512_sub_epi16(a,b)
|
||||||
|
#define vec_mul_16(a,b) _mm512_mullo_epi16(a,b)
|
||||||
|
#define vec_zero() _mm512_setzero_epi32()
|
||||||
|
#define vec_set_16(a) _mm512_set1_epi16(a)
|
||||||
|
#define vec_max_16(a,b) _mm512_max_epi16(a,b)
|
||||||
|
#define vec_min_16(a,b) _mm512_min_epi16(a,b)
|
||||||
|
inline vec_t vec_msb_pack_16(vec_t a, vec_t b){
|
||||||
|
vec_t compacted = _mm512_packs_epi16(_mm512_srli_epi16(a,7),_mm512_srli_epi16(b,7));
|
||||||
|
return _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 2, 4, 6, 1, 3, 5, 7), compacted);
|
||||||
|
}
|
||||||
#define vec_load_psqt(a) _mm256_load_si256(a)
|
#define vec_load_psqt(a) _mm256_load_si256(a)
|
||||||
#define vec_store_psqt(a,b) _mm256_store_si256(a,b)
|
#define vec_store_psqt(a,b) _mm256_store_si256(a,b)
|
||||||
#define vec_add_psqt_32(a,b) _mm256_add_epi32(a,b)
|
#define vec_add_psqt_32(a,b) _mm256_add_epi32(a,b)
|
||||||
#define vec_sub_psqt_32(a,b) _mm256_sub_epi32(a,b)
|
#define vec_sub_psqt_32(a,b) _mm256_sub_epi32(a,b)
|
||||||
#define vec_zero_psqt() _mm256_setzero_si256()
|
#define vec_zero_psqt() _mm256_setzero_si256()
|
||||||
#define NumRegistersSIMD 32
|
#define NumRegistersSIMD 32
|
||||||
|
#define MaxChunkSize 64
|
||||||
|
|
||||||
#elif USE_AVX2
|
#elif USE_AVX2
|
||||||
typedef __m256i vec_t;
|
typedef __m256i vec_t;
|
||||||
@@ -64,12 +74,22 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#define vec_store(a,b) _mm256_store_si256(a,b)
|
#define vec_store(a,b) _mm256_store_si256(a,b)
|
||||||
#define vec_add_16(a,b) _mm256_add_epi16(a,b)
|
#define vec_add_16(a,b) _mm256_add_epi16(a,b)
|
||||||
#define vec_sub_16(a,b) _mm256_sub_epi16(a,b)
|
#define vec_sub_16(a,b) _mm256_sub_epi16(a,b)
|
||||||
|
#define vec_mul_16(a,b) _mm256_mullo_epi16(a,b)
|
||||||
|
#define vec_zero() _mm256_setzero_si256()
|
||||||
|
#define vec_set_16(a) _mm256_set1_epi16(a)
|
||||||
|
#define vec_max_16(a,b) _mm256_max_epi16(a,b)
|
||||||
|
#define vec_min_16(a,b) _mm256_min_epi16(a,b)
|
||||||
|
inline vec_t vec_msb_pack_16(vec_t a, vec_t b){
|
||||||
|
vec_t compacted = _mm256_packs_epi16(_mm256_srli_epi16(a,7), _mm256_srli_epi16(b,7));
|
||||||
|
return _mm256_permute4x64_epi64(compacted, 0b11011000);
|
||||||
|
}
|
||||||
#define vec_load_psqt(a) _mm256_load_si256(a)
|
#define vec_load_psqt(a) _mm256_load_si256(a)
|
||||||
#define vec_store_psqt(a,b) _mm256_store_si256(a,b)
|
#define vec_store_psqt(a,b) _mm256_store_si256(a,b)
|
||||||
#define vec_add_psqt_32(a,b) _mm256_add_epi32(a,b)
|
#define vec_add_psqt_32(a,b) _mm256_add_epi32(a,b)
|
||||||
#define vec_sub_psqt_32(a,b) _mm256_sub_epi32(a,b)
|
#define vec_sub_psqt_32(a,b) _mm256_sub_epi32(a,b)
|
||||||
#define vec_zero_psqt() _mm256_setzero_si256()
|
#define vec_zero_psqt() _mm256_setzero_si256()
|
||||||
#define NumRegistersSIMD 16
|
#define NumRegistersSIMD 16
|
||||||
|
#define MaxChunkSize 32
|
||||||
|
|
||||||
#elif USE_SSE2
|
#elif USE_SSE2
|
||||||
typedef __m128i vec_t;
|
typedef __m128i vec_t;
|
||||||
@@ -78,12 +98,19 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#define vec_store(a,b) *(a)=(b)
|
#define vec_store(a,b) *(a)=(b)
|
||||||
#define vec_add_16(a,b) _mm_add_epi16(a,b)
|
#define vec_add_16(a,b) _mm_add_epi16(a,b)
|
||||||
#define vec_sub_16(a,b) _mm_sub_epi16(a,b)
|
#define vec_sub_16(a,b) _mm_sub_epi16(a,b)
|
||||||
|
#define vec_mul_16(a,b) _mm_mullo_epi16(a,b)
|
||||||
|
#define vec_zero() _mm_setzero_si128()
|
||||||
|
#define vec_set_16(a) _mm_set1_epi16(a)
|
||||||
|
#define vec_max_16(a,b) _mm_max_epi16(a,b)
|
||||||
|
#define vec_min_16(a,b) _mm_min_epi16(a,b)
|
||||||
|
#define vec_msb_pack_16(a,b) _mm_packs_epi16(_mm_srli_epi16(a,7),_mm_srli_epi16(b,7))
|
||||||
#define vec_load_psqt(a) (*(a))
|
#define vec_load_psqt(a) (*(a))
|
||||||
#define vec_store_psqt(a,b) *(a)=(b)
|
#define vec_store_psqt(a,b) *(a)=(b)
|
||||||
#define vec_add_psqt_32(a,b) _mm_add_epi32(a,b)
|
#define vec_add_psqt_32(a,b) _mm_add_epi32(a,b)
|
||||||
#define vec_sub_psqt_32(a,b) _mm_sub_epi32(a,b)
|
#define vec_sub_psqt_32(a,b) _mm_sub_epi32(a,b)
|
||||||
#define vec_zero_psqt() _mm_setzero_si128()
|
#define vec_zero_psqt() _mm_setzero_si128()
|
||||||
#define NumRegistersSIMD (Is64Bit ? 16 : 8)
|
#define NumRegistersSIMD (Is64Bit ? 16 : 8)
|
||||||
|
#define MaxChunkSize 16
|
||||||
|
|
||||||
#elif USE_MMX
|
#elif USE_MMX
|
||||||
typedef __m64 vec_t;
|
typedef __m64 vec_t;
|
||||||
@@ -92,12 +119,26 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#define vec_store(a,b) *(a)=(b)
|
#define vec_store(a,b) *(a)=(b)
|
||||||
#define vec_add_16(a,b) _mm_add_pi16(a,b)
|
#define vec_add_16(a,b) _mm_add_pi16(a,b)
|
||||||
#define vec_sub_16(a,b) _mm_sub_pi16(a,b)
|
#define vec_sub_16(a,b) _mm_sub_pi16(a,b)
|
||||||
|
#define vec_mul_16(a,b) _mm_mullo_pi16(a,b)
|
||||||
|
#define vec_zero() _mm_setzero_si64()
|
||||||
|
#define vec_set_16(a) _mm_set1_pi16(a)
|
||||||
|
inline vec_t vec_max_16(vec_t a,vec_t b){
|
||||||
|
vec_t comparison = _mm_cmpgt_pi16(a,b);
|
||||||
|
return _mm_or_si64(_mm_and_si64(comparison, a), _mm_andnot_si64(comparison, b));
|
||||||
|
}
|
||||||
|
inline vec_t vec_min_16(vec_t a,vec_t b){
|
||||||
|
vec_t comparison = _mm_cmpgt_pi16(a,b);
|
||||||
|
return _mm_or_si64(_mm_and_si64(comparison, b), _mm_andnot_si64(comparison, a));
|
||||||
|
}
|
||||||
|
#define vec_msb_pack_16(a,b) _mm_packs_pi16(_mm_srli_pi16(a,7),_mm_srli_pi16(b,7))
|
||||||
#define vec_load_psqt(a) (*(a))
|
#define vec_load_psqt(a) (*(a))
|
||||||
#define vec_store_psqt(a,b) *(a)=(b)
|
#define vec_store_psqt(a,b) *(a)=(b)
|
||||||
#define vec_add_psqt_32(a,b) _mm_add_pi32(a,b)
|
#define vec_add_psqt_32(a,b) _mm_add_pi32(a,b)
|
||||||
#define vec_sub_psqt_32(a,b) _mm_sub_pi32(a,b)
|
#define vec_sub_psqt_32(a,b) _mm_sub_pi32(a,b)
|
||||||
#define vec_zero_psqt() _mm_setzero_si64()
|
#define vec_zero_psqt() _mm_setzero_si64()
|
||||||
|
#define vec_cleanup() _mm_empty()
|
||||||
#define NumRegistersSIMD 8
|
#define NumRegistersSIMD 8
|
||||||
|
#define MaxChunkSize 8
|
||||||
|
|
||||||
#elif USE_NEON
|
#elif USE_NEON
|
||||||
typedef int16x8_t vec_t;
|
typedef int16x8_t vec_t;
|
||||||
@@ -106,12 +147,24 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
#define vec_store(a,b) *(a)=(b)
|
#define vec_store(a,b) *(a)=(b)
|
||||||
#define vec_add_16(a,b) vaddq_s16(a,b)
|
#define vec_add_16(a,b) vaddq_s16(a,b)
|
||||||
#define vec_sub_16(a,b) vsubq_s16(a,b)
|
#define vec_sub_16(a,b) vsubq_s16(a,b)
|
||||||
|
#define vec_mul_16(a,b) vmulq_s16(a,b)
|
||||||
|
#define vec_zero() vec_t{0}
|
||||||
|
#define vec_set_16(a) vdupq_n_s16(a)
|
||||||
|
#define vec_max_16(a,b) vmaxq_s16(a,b)
|
||||||
|
#define vec_min_16(a,b) vminq_s16(a,b)
|
||||||
|
inline vec_t vec_msb_pack_16(vec_t a, vec_t b){
|
||||||
|
const int8x8_t shifta = vshrn_n_s16(a, 7);
|
||||||
|
const int8x8_t shiftb = vshrn_n_s16(b, 7);
|
||||||
|
const int8x16_t compacted = vcombine_s8(shifta,shiftb);
|
||||||
|
return *reinterpret_cast<const vec_t*> (&compacted);
|
||||||
|
}
|
||||||
#define vec_load_psqt(a) (*(a))
|
#define vec_load_psqt(a) (*(a))
|
||||||
#define vec_store_psqt(a,b) *(a)=(b)
|
#define vec_store_psqt(a,b) *(a)=(b)
|
||||||
#define vec_add_psqt_32(a,b) vaddq_s32(a,b)
|
#define vec_add_psqt_32(a,b) vaddq_s32(a,b)
|
||||||
#define vec_sub_psqt_32(a,b) vsubq_s32(a,b)
|
#define vec_sub_psqt_32(a,b) vsubq_s32(a,b)
|
||||||
#define vec_zero_psqt() psqt_vec_t{0}
|
#define vec_zero_psqt() psqt_vec_t{0}
|
||||||
#define NumRegistersSIMD 16
|
#define NumRegistersSIMD 16
|
||||||
|
#define MaxChunkSize 16
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#undef VECTOR
|
#undef VECTOR
|
||||||
@@ -126,8 +179,10 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
// We use __m* types as template arguments, which causes GCC to emit warnings
|
// We use __m* types as template arguments, which causes GCC to emit warnings
|
||||||
// about losing some attribute information. This is irrelevant to us as we
|
// about losing some attribute information. This is irrelevant to us as we
|
||||||
// only take their size, so the following pragma are harmless.
|
// only take their size, so the following pragma are harmless.
|
||||||
|
#if defined(__GNUC__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename SIMDRegisterType,
|
template <typename SIMDRegisterType,
|
||||||
typename LaneType,
|
typename LaneType,
|
||||||
@@ -159,9 +214,9 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
|
|
||||||
static constexpr int NumRegs = BestRegisterCount<vec_t, WeightType, TransformedFeatureDimensions, NumRegistersSIMD>();
|
static constexpr int NumRegs = BestRegisterCount<vec_t, WeightType, TransformedFeatureDimensions, NumRegistersSIMD>();
|
||||||
static constexpr int NumPsqtRegs = BestRegisterCount<psqt_vec_t, PSQTWeightType, PSQTBuckets, NumRegistersSIMD>();
|
static constexpr int NumPsqtRegs = BestRegisterCount<psqt_vec_t, PSQTWeightType, PSQTBuckets, NumRegistersSIMD>();
|
||||||
|
#if defined(__GNUC__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +241,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
|
|
||||||
// Number of input/output dimensions
|
// Number of input/output dimensions
|
||||||
static constexpr IndexType InputDimensions = FeatureSet::Dimensions;
|
static constexpr IndexType InputDimensions = FeatureSet::Dimensions;
|
||||||
static constexpr IndexType OutputDimensions = HalfDimensions * 2;
|
static constexpr IndexType OutputDimensions = HalfDimensions;
|
||||||
|
|
||||||
// Size of forward propagation buffer
|
// Size of forward propagation buffer
|
||||||
static constexpr std::size_t BufferSize =
|
static constexpr std::size_t BufferSize =
|
||||||
@@ -194,7 +249,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
|
|
||||||
// Hash value embedded in the evaluation file
|
// Hash value embedded in the evaluation file
|
||||||
static constexpr std::uint32_t get_hash_value() {
|
static constexpr std::uint32_t get_hash_value() {
|
||||||
return FeatureSet::HashValue ^ OutputDimensions;
|
return FeatureSet::HashValue ^ (OutputDimensions * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read network parameters
|
// Read network parameters
|
||||||
@@ -232,136 +287,55 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
) / 2;
|
) / 2;
|
||||||
|
|
||||||
|
|
||||||
#if defined(USE_AVX512)
|
|
||||||
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / (SimdWidth * 2);
|
|
||||||
static_assert(HalfDimensions % (SimdWidth * 2) == 0);
|
|
||||||
const __m512i Control = _mm512_setr_epi64(0, 2, 4, 6, 1, 3, 5, 7);
|
|
||||||
const __m512i Zero = _mm512_setzero_si512();
|
|
||||||
|
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
for (IndexType p = 0; p < 2; ++p)
|
||||||
{
|
{
|
||||||
const IndexType offset = HalfDimensions * p;
|
const IndexType offset = (HalfDimensions / 2) * p;
|
||||||
auto out = reinterpret_cast<__m512i*>(&output[offset]);
|
|
||||||
for (IndexType j = 0; j < NumChunks; ++j)
|
#if defined(VECTOR)
|
||||||
|
|
||||||
|
constexpr IndexType OutputChunkSize = MaxChunkSize;
|
||||||
|
static_assert((HalfDimensions / 2) % OutputChunkSize == 0);
|
||||||
|
constexpr IndexType NumOutputChunks = HalfDimensions / 2 / OutputChunkSize;
|
||||||
|
|
||||||
|
vec_t Zero = vec_zero();
|
||||||
|
vec_t One = vec_set_16(127);
|
||||||
|
|
||||||
|
const vec_t* in0 = reinterpret_cast<const vec_t*>(&(accumulation[perspectives[p]][0]));
|
||||||
|
const vec_t* in1 = reinterpret_cast<const vec_t*>(&(accumulation[perspectives[p]][HalfDimensions / 2]));
|
||||||
|
vec_t* out = reinterpret_cast< vec_t*>(output + offset);
|
||||||
|
|
||||||
|
for (IndexType j = 0; j < NumOutputChunks; j += 1)
|
||||||
{
|
{
|
||||||
__m512i sum0 = _mm512_load_si512(&reinterpret_cast<const __m512i*>
|
const vec_t sum0a = vec_max_16(vec_min_16(in0[j * 2 + 0], One), Zero);
|
||||||
(accumulation[perspectives[p]])[j * 2 + 0]);
|
const vec_t sum0b = vec_max_16(vec_min_16(in0[j * 2 + 1], One), Zero);
|
||||||
__m512i sum1 = _mm512_load_si512(&reinterpret_cast<const __m512i*>
|
const vec_t sum1a = vec_max_16(vec_min_16(in1[j * 2 + 0], One), Zero);
|
||||||
(accumulation[perspectives[p]])[j * 2 + 1]);
|
const vec_t sum1b = vec_max_16(vec_min_16(in1[j * 2 + 1], One), Zero);
|
||||||
|
|
||||||
_mm512_store_si512(&out[j], _mm512_permutexvar_epi64(Control,
|
const vec_t pa = vec_mul_16(sum0a, sum1a);
|
||||||
_mm512_max_epi8(_mm512_packs_epi16(sum0, sum1), Zero)));
|
const vec_t pb = vec_mul_16(sum0b, sum1b);
|
||||||
|
|
||||||
|
out[j] = vec_msb_pack_16(pa, pb);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return psqt;
|
|
||||||
|
|
||||||
#elif defined(USE_AVX2)
|
#else
|
||||||
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / SimdWidth;
|
for (IndexType j = 0; j < HalfDimensions / 2; ++j) {
|
||||||
constexpr int Control = 0b11011000;
|
BiasType sum0 = accumulation[static_cast<int>(perspectives[p])][j + 0];
|
||||||
const __m256i Zero = _mm256_setzero_si256();
|
BiasType sum1 = accumulation[static_cast<int>(perspectives[p])][j + HalfDimensions / 2];
|
||||||
|
sum0 = std::max<int>(0, std::min<int>(127, sum0));
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
sum1 = std::max<int>(0, std::min<int>(127, sum1));
|
||||||
{
|
output[offset + j] = static_cast<OutputType>(sum0 * sum1 / 128);
|
||||||
const IndexType offset = HalfDimensions * p;
|
|
||||||
auto out = reinterpret_cast<__m256i*>(&output[offset]);
|
|
||||||
for (IndexType j = 0; j < NumChunks; ++j)
|
|
||||||
{
|
|
||||||
__m256i sum0 = _mm256_load_si256(&reinterpret_cast<const __m256i*>
|
|
||||||
(accumulation[perspectives[p]])[j * 2 + 0]);
|
|
||||||
__m256i sum1 = _mm256_load_si256(&reinterpret_cast<const __m256i*>
|
|
||||||
(accumulation[perspectives[p]])[j * 2 + 1]);
|
|
||||||
|
|
||||||
_mm256_store_si256(&out[j], _mm256_permute4x64_epi64(
|
|
||||||
_mm256_max_epi8(_mm256_packs_epi16(sum0, sum1), Zero), Control));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(vec_cleanup)
|
||||||
|
vec_cleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
return psqt;
|
return psqt;
|
||||||
|
|
||||||
#elif defined(USE_SSE2)
|
|
||||||
|
|
||||||
#ifdef USE_SSE41
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / SimdWidth;
|
|
||||||
const __m128i Zero = _mm_setzero_si128();
|
|
||||||
#else
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / SimdWidth;
|
|
||||||
const __m128i k0x80s = _mm_set1_epi8(-128);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
|
||||||
{
|
|
||||||
const IndexType offset = HalfDimensions * p;
|
|
||||||
auto out = reinterpret_cast<__m128i*>(&output[offset]);
|
|
||||||
for (IndexType j = 0; j < NumChunks; ++j)
|
|
||||||
{
|
|
||||||
__m128i sum0 = _mm_load_si128(&reinterpret_cast<const __m128i*>
|
|
||||||
(accumulation[perspectives[p]])[j * 2 + 0]);
|
|
||||||
__m128i sum1 = _mm_load_si128(&reinterpret_cast<const __m128i*>
|
|
||||||
(accumulation[perspectives[p]])[j * 2 + 1]);
|
|
||||||
const __m128i packedbytes = _mm_packs_epi16(sum0, sum1);
|
|
||||||
|
|
||||||
#ifdef USE_SSE41
|
|
||||||
_mm_store_si128(&out[j], _mm_max_epi8(packedbytes, Zero));
|
|
||||||
#else
|
|
||||||
_mm_store_si128(&out[j], _mm_subs_epi8(_mm_adds_epi8(packedbytes, k0x80s), k0x80s));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return psqt;
|
|
||||||
|
|
||||||
#elif defined(USE_MMX)
|
|
||||||
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / SimdWidth;
|
|
||||||
const __m64 k0x80s = _mm_set1_pi8(-128);
|
|
||||||
|
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
|
||||||
{
|
|
||||||
const IndexType offset = HalfDimensions * p;
|
|
||||||
auto out = reinterpret_cast<__m64*>(&output[offset]);
|
|
||||||
for (IndexType j = 0; j < NumChunks; ++j)
|
|
||||||
{
|
|
||||||
__m64 sum0 = *(&reinterpret_cast<const __m64*>(accumulation[perspectives[p]])[j * 2 + 0]);
|
|
||||||
__m64 sum1 = *(&reinterpret_cast<const __m64*>(accumulation[perspectives[p]])[j * 2 + 1]);
|
|
||||||
const __m64 packedbytes = _mm_packs_pi16(sum0, sum1);
|
|
||||||
out[j] = _mm_subs_pi8(_mm_adds_pi8(packedbytes, k0x80s), k0x80s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_mm_empty();
|
|
||||||
return psqt;
|
|
||||||
|
|
||||||
#elif defined(USE_NEON)
|
|
||||||
|
|
||||||
constexpr IndexType NumChunks = HalfDimensions / (SimdWidth / 2);
|
|
||||||
const int8x8_t Zero = {0};
|
|
||||||
|
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
|
||||||
{
|
|
||||||
const IndexType offset = HalfDimensions * p;
|
|
||||||
const auto out = reinterpret_cast<int8x8_t*>(&output[offset]);
|
|
||||||
for (IndexType j = 0; j < NumChunks; ++j)
|
|
||||||
{
|
|
||||||
int16x8_t sum = reinterpret_cast<const int16x8_t*>(accumulation[perspectives[p]])[j];
|
|
||||||
out[j] = vmax_s8(vqmovn_s16(sum), Zero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return psqt;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
for (IndexType p = 0; p < 2; ++p)
|
|
||||||
{
|
|
||||||
const IndexType offset = HalfDimensions * p;
|
|
||||||
for (IndexType j = 0; j < HalfDimensions; ++j)
|
|
||||||
{
|
|
||||||
BiasType sum = accumulation[perspectives[p]][j];
|
|
||||||
output[offset + j] = static_cast<OutputType>(std::max<int>(0, std::min<int>(127, sum)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return psqt;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end of function transform()
|
} // end of function transform()
|
||||||
|
|
||||||
|
|
||||||
@@ -373,7 +347,6 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
// That might depend on the feature set and generally relies on the
|
// That might depend on the feature set and generally relies on the
|
||||||
// feature set's update cost calculation to be correct and never
|
// feature set's update cost calculation to be correct and never
|
||||||
// allow updates with more added/removed features than MaxActiveDimensions.
|
// allow updates with more added/removed features than MaxActiveDimensions.
|
||||||
using IndexList = ValueList<IndexType, FeatureSet::MaxActiveDimensions>;
|
|
||||||
|
|
||||||
#ifdef VECTOR
|
#ifdef VECTOR
|
||||||
// Gcc-10.2 unnecessarily spills AVX2 registers if this array
|
// Gcc-10.2 unnecessarily spills AVX2 registers if this array
|
||||||
@@ -407,12 +380,12 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
|
|
||||||
// Gather all features to be updated.
|
// Gather all features to be updated.
|
||||||
const Square ksq = pos.square<KING>(perspective);
|
const Square ksq = pos.square<KING>(perspective);
|
||||||
IndexList removed[2], added[2];
|
FeatureSet::IndexList removed[2], added[2];
|
||||||
FeatureSet::append_changed_indices(
|
FeatureSet::append_changed_indices(
|
||||||
ksq, next, perspective, removed[0], added[0]);
|
ksq, next->dirtyPiece, perspective, removed[0], added[0]);
|
||||||
for (StateInfo *st2 = pos.state(); st2 != next; st2 = st2->previous)
|
for (StateInfo *st2 = pos.state(); st2 != next; st2 = st2->previous)
|
||||||
FeatureSet::append_changed_indices(
|
FeatureSet::append_changed_indices(
|
||||||
ksq, st2, perspective, removed[1], added[1]);
|
ksq, st2->dirtyPiece, perspective, removed[1], added[1]);
|
||||||
|
|
||||||
// Mark the accumulators as computed.
|
// Mark the accumulators as computed.
|
||||||
next->accumulator.computed[perspective] = true;
|
next->accumulator.computed[perspective] = true;
|
||||||
@@ -537,7 +510,7 @@ namespace Stockfish::Eval::NNUE {
|
|||||||
// Refresh the accumulator
|
// Refresh the accumulator
|
||||||
auto& accumulator = pos.state()->accumulator;
|
auto& accumulator = pos.state()->accumulator;
|
||||||
accumulator.computed[perspective] = true;
|
accumulator.computed[perspective] = true;
|
||||||
IndexList active;
|
FeatureSet::IndexList active;
|
||||||
FeatureSet::append_active_indices(pos, perspective, active);
|
FeatureSet::append_active_indices(pos, perspective, active);
|
||||||
|
|
||||||
#ifdef VECTOR
|
#ifdef VECTOR
|
||||||
|
|||||||
+20
-20
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -32,30 +32,30 @@ namespace {
|
|||||||
#define S(mg, eg) make_score(mg, eg)
|
#define S(mg, eg) make_score(mg, eg)
|
||||||
|
|
||||||
// Pawn penalties
|
// Pawn penalties
|
||||||
constexpr Score Backward = S( 9, 22);
|
constexpr Score Backward = S( 6, 19);
|
||||||
constexpr Score Doubled = S(13, 51);
|
constexpr Score Doubled = S(11, 51);
|
||||||
constexpr Score DoubledEarly = S(20, 7);
|
constexpr Score DoubledEarly = S(17, 7);
|
||||||
constexpr Score Isolated = S( 3, 15);
|
constexpr Score Isolated = S( 1, 20);
|
||||||
constexpr Score WeakLever = S( 4, 58);
|
constexpr Score WeakLever = S( 2, 57);
|
||||||
constexpr Score WeakUnopposed = S(13, 24);
|
constexpr Score WeakUnopposed = S(15, 18);
|
||||||
|
|
||||||
// Bonus for blocked pawns at 5th or 6th rank
|
// Bonus for blocked pawns at 5th or 6th rank
|
||||||
constexpr Score BlockedPawn[2] = { S(-17, -6), S(-9, 2) };
|
constexpr Score BlockedPawn[2] = { S(-19, -8), S(-7, 3) };
|
||||||
|
|
||||||
constexpr Score BlockedStorm[RANK_NB] = {
|
constexpr Score BlockedStorm[RANK_NB] = {
|
||||||
S(0, 0), S(0, 0), S(75, 78), S(-8, 16), S(-6, 10), S(-6, 6), S(0, 2)
|
S(0, 0), S(0, 0), S(64, 75), S(-3, 14), S(-12, 19), S(-7, 4), S(-10, 5)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Connected pawn bonus
|
// Connected pawn bonus
|
||||||
constexpr int Connected[RANK_NB] = { 0, 5, 7, 11, 23, 48, 87 };
|
constexpr int Connected[RANK_NB] = { 0, 3, 7, 7, 15, 54, 86 };
|
||||||
|
|
||||||
// Strength of pawn shelter for our king by [distance from edge][rank].
|
// Strength of pawn shelter for our king by [distance from edge][rank].
|
||||||
// RANK_1 = 0 is used for files where we have no pawn, or pawn is behind our king.
|
// RANK_1 = 0 is used for files where we have no pawn, or pawn is behind our king.
|
||||||
constexpr Value ShelterStrength[int(FILE_NB) / 2][RANK_NB] = {
|
constexpr Value ShelterStrength[int(FILE_NB) / 2][RANK_NB] = {
|
||||||
{ V( -5), V( 82), V( 92), V( 54), V( 36), V( 22), V( 28) },
|
{ V(-2), V(85), V(95), V(53), V(39), V(23), V(25) },
|
||||||
{ V(-44), V( 63), V( 33), V(-50), V(-30), V(-12), V( -62) },
|
{ V(-55), V(64), V(32), V(-55), V(-30), V(-11), V(-61) },
|
||||||
{ V(-11), V( 77), V( 22), V( -6), V( 31), V( 8), V( -45) },
|
{ V(-11), V(75), V(19), V(-6), V(26), V(9), V(-47) },
|
||||||
{ V(-39), V(-12), V(-29), V(-50), V(-43), V(-68), V(-164) }
|
{ V(-41), V(-11), V(-27), V(-58), V(-42), V(-66), V(-163) }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Danger of enemy pawns moving toward our king by [distance from edge][rank].
|
// Danger of enemy pawns moving toward our king by [distance from edge][rank].
|
||||||
@@ -63,17 +63,17 @@ namespace {
|
|||||||
// is behind our king. Note that UnblockedStorm[0][1-2] accommodate opponent pawn
|
// is behind our king. Note that UnblockedStorm[0][1-2] accommodate opponent pawn
|
||||||
// on edge, likely blocked by our king.
|
// on edge, likely blocked by our king.
|
||||||
constexpr Value UnblockedStorm[int(FILE_NB) / 2][RANK_NB] = {
|
constexpr Value UnblockedStorm[int(FILE_NB) / 2][RANK_NB] = {
|
||||||
{ V( 87), V(-288), V(-168), V( 96), V( 47), V( 44), V( 46) },
|
{ V(94), V(-280), V(-170), V(90), V(59), V(47), V(53) },
|
||||||
{ V( 42), V( -25), V( 120), V( 45), V( 34), V( -9), V( 24) },
|
{ V(43), V(-17), V(128), V(39), V(26), V(-17), V(15) },
|
||||||
{ V( -8), V( 51), V( 167), V( 35), V( -4), V(-16), V(-12) },
|
{ V(-9), V(62), V(170), V(34), V(-5), V(-20), V(-11) },
|
||||||
{ V(-17), V( -13), V( 100), V( 4), V( 9), V(-16), V(-31) }
|
{ V(-27), V(-19), V(106), V(10), V(2), V(-13), V(-24) }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// KingOnFile[semi-open Us][semi-open Them] contains bonuses/penalties
|
// KingOnFile[semi-open Us][semi-open Them] contains bonuses/penalties
|
||||||
// for king when the king is on a semi-open or open file.
|
// for king when the king is on a semi-open or open file.
|
||||||
constexpr Score KingOnFile[2][2] = {{ S(-21,10), S(-7, 1) },
|
constexpr Score KingOnFile[2][2] = {{ S(-18,11), S(-6,-3) },
|
||||||
{ S( 0,-3), S( 9,-4) }};
|
{ S( 0, 0), S( 5,-4) }};
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
#undef V
|
#undef V
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -1019,9 +1019,9 @@ void Position::do_null_move(StateInfo& newSt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
st->key ^= Zobrist::side;
|
st->key ^= Zobrist::side;
|
||||||
|
++st->rule50;
|
||||||
prefetch(TT.first_entry(key()));
|
prefetch(TT.first_entry(key()));
|
||||||
|
|
||||||
++st->rule50;
|
|
||||||
st->pliesFromNull = 0;
|
st->pliesFromNull = 0;
|
||||||
|
|
||||||
sideToMove = ~sideToMove;
|
sideToMove = ~sideToMove;
|
||||||
|
|||||||
+18
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -123,6 +123,7 @@ public:
|
|||||||
Bitboard attackers_to(Square s) const;
|
Bitboard attackers_to(Square s) const;
|
||||||
Bitboard attackers_to(Square s, Bitboard occupied) const;
|
Bitboard attackers_to(Square s, Bitboard occupied) const;
|
||||||
Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
|
Bitboard slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const;
|
||||||
|
template<PieceType Pt> Bitboard attacks_by(Color c) const;
|
||||||
|
|
||||||
// Properties of moves
|
// Properties of moves
|
||||||
bool legal(Move m) const;
|
bool legal(Move m) const;
|
||||||
@@ -312,6 +313,22 @@ inline Bitboard Position::attackers_to(Square s) const {
|
|||||||
return attackers_to(s, pieces());
|
return attackers_to(s, pieces());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<PieceType Pt>
|
||||||
|
inline Bitboard Position::attacks_by(Color c) const {
|
||||||
|
|
||||||
|
if constexpr (Pt == PAWN)
|
||||||
|
return c == WHITE ? pawn_attacks_bb<WHITE>(pieces(WHITE, PAWN))
|
||||||
|
: pawn_attacks_bb<BLACK>(pieces(BLACK, PAWN));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bitboard threats = 0;
|
||||||
|
Bitboard attackers = pieces(c, Pt);
|
||||||
|
while (attackers)
|
||||||
|
threats |= attacks_bb<Pt>(pop_lsb(attackers), pieces());
|
||||||
|
return threats;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline Bitboard Position::checkers() const {
|
inline Bitboard Position::checkers() const {
|
||||||
return st->checkersBB;
|
return st->checkersBB;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+341
-295
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -55,6 +55,7 @@ struct Stack {
|
|||||||
bool ttPv;
|
bool ttPv;
|
||||||
bool ttHit;
|
bool ttHit;
|
||||||
int doubleExtensions;
|
int doubleExtensions;
|
||||||
|
int cutoffCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -74,6 +75,7 @@ struct RootMove {
|
|||||||
|
|
||||||
Value score = -VALUE_INFINITE;
|
Value score = -VALUE_INFINITE;
|
||||||
Value previousScore = -VALUE_INFINITE;
|
Value previousScore = -VALUE_INFINITE;
|
||||||
|
Value averageScore = -VALUE_INFINITE;
|
||||||
int selDepth = 0;
|
int selDepth = 0;
|
||||||
int tbRank = 0;
|
int tbRank = 0;
|
||||||
Value tbScore;
|
Value tbScore;
|
||||||
|
|||||||
+387
@@ -0,0 +1,387 @@
|
|||||||
|
/*
|
||||||
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Stockfish is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STOCKFISH_SIMD_H_INCLUDED
|
||||||
|
#define STOCKFISH_SIMD_H_INCLUDED
|
||||||
|
|
||||||
|
#if defined(USE_AVX2)
|
||||||
|
# include <immintrin.h>
|
||||||
|
|
||||||
|
#elif defined(USE_SSE41)
|
||||||
|
# include <smmintrin.h>
|
||||||
|
|
||||||
|
#elif defined(USE_SSSE3)
|
||||||
|
# include <tmmintrin.h>
|
||||||
|
|
||||||
|
#elif defined(USE_SSE2)
|
||||||
|
# include <emmintrin.h>
|
||||||
|
|
||||||
|
#elif defined(USE_MMX)
|
||||||
|
# include <mmintrin.h>
|
||||||
|
|
||||||
|
#elif defined(USE_NEON)
|
||||||
|
# include <arm_neon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The inline asm is only safe for GCC, where it is necessary to get good codegen.
|
||||||
|
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101693
|
||||||
|
// Clang does fine without it.
|
||||||
|
// Play around here: https://godbolt.org/z/7EWqrYq51
|
||||||
|
#if (defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER))
|
||||||
|
#define USE_INLINE_ASM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Use either the AVX512 or AVX-VNNI version of the VNNI instructions.
|
||||||
|
#if defined(USE_AVXVNNI)
|
||||||
|
#define VNNI_PREFIX "%{vex%} "
|
||||||
|
#else
|
||||||
|
#define VNNI_PREFIX ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Stockfish::Simd {
|
||||||
|
|
||||||
|
#if defined (USE_AVX512)
|
||||||
|
|
||||||
|
[[maybe_unused]] static int m512_hadd(__m512i sum, int bias) {
|
||||||
|
return _mm512_reduce_add_epi32(sum) + bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parameters:
|
||||||
|
sum0 = [zmm0.i128[0], zmm0.i128[1], zmm0.i128[2], zmm0.i128[3]]
|
||||||
|
sum1 = [zmm1.i128[0], zmm1.i128[1], zmm1.i128[2], zmm1.i128[3]]
|
||||||
|
sum2 = [zmm2.i128[0], zmm2.i128[1], zmm2.i128[2], zmm2.i128[3]]
|
||||||
|
sum3 = [zmm3.i128[0], zmm3.i128[1], zmm3.i128[2], zmm3.i128[3]]
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ret = [
|
||||||
|
reduce_add_epi32(zmm0.i128[0]), reduce_add_epi32(zmm1.i128[0]), reduce_add_epi32(zmm2.i128[0]), reduce_add_epi32(zmm3.i128[0]),
|
||||||
|
reduce_add_epi32(zmm0.i128[1]), reduce_add_epi32(zmm1.i128[1]), reduce_add_epi32(zmm2.i128[1]), reduce_add_epi32(zmm3.i128[1]),
|
||||||
|
reduce_add_epi32(zmm0.i128[2]), reduce_add_epi32(zmm1.i128[2]), reduce_add_epi32(zmm2.i128[2]), reduce_add_epi32(zmm3.i128[2]),
|
||||||
|
reduce_add_epi32(zmm0.i128[3]), reduce_add_epi32(zmm1.i128[3]), reduce_add_epi32(zmm2.i128[3]), reduce_add_epi32(zmm3.i128[3])
|
||||||
|
]
|
||||||
|
*/
|
||||||
|
[[maybe_unused]] static __m512i m512_hadd128x16_interleave(
|
||||||
|
__m512i sum0, __m512i sum1, __m512i sum2, __m512i sum3) {
|
||||||
|
|
||||||
|
__m512i sum01a = _mm512_unpacklo_epi32(sum0, sum1);
|
||||||
|
__m512i sum01b = _mm512_unpackhi_epi32(sum0, sum1);
|
||||||
|
|
||||||
|
__m512i sum23a = _mm512_unpacklo_epi32(sum2, sum3);
|
||||||
|
__m512i sum23b = _mm512_unpackhi_epi32(sum2, sum3);
|
||||||
|
|
||||||
|
__m512i sum01 = _mm512_add_epi32(sum01a, sum01b);
|
||||||
|
__m512i sum23 = _mm512_add_epi32(sum23a, sum23b);
|
||||||
|
|
||||||
|
__m512i sum0123a = _mm512_unpacklo_epi64(sum01, sum23);
|
||||||
|
__m512i sum0123b = _mm512_unpackhi_epi64(sum01, sum23);
|
||||||
|
|
||||||
|
return _mm512_add_epi32(sum0123a, sum0123b);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static __m128i m512_haddx4(
|
||||||
|
__m512i sum0, __m512i sum1, __m512i sum2, __m512i sum3,
|
||||||
|
__m128i bias) {
|
||||||
|
|
||||||
|
__m512i sum = m512_hadd128x16_interleave(sum0, sum1, sum2, sum3);
|
||||||
|
|
||||||
|
__m256i sum256lo = _mm512_castsi512_si256(sum);
|
||||||
|
__m256i sum256hi = _mm512_extracti64x4_epi64(sum, 1);
|
||||||
|
|
||||||
|
sum256lo = _mm256_add_epi32(sum256lo, sum256hi);
|
||||||
|
|
||||||
|
__m128i sum128lo = _mm256_castsi256_si128(sum256lo);
|
||||||
|
__m128i sum128hi = _mm256_extracti128_si256(sum256lo, 1);
|
||||||
|
|
||||||
|
return _mm_add_epi32(_mm_add_epi32(sum128lo, sum128hi), bias);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m512_add_dpbusd_epi32(
|
||||||
|
__m512i& acc,
|
||||||
|
__m512i a,
|
||||||
|
__m512i b) {
|
||||||
|
|
||||||
|
# if defined (USE_VNNI)
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
asm(
|
||||||
|
"vpdpbusd %[b], %[a], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc)
|
||||||
|
: [a]"v"(a), [b]"vm"(b)
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
acc = _mm512_dpbusd_epi32(acc, a, b);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m512i tmp = _mm512_maddubs_epi16(a, b);
|
||||||
|
asm(
|
||||||
|
"vpmaddwd %[tmp], %[ones], %[tmp]\n\t"
|
||||||
|
"vpaddd %[acc], %[tmp], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp]"+&v"(tmp)
|
||||||
|
: [ones]"v"(_mm512_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m512i product0 = _mm512_maddubs_epi16(a, b);
|
||||||
|
product0 = _mm512_madd_epi16(product0, _mm512_set1_epi16(1));
|
||||||
|
acc = _mm512_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m512_add_dpbusd_epi32x2(
|
||||||
|
__m512i& acc,
|
||||||
|
__m512i a0, __m512i b0,
|
||||||
|
__m512i a1, __m512i b1) {
|
||||||
|
|
||||||
|
# if defined (USE_VNNI)
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
asm(
|
||||||
|
"vpdpbusd %[b0], %[a0], %[acc]\n\t"
|
||||||
|
"vpdpbusd %[b1], %[a1], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc)
|
||||||
|
: [a0]"v"(a0), [b0]"vm"(b0), [a1]"v"(a1), [b1]"vm"(b1)
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
acc = _mm512_dpbusd_epi32(acc, a0, b0);
|
||||||
|
acc = _mm512_dpbusd_epi32(acc, a1, b1);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m512i tmp0 = _mm512_maddubs_epi16(a0, b0);
|
||||||
|
__m512i tmp1 = _mm512_maddubs_epi16(a1, b1);
|
||||||
|
asm(
|
||||||
|
"vpaddsw %[tmp0], %[tmp1], %[tmp0]\n\t"
|
||||||
|
"vpmaddwd %[tmp0], %[ones], %[tmp0]\n\t"
|
||||||
|
"vpaddd %[acc], %[tmp0], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp0]"+&v"(tmp0)
|
||||||
|
: [tmp1]"v"(tmp1), [ones]"v"(_mm512_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m512i product0 = _mm512_maddubs_epi16(a0, b0);
|
||||||
|
__m512i product1 = _mm512_maddubs_epi16(a1, b1);
|
||||||
|
product0 = _mm512_adds_epi16(product0, product1);
|
||||||
|
product0 = _mm512_madd_epi16(product0, _mm512_set1_epi16(1));
|
||||||
|
acc = _mm512_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (USE_AVX2)
|
||||||
|
|
||||||
|
[[maybe_unused]] static int m256_hadd(__m256i sum, int bias) {
|
||||||
|
__m128i sum128 = _mm_add_epi32(_mm256_castsi256_si128(sum), _mm256_extracti128_si256(sum, 1));
|
||||||
|
sum128 = _mm_add_epi32(sum128, _mm_shuffle_epi32(sum128, _MM_PERM_BADC));
|
||||||
|
sum128 = _mm_add_epi32(sum128, _mm_shuffle_epi32(sum128, _MM_PERM_CDAB));
|
||||||
|
return _mm_cvtsi128_si32(sum128) + bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static __m128i m256_haddx4(
|
||||||
|
__m256i sum0, __m256i sum1, __m256i sum2, __m256i sum3,
|
||||||
|
__m128i bias) {
|
||||||
|
|
||||||
|
sum0 = _mm256_hadd_epi32(sum0, sum1);
|
||||||
|
sum2 = _mm256_hadd_epi32(sum2, sum3);
|
||||||
|
|
||||||
|
sum0 = _mm256_hadd_epi32(sum0, sum2);
|
||||||
|
|
||||||
|
__m128i sum128lo = _mm256_castsi256_si128(sum0);
|
||||||
|
__m128i sum128hi = _mm256_extracti128_si256(sum0, 1);
|
||||||
|
|
||||||
|
return _mm_add_epi32(_mm_add_epi32(sum128lo, sum128hi), bias);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m256_add_dpbusd_epi32(
|
||||||
|
__m256i& acc,
|
||||||
|
__m256i a,
|
||||||
|
__m256i b) {
|
||||||
|
|
||||||
|
# if defined (USE_VNNI)
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
asm(
|
||||||
|
VNNI_PREFIX "vpdpbusd %[b], %[a], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc)
|
||||||
|
: [a]"v"(a), [b]"vm"(b)
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
acc = _mm256_dpbusd_epi32(acc, a, b);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m256i tmp = _mm256_maddubs_epi16(a, b);
|
||||||
|
asm(
|
||||||
|
"vpmaddwd %[tmp], %[ones], %[tmp]\n\t"
|
||||||
|
"vpaddd %[acc], %[tmp], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp]"+&v"(tmp)
|
||||||
|
: [ones]"v"(_mm256_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m256i product0 = _mm256_maddubs_epi16(a, b);
|
||||||
|
product0 = _mm256_madd_epi16(product0, _mm256_set1_epi16(1));
|
||||||
|
acc = _mm256_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m256_add_dpbusd_epi32x2(
|
||||||
|
__m256i& acc,
|
||||||
|
__m256i a0, __m256i b0,
|
||||||
|
__m256i a1, __m256i b1) {
|
||||||
|
|
||||||
|
# if defined (USE_VNNI)
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
asm(
|
||||||
|
VNNI_PREFIX "vpdpbusd %[b0], %[a0], %[acc]\n\t"
|
||||||
|
VNNI_PREFIX "vpdpbusd %[b1], %[a1], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc)
|
||||||
|
: [a0]"v"(a0), [b0]"vm"(b0), [a1]"v"(a1), [b1]"vm"(b1)
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
acc = _mm256_dpbusd_epi32(acc, a0, b0);
|
||||||
|
acc = _mm256_dpbusd_epi32(acc, a1, b1);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m256i tmp0 = _mm256_maddubs_epi16(a0, b0);
|
||||||
|
__m256i tmp1 = _mm256_maddubs_epi16(a1, b1);
|
||||||
|
asm(
|
||||||
|
"vpaddsw %[tmp0], %[tmp1], %[tmp0]\n\t"
|
||||||
|
"vpmaddwd %[tmp0], %[ones], %[tmp0]\n\t"
|
||||||
|
"vpaddd %[acc], %[tmp0], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp0]"+&v"(tmp0)
|
||||||
|
: [tmp1]"v"(tmp1), [ones]"v"(_mm256_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m256i product0 = _mm256_maddubs_epi16(a0, b0);
|
||||||
|
__m256i product1 = _mm256_maddubs_epi16(a1, b1);
|
||||||
|
product0 = _mm256_adds_epi16(product0, product1);
|
||||||
|
product0 = _mm256_madd_epi16(product0, _mm256_set1_epi16(1));
|
||||||
|
acc = _mm256_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (USE_SSSE3)
|
||||||
|
|
||||||
|
[[maybe_unused]] static int m128_hadd(__m128i sum, int bias) {
|
||||||
|
sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0x4E)); //_MM_PERM_BADC
|
||||||
|
sum = _mm_add_epi32(sum, _mm_shuffle_epi32(sum, 0xB1)); //_MM_PERM_CDAB
|
||||||
|
return _mm_cvtsi128_si32(sum) + bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static __m128i m128_haddx4(
|
||||||
|
__m128i sum0, __m128i sum1, __m128i sum2, __m128i sum3,
|
||||||
|
__m128i bias) {
|
||||||
|
|
||||||
|
sum0 = _mm_hadd_epi32(sum0, sum1);
|
||||||
|
sum2 = _mm_hadd_epi32(sum2, sum3);
|
||||||
|
sum0 = _mm_hadd_epi32(sum0, sum2);
|
||||||
|
return _mm_add_epi32(sum0, bias);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m128_add_dpbusd_epi32(
|
||||||
|
__m128i& acc,
|
||||||
|
__m128i a,
|
||||||
|
__m128i b) {
|
||||||
|
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m128i tmp = _mm_maddubs_epi16(a, b);
|
||||||
|
asm(
|
||||||
|
"pmaddwd %[ones], %[tmp]\n\t"
|
||||||
|
"paddd %[tmp], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp]"+&v"(tmp)
|
||||||
|
: [ones]"v"(_mm_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m128i product0 = _mm_maddubs_epi16(a, b);
|
||||||
|
product0 = _mm_madd_epi16(product0, _mm_set1_epi16(1));
|
||||||
|
acc = _mm_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void m128_add_dpbusd_epi32x2(
|
||||||
|
__m128i& acc,
|
||||||
|
__m128i a0, __m128i b0,
|
||||||
|
__m128i a1, __m128i b1) {
|
||||||
|
|
||||||
|
# if defined (USE_INLINE_ASM)
|
||||||
|
__m128i tmp0 = _mm_maddubs_epi16(a0, b0);
|
||||||
|
__m128i tmp1 = _mm_maddubs_epi16(a1, b1);
|
||||||
|
asm(
|
||||||
|
"paddsw %[tmp1], %[tmp0]\n\t"
|
||||||
|
"pmaddwd %[ones], %[tmp0]\n\t"
|
||||||
|
"paddd %[tmp0], %[acc]\n\t"
|
||||||
|
: [acc]"+v"(acc), [tmp0]"+&v"(tmp0)
|
||||||
|
: [tmp1]"v"(tmp1), [ones]"v"(_mm_set1_epi16(1))
|
||||||
|
);
|
||||||
|
# else
|
||||||
|
__m128i product0 = _mm_maddubs_epi16(a0, b0);
|
||||||
|
__m128i product1 = _mm_maddubs_epi16(a1, b1);
|
||||||
|
product0 = _mm_adds_epi16(product0, product1);
|
||||||
|
product0 = _mm_madd_epi16(product0, _mm_set1_epi16(1));
|
||||||
|
acc = _mm_add_epi32(acc, product0);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (USE_NEON)
|
||||||
|
|
||||||
|
[[maybe_unused]] static int neon_m128_reduce_add_epi32(int32x4_t s) {
|
||||||
|
# if USE_NEON >= 8
|
||||||
|
return vaddvq_s32(s);
|
||||||
|
# else
|
||||||
|
return s[0] + s[1] + s[2] + s[3];
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static int neon_m128_hadd(int32x4_t sum, int bias) {
|
||||||
|
return neon_m128_reduce_add_epi32(sum) + bias;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static int32x4_t neon_m128_haddx4(
|
||||||
|
int32x4_t sum0, int32x4_t sum1, int32x4_t sum2, int32x4_t sum3,
|
||||||
|
int32x4_t bias) {
|
||||||
|
|
||||||
|
int32x4_t hsums {
|
||||||
|
neon_m128_reduce_add_epi32(sum0),
|
||||||
|
neon_m128_reduce_add_epi32(sum1),
|
||||||
|
neon_m128_reduce_add_epi32(sum2),
|
||||||
|
neon_m128_reduce_add_epi32(sum3)
|
||||||
|
};
|
||||||
|
return vaddq_s32(hsums, bias);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static void neon_m128_add_dpbusd_epi32x2(
|
||||||
|
int32x4_t& acc,
|
||||||
|
int8x8_t a0, int8x8_t b0,
|
||||||
|
int8x8_t a1, int8x8_t b1) {
|
||||||
|
|
||||||
|
int16x8_t product = vmull_s8(a0, b0);
|
||||||
|
product = vmlal_s8(product, a1, b1);
|
||||||
|
acc = vpadalq_s16(acc, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // STOCKFISH_SIMD_H_INCLUDED
|
||||||
+12
-12
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -769,7 +769,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
|||||||
goto encode_remaining; // With pawns we have finished special treatments
|
goto encode_remaining; // With pawns we have finished special treatments
|
||||||
}
|
}
|
||||||
|
|
||||||
// In positions withouth pawns, we further flip the squares to ensure leading
|
// In positions without pawns, we further flip the squares to ensure leading
|
||||||
// piece is below RANK_5.
|
// piece is below RANK_5.
|
||||||
if (rank_of(squares[0]) > RANK_4)
|
if (rank_of(squares[0]) > RANK_4)
|
||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
@@ -812,7 +812,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
|||||||
// Rs "together" in 62 * 61 / 2 ways (we divide by 2 because rooks can be
|
// Rs "together" in 62 * 61 / 2 ways (we divide by 2 because rooks can be
|
||||||
// swapped and still get the same position.)
|
// swapped and still get the same position.)
|
||||||
//
|
//
|
||||||
// In case we have at least 3 unique pieces (inlcuded kings) we encode them
|
// In case we have at least 3 unique pieces (included kings) we encode them
|
||||||
// together.
|
// together.
|
||||||
if (entry->hasUniquePieces) {
|
if (entry->hasUniquePieces) {
|
||||||
|
|
||||||
@@ -827,7 +827,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
|
|||||||
+ (squares[1] - adjust1)) * 62
|
+ (squares[1] - adjust1)) * 62
|
||||||
+ squares[2] - adjust2;
|
+ squares[2] - adjust2;
|
||||||
|
|
||||||
// First piece is on a1-h8 diagonal, second below: map this occurence to
|
// First piece is on a1-h8 diagonal, second below: map this occurrence to
|
||||||
// 6 to differentiate from the above case, rank_of() maps a1-d4 diagonal
|
// 6 to differentiate from the above case, rank_of() maps a1-d4 diagonal
|
||||||
// to 0...3 and finally MapB1H1H7[] maps the b1-h1-h7 triangle to 0..27.
|
// to 0...3 and finally MapB1H1H7[] maps the b1-h1-h7 triangle to 0..27.
|
||||||
else if (off_A1H8(squares[1]))
|
else if (off_A1H8(squares[1]))
|
||||||
@@ -857,7 +857,7 @@ encode_remaining:
|
|||||||
idx *= d->groupIdx[0];
|
idx *= d->groupIdx[0];
|
||||||
Square* groupSq = squares + d->groupLen[0];
|
Square* groupSq = squares + d->groupLen[0];
|
||||||
|
|
||||||
// Encode remainig pawns then pieces according to square, in ascending order
|
// Encode remaining pawns then pieces according to square, in ascending order
|
||||||
bool remainingPawns = entry->hasPawns && entry->pawnCount[1];
|
bool remainingPawns = entry->hasPawns && entry->pawnCount[1];
|
||||||
|
|
||||||
while (d->groupLen[++next])
|
while (d->groupLen[++next])
|
||||||
@@ -885,7 +885,7 @@ encode_remaining:
|
|||||||
|
|
||||||
// Group together pieces that will be encoded together. The general rule is that
|
// Group together pieces that will be encoded together. The general rule is that
|
||||||
// a group contains pieces of same type and color. The exception is the leading
|
// a group contains pieces of same type and color. The exception is the leading
|
||||||
// group that, in case of positions withouth pawns, can be formed by 3 different
|
// group that, in case of positions without pawns, can be formed by 3 different
|
||||||
// pieces (default) or by the king pair when there is not a unique piece apart
|
// pieces (default) or by the king pair when there is not a unique piece apart
|
||||||
// from the kings. When there are pawns, pawns are always first in pieces[].
|
// from the kings. When there are pawns, pawns are always first in pieces[].
|
||||||
//
|
//
|
||||||
@@ -917,7 +917,7 @@ void set_groups(T& e, PairsData* d, int order[], File f) {
|
|||||||
//
|
//
|
||||||
// This ensures unique encoding for the whole position. The order of the
|
// This ensures unique encoding for the whole position. The order of the
|
||||||
// groups is a per-table parameter and could not follow the canonical leading
|
// groups is a per-table parameter and could not follow the canonical leading
|
||||||
// pawns/pieces -> remainig pawns -> remaining pieces. In particular the
|
// pawns/pieces -> remaining pawns -> remaining pieces. In particular the
|
||||||
// first group is at order[0] position and the remaining pawns, when present,
|
// first group is at order[0] position and the remaining pawns, when present,
|
||||||
// are at order[1] position.
|
// are at order[1] position.
|
||||||
bool pp = e.hasPawns && e.pawnCount[1]; // Pawns on both sides
|
bool pp = e.hasPawns && e.pawnCount[1]; // Pawns on both sides
|
||||||
@@ -937,7 +937,7 @@ void set_groups(T& e, PairsData* d, int order[], File f) {
|
|||||||
d->groupIdx[1] = idx;
|
d->groupIdx[1] = idx;
|
||||||
idx *= Binomial[d->groupLen[1]][48 - d->groupLen[0]];
|
idx *= Binomial[d->groupLen[1]][48 - d->groupLen[0]];
|
||||||
}
|
}
|
||||||
else // Remainig pieces
|
else // Remaining pieces
|
||||||
{
|
{
|
||||||
d->groupIdx[next] = idx;
|
d->groupIdx[next] = idx;
|
||||||
idx *= Binomial[d->groupLen[next]][freeSquares];
|
idx *= Binomial[d->groupLen[next]][freeSquares];
|
||||||
@@ -947,7 +947,7 @@ void set_groups(T& e, PairsData* d, int order[], File f) {
|
|||||||
d->groupIdx[n] = idx;
|
d->groupIdx[n] = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In Recursive Pairing each symbol represents a pair of childern symbols. So
|
// In Recursive Pairing each symbol represents a pair of children symbols. So
|
||||||
// read d->btree[] symbols data and expand each one in his left and right child
|
// read d->btree[] symbols data and expand each one in his left and right child
|
||||||
// symbol until reaching the leafs that represent the symbol value.
|
// symbol until reaching the leafs that represent the symbol value.
|
||||||
uint8_t set_symlen(PairsData* d, Sym s, std::vector<bool>& visited) {
|
uint8_t set_symlen(PairsData* d, Sym s, std::vector<bool>& visited) {
|
||||||
@@ -1290,7 +1290,7 @@ void Tablebases::init(const std::string& paths) {
|
|||||||
for (auto s : diagonal)
|
for (auto s : diagonal)
|
||||||
MapA1D1D4[s] = code++;
|
MapA1D1D4[s] = code++;
|
||||||
|
|
||||||
// MapKK[] encodes all the 461 possible legal positions of two kings where
|
// MapKK[] encodes all the 462 possible legal positions of two kings where
|
||||||
// the first is in the a1-d1-d4 triangle. If the first king is on the a1-d4
|
// the first is in the a1-d1-d4 triangle. If the first king is on the a1-d4
|
||||||
// diagonal, the other one shall not to be above the a1-h8 diagonal.
|
// diagonal, the other one shall not to be above the a1-h8 diagonal.
|
||||||
std::vector<std::pair<int, Square>> bothOnDiagonal;
|
std::vector<std::pair<int, Square>> bothOnDiagonal;
|
||||||
@@ -1317,7 +1317,7 @@ void Tablebases::init(const std::string& paths) {
|
|||||||
for (auto p : bothOnDiagonal)
|
for (auto p : bothOnDiagonal)
|
||||||
MapKK[p.first][p.second] = code++;
|
MapKK[p.first][p.second] = code++;
|
||||||
|
|
||||||
// Binomial[] stores the Binomial Coefficents using Pascal rule. There
|
// Binomial[] stores the Binomial Coefficients using Pascal rule. There
|
||||||
// are Binomial[k][n] ways to choose k elements from a set of n elements.
|
// are Binomial[k][n] ways to choose k elements from a set of n elements.
|
||||||
Binomial[0][0] = 1;
|
Binomial[0][0] = 1;
|
||||||
|
|
||||||
@@ -1337,7 +1337,7 @@ void Tablebases::init(const std::string& paths) {
|
|||||||
for (int leadPawnsCnt = 1; leadPawnsCnt <= 5; ++leadPawnsCnt)
|
for (int leadPawnsCnt = 1; leadPawnsCnt <= 5; ++leadPawnsCnt)
|
||||||
for (File f = FILE_A; f <= FILE_D; ++f)
|
for (File f = FILE_A; f <= FILE_D; ++f)
|
||||||
{
|
{
|
||||||
// Restart the index at every file because TB table is splitted
|
// Restart the index at every file because TB table is split
|
||||||
// by file, so we can reuse the same index for different files.
|
// by file, so we can reuse the same index for different files.
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -38,7 +38,7 @@ enum WDLScore {
|
|||||||
// Possible states after a probing operation
|
// Possible states after a probing operation
|
||||||
enum ProbeState {
|
enum ProbeState {
|
||||||
FAIL = 0, // Probe failed (missing file table)
|
FAIL = 0, // Probe failed (missing file table)
|
||||||
OK = 1, // Probe succesful
|
OK = 1, // Probe successful
|
||||||
CHANGE_STM = -1, // DTZ should check the other side
|
CHANGE_STM = -1, // DTZ should check the other side
|
||||||
ZEROING_BEST_MOVE = 2 // Best move zeroes DTZ (capture or pawn move)
|
ZEROING_BEST_MOVE = 2 // Best move zeroes DTZ (capture or pawn move)
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -60,15 +60,15 @@ void Thread::clear() {
|
|||||||
|
|
||||||
counterMoves.fill(MOVE_NONE);
|
counterMoves.fill(MOVE_NONE);
|
||||||
mainHistory.fill(0);
|
mainHistory.fill(0);
|
||||||
lowPlyHistory.fill(0);
|
|
||||||
captureHistory.fill(0);
|
captureHistory.fill(0);
|
||||||
|
previousDepth = 0;
|
||||||
|
|
||||||
for (bool inCheck : { false, true })
|
for (bool inCheck : { false, true })
|
||||||
for (StatsType c : { NoCaptures, Captures })
|
for (StatsType c : { NoCaptures, Captures })
|
||||||
{
|
{
|
||||||
for (auto& to : continuationHistory[inCheck][c])
|
for (auto& to : continuationHistory[inCheck][c])
|
||||||
for (auto& h : to)
|
for (auto& h : to)
|
||||||
h->fill(0);
|
h->fill(-71);
|
||||||
continuationHistory[inCheck][c][NO_PIECE][0]->fill(Search::CounterMovePruneThreshold - 1);
|
continuationHistory[inCheck][c][NO_PIECE][0]->fill(Search::CounterMovePruneThreshold - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +187,7 @@ void ThreadPool::clear() {
|
|||||||
|
|
||||||
main()->callsCnt = 0;
|
main()->callsCnt = 0;
|
||||||
main()->bestPreviousScore = VALUE_INFINITE;
|
main()->bestPreviousScore = VALUE_INFINITE;
|
||||||
|
main()->bestPreviousAverageScore = VALUE_INFINITE;
|
||||||
main()->previousTimeReduction = 1.0;
|
main()->previousTimeReduction = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-5
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -88,19 +88,20 @@ public:
|
|||||||
Pawns::Table pawnsTable;
|
Pawns::Table pawnsTable;
|
||||||
Material::Table materialTable;
|
Material::Table materialTable;
|
||||||
size_t pvIdx, pvLast;
|
size_t pvIdx, pvLast;
|
||||||
uint64_t ttHitAverage;
|
RunningAverage complexityAverage;
|
||||||
|
std::atomic<uint64_t> nodes, tbHits, bestMoveChanges;
|
||||||
int selDepth, nmpMinPly;
|
int selDepth, nmpMinPly;
|
||||||
Color nmpColor;
|
Color nmpColor;
|
||||||
std::atomic<uint64_t> nodes, tbHits, bestMoveChanges;
|
Value bestValue, optimism[COLOR_NB];
|
||||||
uint64_t maxNodes;
|
uint64_t maxNodes;
|
||||||
|
|
||||||
Position rootPos;
|
Position rootPos;
|
||||||
StateInfo rootState;
|
StateInfo rootState;
|
||||||
Search::RootMoves rootMoves;
|
Search::RootMoves rootMoves;
|
||||||
Depth rootDepth, completedDepth;
|
Depth rootDepth, completedDepth, depth, previousDepth;
|
||||||
|
Value rootDelta;
|
||||||
CounterMoveHistory counterMoves;
|
CounterMoveHistory counterMoves;
|
||||||
ButterflyHistory mainHistory;
|
ButterflyHistory mainHistory;
|
||||||
LowPlyHistory lowPlyHistory;
|
|
||||||
CapturePieceToHistory captureHistory;
|
CapturePieceToHistory captureHistory;
|
||||||
ContinuationHistory continuationHistory[2][2];
|
ContinuationHistory continuationHistory[2][2];
|
||||||
Score trend;
|
Score trend;
|
||||||
@@ -123,6 +124,7 @@ struct MainThread : public Thread {
|
|||||||
|
|
||||||
double previousTimeReduction;
|
double previousTimeReduction;
|
||||||
Value bestPreviousScore;
|
Value bestPreviousScore;
|
||||||
|
Value bestPreviousAverageScore;
|
||||||
Value iterValue[4];
|
Value iterValue[4];
|
||||||
int callsCnt;
|
int callsCnt;
|
||||||
bool stopOnPonderhit;
|
bool stopOnPonderhit;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+8
-4
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -68,6 +68,9 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
|
|||||||
TimePoint timeLeft = std::max(TimePoint(1),
|
TimePoint timeLeft = std::max(TimePoint(1),
|
||||||
limits.time[us] + limits.inc[us] * (mtg - 1) - moveOverhead * (2 + mtg));
|
limits.time[us] + limits.inc[us] * (mtg - 1) - moveOverhead * (2 + mtg));
|
||||||
|
|
||||||
|
// Use extra time with larger increments
|
||||||
|
double optExtra = std::clamp(1.0 + 12.0 * limits.inc[us] / limits.time[us], 1.0, 1.12);
|
||||||
|
|
||||||
// A user may scale time usage by setting UCI option "Slow Mover"
|
// A user may scale time usage by setting UCI option "Slow Mover"
|
||||||
// Default is 100 and changing this value will probably lose elo.
|
// Default is 100 and changing this value will probably lose elo.
|
||||||
timeLeft = slowMover * timeLeft / 100;
|
timeLeft = slowMover * timeLeft / 100;
|
||||||
@@ -78,15 +81,16 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
|
|||||||
if (limits.movestogo == 0)
|
if (limits.movestogo == 0)
|
||||||
{
|
{
|
||||||
optScale = std::min(0.0084 + std::pow(ply + 3.0, 0.5) * 0.0042,
|
optScale = std::min(0.0084 + std::pow(ply + 3.0, 0.5) * 0.0042,
|
||||||
0.2 * limits.time[us] / double(timeLeft));
|
0.2 * limits.time[us] / double(timeLeft))
|
||||||
|
* optExtra;
|
||||||
maxScale = std::min(7.0, 4.0 + ply / 12.0);
|
maxScale = std::min(7.0, 4.0 + ply / 12.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// x moves in y seconds (+ z increment)
|
// x moves in y seconds (+ z increment)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
optScale = std::min((0.8 + ply / 128.0) / mtg,
|
optScale = std::min((0.88 + ply / 116.4) / mtg,
|
||||||
0.8 * limits.time[us] / double(timeLeft));
|
0.88 * limits.time[us] / double(timeLeft));
|
||||||
maxScale = std::min(6.3, 1.5 + 0.11 * mtg);
|
maxScale = std::min(6.3, 1.5 + 0.11 * mtg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -45,9 +45,9 @@ void TTEntry::save(Key k, Value v, bool pv, Bound b, Depth d, Move m, Value ev)
|
|||||||
move16 = (uint16_t)m;
|
move16 = (uint16_t)m;
|
||||||
|
|
||||||
// Overwrite less valuable entries (cheapest checks first)
|
// Overwrite less valuable entries (cheapest checks first)
|
||||||
if (b == BOUND_EXACT
|
if ( b == BOUND_EXACT
|
||||||
|| (uint16_t)k != key16
|
|| (uint16_t)k != key16
|
||||||
|| d - DEPTH_OFFSET > depth8 - 4)
|
|| d - DEPTH_OFFSET + 2 * pv > depth8 - 4)
|
||||||
{
|
{
|
||||||
assert(d > DEPTH_OFFSET);
|
assert(d > DEPTH_OFFSET);
|
||||||
assert(d < 256 + DEPTH_OFFSET);
|
assert(d < 256 + DEPTH_OFFSET);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -84,7 +84,7 @@ class Tune {
|
|||||||
|
|
||||||
static Tune& instance() { static Tune t; return t; } // Singleton
|
static Tune& instance() { static Tune t; return t; } // Singleton
|
||||||
|
|
||||||
// Use polymorphism to accomodate Entry of different types in the same vector
|
// Use polymorphism to accommodate Entry of different types in the same vector
|
||||||
struct EntryBase {
|
struct EntryBase {
|
||||||
virtual ~EntryBase() = default;
|
virtual ~EntryBase() = default;
|
||||||
virtual void init_option() = 0;
|
virtual void init_option() = 0;
|
||||||
|
|||||||
+2
-6
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -457,7 +457,7 @@ constexpr Square rotate180(Square sq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr int from_to(Move m) {
|
constexpr int from_to(Move m) {
|
||||||
return m & 0xFFF;
|
return m & 0xFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr MoveType type_of(Move m) {
|
constexpr MoveType type_of(Move m) {
|
||||||
@@ -472,10 +472,6 @@ constexpr Move make_move(Square from, Square to) {
|
|||||||
return Move((from << 6) + to);
|
return Move((from << 6) + to);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr Move reverse_move(Move m) {
|
|
||||||
return make_move(to_sq(m), from_sq(m));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<MoveType T>
|
template<MoveType T>
|
||||||
constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
|
constexpr Move make(Square from, Square to, PieceType pt = KNIGHT) {
|
||||||
return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
|
return Move(T + ((pt - KNIGHT) << 12) + (from << 6) + to);
|
||||||
|
|||||||
+10
-4
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -220,8 +220,8 @@ namespace UCI {
|
|||||||
// Coefficients of a 3rd order polynomial fit based on fishtest data
|
// Coefficients of a 3rd order polynomial fit based on fishtest data
|
||||||
// for two parameters needed to transform eval to the argument of a
|
// for two parameters needed to transform eval to the argument of a
|
||||||
// logistic function.
|
// logistic function.
|
||||||
double as[] = {-3.68389304, 30.07065921, -60.52878723, 149.53378557};
|
double as[] = {-1.17202460e-01, 5.94729104e-01, 1.12065546e+01, 1.22606222e+02};
|
||||||
double bs[] = {-2.0181857, 15.85685038, -29.83452023, 47.59078827};
|
double bs[] = {-1.79066759, 11.30759193, -17.43677612, 36.47147479};
|
||||||
double a = (((as[0] * m + as[1]) * m + as[2]) * m) + as[3];
|
double a = (((as[0] * m + as[1]) * m + as[2]) * m) + as[3];
|
||||||
double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3];
|
double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3];
|
||||||
|
|
||||||
@@ -380,8 +380,14 @@ void UCI::loop(int argc, char* argv[]) {
|
|||||||
std::cout << th.id() << '\n';
|
std::cout << th.id() << '\n';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else if (token == "--help" || token == "help" || token == "--license" || token == "license")
|
||||||
|
sync_cout << "\nStockfish is a powerful chess engine and free software licensed under the GNU GPLv3."
|
||||||
|
"\nStockfish is normally used with a separate graphical user interface (GUI)."
|
||||||
|
"\nStockfish implements the universal chess interface (UCI) to exchange information."
|
||||||
|
"\nFor further information see https://github.com/official-stockfish/Stockfish#readme"
|
||||||
|
"\nor the corresponding README.md and Copying.txt files distributed with this program.\n" << sync_endl;
|
||||||
else if (!token.empty() && token[0] != '#')
|
else if (!token.empty() && token[0] != '#')
|
||||||
sync_cout << "Unknown command: " << cmd << sync_endl;
|
sync_cout << "Unknown command: '" << cmd << "'. Type help for more information." << sync_endl;
|
||||||
|
|
||||||
} while (token != "quit" && argc == 1); // Command line args are one-shot
|
} while (token != "quit" && argc == 1); // Command line args are one-shot
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||||
Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
|
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
|
||||||
|
|
||||||
Stockfish is free software: you can redistribute it and/or modify
|
Stockfish is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -185,7 +185,7 @@ Option& Option::operator=(const string& v) {
|
|||||||
|
|
||||||
assert(!type.empty());
|
assert(!type.empty());
|
||||||
|
|
||||||
if ( (type != "button" && v.empty())
|
if ( (type != "button" && type != "string" && v.empty())
|
||||||
|| (type == "check" && v != "true" && v != "false")
|
|| (type == "check" && v != "true" && v != "false")
|
||||||
|| (type == "spin" && (stof(v) < min || stof(v) > max)))
|
|| (type == "spin" && (stof(v) < min || stof(v) > max)))
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ cat << EOF > repeat.exp
|
|||||||
expect eof
|
expect eof
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# to increase the likelyhood of finding a non-reproducible case,
|
# to increase the likelihood of finding a non-reproducible case,
|
||||||
# the allowed number of nodes are varied systematically
|
# the allowed number of nodes are varied systematically
|
||||||
for i in `seq 1 20`
|
for i in `seq 1 20`
|
||||||
do
|
do
|
||||||
|
|||||||
Reference in New Issue
Block a user