From ba32bd5d70b3549ec43ae484fa6ce95f0ddf10b2 Mon Sep 17 00:00:00 2001 From: Tomasz Sobczyk Date: Mon, 19 Apr 2021 18:57:21 +0200 Subject: [PATCH] Bring the changes closer to official-stockfish/master --- .travis.yml | 31 +- README.md | 312 +++++++++++++++--- src/Makefile | 37 +-- src/misc.cpp | 81 ----- src/misc.h | 83 +---- src/nnue/architectures/halfkp_256x2-32-32.h | 56 ++-- src/nnue/evaluate_nnue.cpp | 5 +- src/nnue/evaluate_nnue.h | 5 +- src/nnue/features/feature_set.h | 5 +- src/nnue/features/half_kp.cpp | 20 +- src/nnue/features/half_kp.h | 23 +- src/nnue/layers/affine_transform.h | 5 +- src/nnue/layers/clipped_relu.h | 30 -- src/nnue/layers/input_slice.h | 27 -- src/nnue/nnue_accumulator.h | 5 +- src/nnue/nnue_common.h | 11 - src/nnue/nnue_feature_transformer.h | 5 +- src/position.cpp | 4 +- src/tools/convert.cpp | 6 +- ...ensfen.cpp => training_data_generator.cpp} | 34 +- .../{gensfen.h => training_data_generator.h} | 2 +- ....cpp => training_data_generator_nonpv.cpp} | 26 +- ...onpv.h => training_data_generator_nonpv.h} | 2 +- src/uci.cpp | 23 +- src/uci.h | 2 - stockfish.md | 242 -------------- tests/instrumented.sh | 54 ++- tests/instrumented_learn.sh | 155 --------- 28 files changed, 451 insertions(+), 840 deletions(-) rename src/tools/{gensfen.cpp => training_data_generator.cpp} (97%) rename src/tools/{gensfen.h => training_data_generator.h} (75%) rename src/tools/{gensfen_nonpv.cpp => training_data_generator_nonpv.cpp} (95%) rename src/tools/{gensfen_nonpv.h => training_data_generator_nonpv.h} (71%) delete mode 100644 stockfish.md delete mode 100755 tests/instrumented_learn.sh diff --git a/.travis.yml b/.travis.yml index 3a04de58..377796f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,34 +7,11 @@ matrix: compiler: gcc addons: apt: - packages: ['g++-multilib', 'valgrind', 'expect', 'curl', 'libopenblas-dev'] + packages: ['g++-multilib', 'valgrind', 'expect', 'curl'] env: - COMPILER=g++ - COMP=gcc -# - os: linux -# compiler: clang -# addons: -# apt: -# packages: ['clang-10', 'llvm-10-dev', 'g++-multilib', 'valgrind', 'expect', 'curl', 'openblas'] -# env: -# - COMPILER=clang++-10 -# - COMP=clang -# -# - os: osx -# osx_image: xcode12 -# compiler: gcc -# env: -# - COMPILER=g++ -# - COMP=gcc -# -# - os: osx -# osx_image: xcode12 -# compiler: clang -# env: -# - COMPILER=clang++ -# - COMP=clang - branches: only: - master @@ -96,9 +73,3 @@ script: # - make clean && make -j2 ARCH=x86-64-modern sanitize=undefined optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-undefined - make clean && make -j2 ARCH=x86-64-modern sanitize=thread optimize=no debug=yes build > /dev/null && ../tests/instrumented.sh --sanitizer-thread - - # NNUE testing - - export CXXFLAGS="-O1 -fno-inline" - - make clean && make -j2 ARCH=x86-64-modern debug=no optimize=no build > /dev/null && ../tests/instrumented_learn.sh --valgrind - - make clean && make -j2 ARCH=x86-64-modern sanitize=undefined optimize=no debug=yes build > /dev/null && ../tests/instrumented_learn.sh --sanitizer-undefined - - make clean && make -j2 ARCH=x86-64-modern sanitize=thread optimize=no debug=yes build > /dev/null && ../tests/instrumented_learn.sh --sanitizer-thread diff --git a/README.md b/README.md index 10d43595..6c974a78 100644 --- a/README.md +++ b/README.md @@ -24,54 +24,117 @@ This distribution of Stockfish consists of the following files: * Readme.md, the file you are currently reading. * Copying.txt, a text file containing the GNU General Public License version 3. - + * AUTHORS, a text file with the list of authors for the project -Stockfish NNUE is a port of a shogi neural network named NNUE (efficiently updateable neural network backwards) to Stockfish 11. To learn more about the Stockfish chess engine, look [here](stockfish.md) for an overview and [here](https://github.com/official-stockfish/Stockfish) for the official repository. + * src, a subdirectory containing the full source code, including a Makefile + that can be used to compile Stockfish on Unix-like systems. -======= -## Building + * a file with the .nnue extension, storing the neural network for the NNUE + evaluation. Binary distributions will have this file embedded. -To compile: -``` -make -jN ARCH=... build -``` +## UCI options -To compile with Profile Guided Optimizations. Requires that the computer that is used for compilation supports the selected `ARCH`. -``` -make -jN ARCH=... profile-build -``` +Currently, Stockfish has the following UCI options: -`N` is the number of threads to use for compilation. + * #### Threads + The number of CPU threads used for searching a position. For best performance, set + this equal to the number of CPU cores available. -`ARCH` is one of: -`x86-64-vnni512`, `x86-64-vnni256`, `x86-64-avx512`, `x86-64-bmi2`, `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, -armv7`, `armv7-neon`, `armv8`, `apple-silicon`, `general-64`, `general-32`. + * #### Hash + The size of the hash table in MB. It is recommended to set Hash after setting Threads. -`ARCH` needs to be chosen based based on the instruction set of the CPU that will run stockfish. `x86-64-modern` will produce a binary that works on most common processors, but other options may increase performance for specific hardware. + * #### Clear Hash + Clear the hash table. -Additional options: + * #### Ponder + Let Stockfish ponder its next move while the opponent is thinking. -### Building Instructions for Mac + * #### MultiPV + Output the N best lines (principal variations, PVs) when searching. + Leave at 1 for best performance. -1. Ensure that you have OpenBlas Installed -``` -brew install openblas -``` -2. Go to src then build using the makefile -``` -cd src -make build ARCH=x86-64 COMP=gcc blas=yes -``` -or -``` -cd src -make profile-build ARCH=x86-64 COMP=gcc blas=yes -``` + * #### Use NNUE + Toggle between the NNUE and classical evaluation functions. If set to "true", + the network parameters must be available to load from file (see also EvalFile), + if they are not embedded in the binary. -## Training Guide + * #### EvalFile + 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. + Other locations, such as the directory that contains the binary and the working directory, + are also searched. + + * #### UCI_AnalyseMode + An option handled by your GUI. + + * #### UCI_Chess960 + An option handled by your GUI. If true, Stockfish will play Chess960. + + * #### UCI_ShowWDL + If enabled, show approximate WDL statistics as part of the engine output. + These WDL numbers model expected game outcomes for a given evaluation and + game ply for engine self-play at fishtest LTC conditions (60+0.6s per game). + + * #### UCI_LimitStrength + Enable weaker play aiming for an Elo rating as set by UCI_Elo. This option overrides Skill Level. + + * #### UCI_Elo + If enabled by UCI_LimitStrength, aim for an engine strength of the given Elo. + This Elo rating has been calibrated at a time control of 60s+0.6s and anchored to CCRL 40/4. + + * #### Skill Level + Lower the Skill Level in order to make Stockfish play weaker (see also UCI_LimitStrength). + Internally, MultiPV is enabled, and with a certain probability depending on the Skill Level a + weaker move will be played. + + * #### SyzygyPath + Path to the folders/directories storing the Syzygy tablebase files. Multiple + directories are to be separated by ";" on Windows and by ":" on Unix-based + operating systems. Do not use spaces around the ";" or ":". + + 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 + the .rtbz files on a regular HD. It is recommended to verify all md5 checksums + of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will + lead to engine crashes. + + * #### SyzygyProbeDepth + Minimum remaining search depth for which a position is probed. Set this option + to a higher value to probe less aggressively if you experience too much slowdown + (in terms of nps) due to tablebase probing. + + * #### Syzygy50MoveRule + Disable to let fifty-move rule draws detected by Syzygy tablebase probes count + as wins or losses. This is useful for ICCF correspondence games. + + * #### SyzygyProbeLimit + Limit Syzygy tablebase probing to positions with at most this many pieces left + (including kings and pawns). + + * #### Contempt + A positive value for contempt favors middle game positions and avoids draws, + effective for the classical evaluation only. + + * #### Analysis Contempt + By default, contempt is set to prefer the side to move. Set this option to "White" + or "Black" to analyse with contempt for that side, or "Off" to disable contempt. + + * #### Move Overhead + Assume a time delay of x ms due to network and GUI overheads. This is useful to + avoid losses on time in those cases. + + * #### Slow Mover + Lower values will make Stockfish take less time in games, higher values will + make it think longer. + + * #### nodestime + Tells the engine to use nodes searched instead of wall time to account for + elapsed time. Useful for engine testing. + + * #### Debug Log File + Write all communication to and from the engine into a text file. ### Generating Training Data @@ -81,24 +144,26 @@ To generate training data from the classic eval, use the gensfen command with th uci setoption name PruneAtShallowDepth value false setoption name Use NNUE value false -setoption name Threads value x -setoption name Hash value y +setoption name Threads value X +setoption name Hash value Y setoption name SyzygyPath value path isready -gensfen depth a loop b use_draw_in_training_data_generation 1 eval_limit 32000 +gensfen depth A count B keep_draws 1 eval_limit 32000 ``` -- `depth` is the searched depth per move, or how far the engine looks forward. This value is an integer. -- `loop` is the amount of positions generated. This value is also an integer. +- `A` is the searched depth per move, or how far the engine looks forward. This value is an integer. +- `B` is the amount of positions generated. This value is also an integer. Specify how many threads and how much memory you would like to use with the `x` and `y` values. The option SyzygyPath is not necessary, but if you would like to use it, you must first have Syzygy endgame tablebases on your computer, which you can find [here](http://oics.olympuschess.com/tracker/index.php). You will need to have a torrent client to download these tablebases, as that is probably the fastest way to obtain them. The `path` is the path to the folder containing those tablebases. It does not have to be surrounded in quotes. -This will create a file named "generated_kifu.binpack" in the same folder as the binary containing the generated training data. Once generation is done, you can rename the file to something like "1billiondepth12.binpack" to remember the depth and quantity of the positions and move it to a folder named "trainingdata" in the same directory as the binaries. +This will create a file named "training_data.binpack" in the same folder as the binary containing the generated training data. Once generation is done, you can rename the file to something like "1billiondepth12.binpack" to remember the depth and quantity of the positions and move it to a folder named "trainingdata" in the same directory as the binaries. You will also need validation data that is used for loss calculation and accuracy computation. Validation data is generated in the same way as training data, but generally at most 1 million positions should be used as there's no need for more and it would just slow the learning process down. It may also be better to slightly increase the depth for validation data. After generation you can rename the validation data file to "val.binpack" and drop it in a folder named "validationdata" in the same directory to make it easier. ## Training data formats. +Currently there are 3 training data formats. Two of them are supported directly. + - `.bin` - the original training data format. Uses 40 bytes per entry. Is supported directly by the `gensfen` and `learn` commands. - `.plain` - a human readable training data format. This one is not supported directly by the `gensfen` and `learn` commands. It should not be used for data exchange because it's less compact than other formats. It is mostly useful for inspection of the data. - `.binpack` - a compact binary training data format that exploits positions chains to further reduce size. It uses on average between 2 to 3 bytes per entry when generating data with `gensfen`. It is supported directly by `gensfen` and `learn` commands. It is currently the default for the `gensfen` command. A more in depth description can be found [here](docs/binpack.md) @@ -107,4 +172,165 @@ You will also need validation data that is used for loss calculation and accurac There is a builting converted that support all 3 formats described above. Any of them can be converted to any other. For more information and usage guide see [here](docs/convert.md). -A more updated list can be found in the #sf-nnue-resources channel in the Discord. +## A note on classical evaluation versus NNUE evaluation + +Both approaches assign a value to a position that is used in alpha-beta (PVS) search +to find the best move. The classical evaluation computes this value as a function +of various chess concepts, handcrafted by experts, tested and tuned using fishtest. +The NNUE evaluation computes this value with a neural network based on basic +inputs (e.g. piece positions only). The network is optimized and trained +on the evaluations of millions of positions at moderate search depth. + +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 +of the neural network need to be updated after a typical chess move. +[The nodchip repository](https://github.com/nodchip/Stockfish) provides additional +tools to train and develop the NNUE networks. 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: + +1) the NNUE evaluation depends on the Stockfish binary and the network parameter +file (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 +that is guaranteed to be compatible with that binary. + +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 +can 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` +(for instance, `nn-c157e0a5755b.nnue`). This file can be downloaded from +``` +https://tests.stockfishchess.org/api/nn/[filename] +``` +replacing `[filename]` as needed. + +## What to expect from the Syzygy tablebases? + +If the engine is searching a position that is not in the tablebases (e.g. +a position with 8 pieces), it will access the tablebases during the search. +If the engine reports a very large score (typically 153.xx), this means +it has found a winning line into a tablebase position. + +If the engine is given a position to search that is in the tablebases, it +will use the tablebases at the beginning of the search to preselect all +good moves, i.e. all moves that preserve the win or preserve the draw while +taking into account the 50-move rule. +It will then perform a search only on those moves. **The engine will not move +immediately**, unless there is only a single good move. **The engine likely +will not report a mate score, even if the position is known to be won.** + +It is therefore clear that this behaviour is not identical to what one might +be used to with Nalimov tablebases. There are technical reasons for this +difference, the main technical reason being that Nalimov tablebases use the +DTM metric (distance-to-mate), while the Syzygy tablebases use a variation of the +DTZ metric (distance-to-zero, zero meaning any move that resets the 50-move +counter). This special metric is one of the reasons that the Syzygy tablebases are +more compact than Nalimov tablebases, while still storing all information +needed for optimal play and in addition being able to take into account +the 50-move rule. + +## Large Pages + +Stockfish supports large pages on Linux and Windows. Large pages make +the hash access more efficient, improving the engine speed, especially +on large hash sizes. Typical increases are 5..10% in terms of nodes per +second, but speed increases up to 30% have been measured. The support is +automatic. Stockfish attempts to use large pages when available and +will fall back to regular memory allocation when this is not the case. + +### Support on Linux + +Large page support on Linux is obtained by the Linux kernel +transparent huge pages functionality. Typically, transparent huge pages +are already enabled, and no configuration is needed. + +### Support on Windows + +The use of large pages requires "Lock Pages in Memory" privilege. See +[Enable the Lock Pages in Memory Option (Windows)](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows) +on how to enable this privilege, then run [RAMMap](https://docs.microsoft.com/en-us/sysinternals/downloads/rammap) +to double-check that large pages are used. We suggest that you reboot +your computer after you have enabled large pages, because long Windows +sessions suffer from memory fragmentation, which may prevent Stockfish +from getting large pages: a fresh session is better in this regard. + +## Compiling Stockfish yourself from the sources + +Stockfish has support for 32 or 64-bit CPUs, certain hardware +instructions, big-endian machines such as Power PC, and other platforms. + +On Unix-like systems, it should be easy to compile Stockfish +directly from the source code with the included Makefile in the folder +`src`. In general it is recommended to run `make help` to see a list of make +targets with corresponding descriptions. + +``` + cd src + make help + make net + make build ARCH=x86-64-modern +``` + +When not using the Makefile to compile (for instance, with Microsoft MSVC) you +need to manually set/unset some switches in the compiler command line; see +file *types.h* for a quick reference. + +When reporting an issue or a bug, please tell us which Stockfish version +and which compiler you used to create your executable. This information +can be found by typing the following command in a console: + +``` + ./stockfish compiler +``` + +## Understanding the code base and participating in the project + +Stockfish's improvement over the last decade has been a great community +effort. There are a few ways to help contribute to its growth. + +### Donating hardware + +Improving Stockfish requires a massive amount of testing. You can donate +your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker:-overview) +and view the current tests on [Fishtest](https://tests.stockfishchess.org/tests). + +### Improving the code + +If you want to help improve the code, there are several valuable resources: + +* [In this wiki,](https://www.chessprogramming.org) many techniques used in +Stockfish are explained with a lot of background information. + +* [The section on Stockfish](https://www.chessprogramming.org/Stockfish) +describes many features and techniques used by Stockfish. However, it is +generic rather than being focused on Stockfish's precise implementation. +Nevertheless, a helpful resource. + +* The latest source can always be found on [GitHub](https://github.com/official-stockfish/Stockfish). +Discussions about Stockfish take place these days mainly in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking) +group and on the [Stockfish Discord channel](https://discord.gg/nv8gDtt). +The engine testing is done on [Fishtest](https://tests.stockfishchess.org/tests). +If you want to help improve Stockfish, please read this [guideline](https://github.com/glinscott/fishtest/wiki/Creating-my-first-test) +first, where the basics of Stockfish development are explained. + + +## Terms of use + +Stockfish is free, and distributed under the **GNU General Public License version 3** +(GPL v3). Essentially, this means you are free to do almost exactly +what you want with the program, including distributing it among your +friends, making it available for download from your website, selling +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. + +The only real limitation is that whenever you distribute Stockfish in +some way, you MUST always include the full source code, or a pointer +to where the source code can be found, to generate the exact binary +you are distributing. If you make any changes to the source code, +these changes must also be made available under the GPL. + +For full details, read the copy of the GPL v3 found in the file named +*Copying.txt*. diff --git a/src/Makefile b/src/Makefile index 86d00d95..cc0f7391 100644 --- a/src/Makefile +++ b/src/Makefile @@ -52,8 +52,8 @@ SRCS = benchmark.cpp bitbase.cpp bitboard.cpp endgame.cpp evaluate.cpp main.cpp nnue/evaluate_nnue.cpp \ nnue/features/half_kp.cpp \ tools/sfen_packer.cpp \ - tools/gensfen.cpp \ - tools/gensfen_nonpv.cpp \ + tools/training_data_generator.cpp \ + tools/training_data_generator_nonpv.cpp \ tools/opening_book.cpp \ tools/convert.cpp \ tools/transform.cpp \ @@ -113,7 +113,6 @@ else SUPPORTED_ARCH=false endif -blas = no optimize = yes debug = no sanitize = no @@ -309,9 +308,9 @@ endif ### ========================================================================== ### 3.1 Selecting compiler (default = gcc) -CXXFLAGS += -g -Wall -Wcast-qual -fno-exceptions -std=c++17 -fopenmp -I. $(EXTRACXXFLAGS) -LDFLAGS += -fopenmp $(EXTRALDFLAGS) -DEPENDFLAGS += -std=c++17 -I. +CXXFLAGS += -Wall -Wcast-qual -fno-exceptions -std=c++17 -I. $(EXTRACXXFLAGS) +DEPENDFLAGS += -std=c++17 +LDFLAGS += $(EXTRALDFLAGS) ifeq ($(COMP),) COMP=gcc @@ -465,28 +464,6 @@ ifneq ($(comp),mingw) endif endif -### 3.2.1. BLAS libraries -ifeq ($(blas), yes) - LDFLAGS += -lopenblas - - ifeq ($(KERNEL),Linux) - LDFLAGS += - else ifeq ($(KERNEL), Darwin) - CXXFLAGS += -I/usr/local/opt/openblas/include - LDFLAGS += -L/usr/local/opt/openblas/lib -lcblas - else - CXXFLAGS += -I/mingw64/include/OpenBLAS - - ifeq ($(debug),yes) - LDFLAGS += -Wl,-static - else - LDFLAGS += -Wl,-s -static - endif - endif - - CXXFLAGS += -DUSE_BLAS -endif - ### 3.2.2 Debugging ifeq ($(debug),no) CXXFLAGS += -DNDEBUG @@ -809,12 +786,12 @@ net: # clean binaries and objects objclean: - @rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o ./learn/*.o ./extra/*.o ./eval/*.o + @rm -f $(EXE) *.o ./syzygy/*.o ./nnue/*.o ./nnue/features/*.o ./tools/*.o ./extra/*.o ./eval/*.o # clean auxiliary profiling files profileclean: @rm -rf profdir - @rm -f bench.txt *.gcda *.gcno ./syzygy/*.gcda ./nnue/*.gcda ./nnue/features/*.gcda *.s ./learn/*.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 $(PGO_TRAINING_DATA_FILE) diff --git a/src/misc.cpp b/src/misc.cpp index e47e2649..b58695ec 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -664,85 +664,4 @@ void sleep(int ms) std::this_thread::sleep_for(std::chrono::milliseconds(ms)); } -void* aligned_malloc(size_t size, size_t align) -{ - void* p = _mm_malloc(size, align); - if (p == nullptr) - { - std::cout << "info string can't allocate memory. sise = " << size << std::endl; - exit(1); - } - return p; -} - -std::uint64_t get_file_size(std::fstream& fs) -{ - auto pos = fs.tellg(); - - fs.seekg(0, fstream::end); - const uint64_t eofPos = (uint64_t)fs.tellg(); - fs.clear(); // Otherwise, the next seek may fail. - fs.seekg(0, fstream::beg); - const uint64_t begPos = (uint64_t)fs.tellg(); - fs.seekg(pos); - - return eofPos - begPos; -} - -int read_file_to_memory(std::string filename, std::function callback_func) -{ - fstream fs(filename, ios::in | ios::binary); - if (fs.fail()) - return 1; - - const uint64_t file_size = get_file_size(fs); - //std::cout << "filename = " << filename << " , file_size = " << file_size << endl; - - // I know the file size, so call callback_func to get a buffer for this, - // Get the pointer. - void* ptr = callback_func(file_size); - - // If the buffer could not be secured, or if the file size is different from the expected file size, - // It is supposed to return nullptr. At this time, reading is interrupted and an error is returned. - if (ptr == nullptr) - return 2; - - // read in pieces - - const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to read in one read (1GB) - for (uint64_t pos = 0; pos < file_size; pos += block_size) - { - // size to read this time - uint64_t read_size = (pos + block_size < file_size) ? block_size : (file_size - pos); - fs.read((char*)ptr + pos, read_size); - - // Read error occurred in the middle of the file. - if (fs.fail()) - return 2; - - //cout << "."; - } - fs.close(); - - return 0; -} - -int write_memory_to_file(std::string filename, void* ptr, uint64_t size) -{ - fstream fs(filename, ios::out | ios::binary); - if (fs.fail()) - return 1; - - const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to write in one write (1GB) - for (uint64_t pos = 0; pos < size; pos += block_size) - { - // Memory size to write this time - uint64_t write_size = (pos + block_size < size) ? block_size : (size - pos); - fs.write((char*)ptr + pos, write_size); - //cout << "."; - } - fs.close(); - return 0; -} - } // namespace Stockfish diff --git a/src/misc.h b/src/misc.h index 6eb8b1ae..b7d3c78a 100644 --- a/src/misc.h +++ b/src/misc.h @@ -489,91 +489,10 @@ private: namespace WinProcGroup { void bindThisThread(size_t idx); } -// sleep for the specified number of milliseconds. -extern void sleep(int ms); // Returns a string that represents the current time. (Used for log output when learning evaluation function) std::string now_string(); - -// When compiled with gcc/clang such as msys2, Windows Subsystem for Linux, -// In C++ std::ifstream, ::read() is a wrapper for that because it is not possible to read and write files larger than 2GB in one shot. -// -// callback_func of the argument of read_file_to_memory() uses the file size as an argument when the file can be opened -// It will be called back, so if you allocate a buffer and pass a function that returns the first pointer, it will be read there. -// These functions return non-zero on error, such as when the file cannot be found. -// -// Also, if the buffer cannot be allocated in the callback function or if the file size is different from the expected file size, -// Return nullptr. At this time, read_file_to_memory() interrupts reading and returns with an error. - -std::uint64_t get_file_size(std::fstream& fs); -int read_file_to_memory(std::string filename, std::function callback_func); -int write_memory_to_file(std::string filename, void* ptr, uint64_t size); - -// -------------------- -// async version of PRNG -// -------------------- - -// async version of PRNG -struct AsyncPRNG -{ - AsyncPRNG() : prng() { } - AsyncPRNG(uint64_t seed) : prng(seed) { assert(seed); } - AsyncPRNG(const std::string& seed) : prng(seed) { } - // [ASYNC] Extract one random number. - template T rand() { - std::unique_lock lk(mutex); - return prng.rand(); - } - - // [ASYNC] Returns a random number from 0 to n-1. (Not uniform distribution, but this is enough in reality) - uint64_t rand(uint64_t n) { - std::unique_lock lk(mutex); - return prng.rand(n); - } - - // Return the random seed used internally. - uint64_t get_seed() const { return prng.get_seed(); } - -protected: - std::mutex mutex; - PRNG prng; -}; - -// Display a random seed. (For debugging) -inline std::ostream& operator<<(std::ostream& os, AsyncPRNG& prng) -{ - os << "AsyncPRNG::seed = " << std::hex << prng.get_seed() << std::dec; - return os; -} - -// -------------------- -// Math -// -------------------- - -// Mathematical function used for progress calculation and learning -namespace Math { - inline double sigmoid(double x) - { - return 1.0 / (1.0 + std::exp(-x)); - } - - inline double dsigmoid(double x) - { - // Sigmoid function - // f(x) = 1/(1+exp(-x)) - // the first derivative is - // f'(x) = df/dx = f(x)・{ 1-f(x)} - // becomes - - return sigmoid(x) * (1.0 - sigmoid(x)); - } - - // Clip v so that it fits between [lo,hi]. - // * In Stockfish, this function is written in bitboard.h. - template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { - return v < lo ? lo : v > hi ? hi : v; - } -} +void sleep(int ms); namespace Algo { // Fisher-Yates diff --git a/src/nnue/architectures/halfkp_256x2-32-32.h b/src/nnue/architectures/halfkp_256x2-32-32.h index 21308368..a6768204 100644 --- a/src/nnue/architectures/halfkp_256x2-32-32.h +++ b/src/nnue/architectures/halfkp_256x2-32-32.h @@ -2,18 +2,18 @@ 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ // Definition of input features and network structure used in NNUE evaluation function @@ -21,33 +21,33 @@ #ifndef NNUE_HALFKP_256X2_32_32_H_INCLUDED #define NNUE_HALFKP_256X2_32_32_H_INCLUDED -#include "nnue/features/feature_set.h" -#include "nnue/features/half_kp.h" +#include "../features/feature_set.h" +#include "../features/half_kp.h" -#include "nnue/layers/input_slice.h" -#include "nnue/layers/affine_transform.h" -#include "nnue/layers/clipped_relu.h" +#include "../layers/input_slice.h" +#include "../layers/affine_transform.h" +#include "../layers/clipped_relu.h" namespace Stockfish::Eval::NNUE { - // Input features used in evaluation function - using RawFeatures = Features::FeatureSet< - Features::HalfKP>; +// Input features used in evaluation function +using RawFeatures = Features::FeatureSet< + Features::HalfKP>; - // Number of input feature dimensions after conversion - constexpr IndexType kTransformedFeatureDimensions = 256; +// Number of input feature dimensions after conversion +constexpr IndexType kTransformedFeatureDimensions = 256; - namespace Layers { +namespace Layers { - // Define network structure - using InputLayer = InputSlice; - using HiddenLayer1 = ClippedReLU>; - using HiddenLayer2 = ClippedReLU>; - using OutputLayer = AffineTransform; +// Define network structure +using InputLayer = InputSlice; +using HiddenLayer1 = ClippedReLU>; +using HiddenLayer2 = ClippedReLU>; +using OutputLayer = AffineTransform; - } // namespace Layers +} // namespace Layers - using Network = Layers::OutputLayer; +using Network = Layers::OutputLayer; } // namespace Stockfish::Eval::NNUE diff --git a/src/nnue/evaluate_nnue.cpp b/src/nnue/evaluate_nnue.cpp index 7b2a1ae8..5416f13e 100644 --- a/src/nnue/evaluate_nnue.cpp +++ b/src/nnue/evaluate_nnue.cpp @@ -1,14 +1,17 @@ /* 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 . */ @@ -138,4 +141,4 @@ namespace Stockfish::Eval::NNUE { return ReadParameters(stream); } -} // namespace Stockfish::Eval::NNUE \ No newline at end of file +} // namespace Stockfish::Eval::NNUE diff --git a/src/nnue/evaluate_nnue.h b/src/nnue/evaluate_nnue.h index 010a89f7..24aa6cc0 100644 --- a/src/nnue/evaluate_nnue.h +++ b/src/nnue/evaluate_nnue.h @@ -1,14 +1,17 @@ /* 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 . */ @@ -53,4 +56,4 @@ namespace Stockfish::Eval::NNUE { } // namespace Stockfish::Eval::NNUE -#endif // #ifndef NNUE_EVALUATE_NNUE_H_INCLUDED \ No newline at end of file +#endif // #ifndef NNUE_EVALUATE_NNUE_H_INCLUDED diff --git a/src/nnue/features/feature_set.h b/src/nnue/features/feature_set.h index fb25bce5..a3fea9c0 100644 --- a/src/nnue/features/feature_set.h +++ b/src/nnue/features/feature_set.h @@ -1,14 +1,17 @@ /* 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 . */ @@ -63,4 +66,4 @@ namespace Stockfish::Eval::NNUE::Features { } // namespace Stockfish::Eval::NNUE::Features -#endif // #ifndef NNUE_FEATURE_SET_H_INCLUDED \ No newline at end of file +#endif // #ifndef NNUE_FEATURE_SET_H_INCLUDED diff --git a/src/nnue/features/half_kp.cpp b/src/nnue/features/half_kp.cpp index 05eb1a9a..8e6907ae 100644 --- a/src/nnue/features/half_kp.cpp +++ b/src/nnue/features/half_kp.cpp @@ -2,18 +2,18 @@ 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ //Definition of input features HalfKP of NNUE evaluation function diff --git a/src/nnue/features/half_kp.h b/src/nnue/features/half_kp.h index 3c94778d..2461acb7 100644 --- a/src/nnue/features/half_kp.h +++ b/src/nnue/features/half_kp.h @@ -2,23 +2,26 @@ 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ +//Definition of input features HalfKP of NNUE evaluation function + #ifndef NNUE_FEATURES_HALF_KP_H_INCLUDED #define NNUE_FEATURES_HALF_KP_H_INCLUDED +#include "../../evaluate.h" #include "features_common.h" namespace Stockfish::Eval::NNUE::Features { diff --git a/src/nnue/layers/affine_transform.h b/src/nnue/layers/affine_transform.h index 3e54ab7f..1faa180d 100644 --- a/src/nnue/layers/affine_transform.h +++ b/src/nnue/layers/affine_transform.h @@ -1,14 +1,17 @@ /* 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 . */ @@ -458,4 +461,4 @@ namespace Stockfish::Eval::NNUE::Layers { } // namespace Stockfish::Eval::NNUE::Layers -#endif // #ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED \ No newline at end of file +#endif // #ifndef NNUE_LAYERS_AFFINE_TRANSFORM_H_INCLUDED diff --git a/src/nnue/layers/clipped_relu.h b/src/nnue/layers/clipped_relu.h index 7efb0a0b..a10e3e48 100644 --- a/src/nnue/layers/clipped_relu.h +++ b/src/nnue/layers/clipped_relu.h @@ -47,8 +47,6 @@ namespace Stockfish::Eval::NNUE::Layers { static constexpr std::size_t kBufferSize = PreviousLayer::kBufferSize + kSelfBufferSize; - static constexpr int kLayerIndex = PreviousLayer::kLayerIndex + 1; - // Hash value embedded in the evaluation file static constexpr std::uint32_t GetHashValue() { std::uint32_t hash_value = 0x538D24C7u; @@ -56,36 +54,11 @@ namespace Stockfish::Eval::NNUE::Layers { return hash_value; } - static std::string get_name() { - return "ClippedReLU[" + - std::to_string(kOutputDimensions) + "]"; - } - - // A string that represents the structure from the input layer to this layer - static std::string get_structure_string() { - return get_name() + "(" + - PreviousLayer::get_structure_string() + ")"; - } - - static std::string get_layers_info() { - std::string info = PreviousLayer::get_layers_info(); - info += "\n - "; - info += std::to_string(kLayerIndex); - info += " - "; - info += get_name(); - return info; - } - // Read network parameters bool ReadParameters(std::istream& stream) { return previous_layer_.ReadParameters(stream); } - // write parameters - bool WriteParameters(std::ostream& stream) const { - return previous_layer_.WriteParameters(stream); - } - // Forward propagation const OutputType* Propagate( const TransformedFeatureType* transformed_features, char* buffer) const { @@ -185,9 +158,6 @@ namespace Stockfish::Eval::NNUE::Layers { } private: - // Make the learning class a friend - friend class Trainer; - PreviousLayer previous_layer_; }; diff --git a/src/nnue/layers/input_slice.h b/src/nnue/layers/input_slice.h index f7dab19e..9a7ce92e 100644 --- a/src/nnue/layers/input_slice.h +++ b/src/nnue/layers/input_slice.h @@ -41,8 +41,6 @@ class InputSlice { // Size of forward propagation buffer used from the input layer to this layer static constexpr std::size_t kBufferSize = 0; - static constexpr int kLayerIndex = 1; - // Hash value embedded in the evaluation file static constexpr std::uint32_t GetHashValue() { std::uint32_t hash_value = 0xEC42E90Du; @@ -50,35 +48,10 @@ class InputSlice { return hash_value; } - static std::string get_name() { - return "InputSlice[" + std::to_string(kOutputDimensions) + "(" + - std::to_string(Offset) + ":" + - std::to_string(Offset + kOutputDimensions) + ")]"; - } - - // A string that represents the structure from the input layer to this layer - static std::string get_structure_string() { - return get_name(); - } - - static std::string get_layers_info() { - std::string info = " - "; - info += std::to_string(kLayerIndex); - info += " - "; - info += get_name(); - return info; - } - // Read network parameters bool ReadParameters(std::istream& /*stream*/) { return true; } - - // write parameters - bool WriteParameters(std::ostream& /*stream*/) const { - return true; - } - // Forward propagation const OutputType* Propagate( const TransformedFeatureType* transformed_features, diff --git a/src/nnue/nnue_accumulator.h b/src/nnue/nnue_accumulator.h index 5da4ecb5..55fafa13 100644 --- a/src/nnue/nnue_accumulator.h +++ b/src/nnue/nnue_accumulator.h @@ -1,14 +1,17 @@ /* 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 . */ @@ -34,4 +37,4 @@ namespace Stockfish::Eval::NNUE { } // namespace Stockfish::Eval::NNUE -#endif // NNUE_ACCUMULATOR_H_INCLUDED \ No newline at end of file +#endif // NNUE_ACCUMULATOR_H_INCLUDED diff --git a/src/nnue/nnue_common.h b/src/nnue/nnue_common.h index 1479d6b3..bfd0738e 100644 --- a/src/nnue/nnue_common.h +++ b/src/nnue/nnue_common.h @@ -25,13 +25,6 @@ #include #include -#if defined(__GNUC__ ) && (__GNUC__ < 8) -#include -namespace sys = std::experimental::filesystem; -#else -#include -namespace sys = std::filesystem; -#endif #if defined(USE_AVX2) #include @@ -112,10 +105,6 @@ namespace Stockfish::Eval::NNUE { using TransformedFeatureType = std::uint8_t; using IndexType = std::uint32_t; - // Forward declaration of learning class template - template - class Trainer; - // Round n up to be a multiple of base template constexpr IntType CeilToMultiple(IntType n, IntType base) { diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index b5c8f40e..1e0b0e6d 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -1,14 +1,17 @@ /* 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 . */ @@ -411,4 +414,4 @@ namespace Stockfish::Eval::NNUE { } // namespace Stockfish::Eval::NNUE -#endif // #ifndef NNUE_FEATURE_TRANSFORMER_H_INCLUDED \ No newline at end of file +#endif // #ifndef NNUE_FEATURE_TRANSFORMER_H_INCLUDED diff --git a/src/position.cpp b/src/position.cpp index c515f253..8ef516b6 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1007,10 +1007,10 @@ void Position::do_null_move(StateInfo& newSt) { st = &newSt; // Used by NNUE + st->dirtyPiece.dirty_num = 0; + st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator() st->accumulator.state[WHITE] = Eval::NNUE::EMPTY; st->accumulator.state[BLACK] = Eval::NNUE::EMPTY; - auto& dp = st->dirtyPiece; - dp.dirty_num = 0; if (st->epSquare != SQ_NONE) { diff --git a/src/tools/convert.cpp b/src/tools/convert.cpp index 0be7070c..03f3e4a7 100644 --- a/src/tools/convert.cpp +++ b/src/tools/convert.cpp @@ -25,8 +25,10 @@ #include #include #include +#include using namespace std; +namespace sys = std::filesystem; namespace Stockfish::Tools { @@ -123,7 +125,7 @@ namespace Stockfish::Tools score = (score - src_score_min_value) / (src_score_max_value - src_score_min_value); // Scale to [dest_score_min_value, dest_score_max_value]. score = score * (dest_score_max_value - dest_score_min_value) + dest_score_min_value; - p.score = Math::clamp((int32_t)std::round(score), -(int32_t)VALUE_MATE, (int32_t)VALUE_MATE); + p.score = std::clamp((int32_t)std::round(score), -(int32_t)VALUE_MATE, (int32_t)VALUE_MATE); } else if (token == "ply") { int temp; @@ -414,7 +416,7 @@ namespace Stockfish::Tools Value value = parse_score_from_pgn_extract(str_eval, success); if (success) { eval_found = true; - psv.score = Math::clamp(value, -VALUE_MATE, VALUE_MATE); + psv.score = std::clamp(value, -VALUE_MATE, VALUE_MATE); } #if defined(DEBUG_CONVERT_BIN_FROM_PGN_EXTRACT) diff --git a/src/tools/gensfen.cpp b/src/tools/training_data_generator.cpp similarity index 97% rename from src/tools/gensfen.cpp rename to src/tools/training_data_generator.cpp index 1e721a3e..10f84fe5 100644 --- a/src/tools/gensfen.cpp +++ b/src/tools/training_data_generator.cpp @@ -1,4 +1,4 @@ -#include "gensfen.h" +#include "training_data_generator.h" #include "sfen_writer.h" #include "packed_sfen.h" @@ -37,7 +37,7 @@ using namespace std; namespace Stockfish::Tools { // Class to generate sfen with multiple threads - struct Gensfen + struct TrainingDataGenerator { struct Params { @@ -123,7 +123,7 @@ namespace Stockfish::Tools static constexpr uint64_t REPORT_STATS_EVERY = 200000; static_assert(REPORT_STATS_EVERY % REPORT_DOT_EVERY == 0); - Gensfen( + TrainingDataGenerator( const Params& prm ) : params(prm), @@ -205,7 +205,7 @@ namespace Stockfish::Tools void maybe_report(uint64_t done); }; - void Gensfen::set_gensfen_search_limits() + void TrainingDataGenerator::set_gensfen_search_limits() { // About Search::Limits // Be careful because this member variable is global and affects other threads. @@ -224,7 +224,7 @@ namespace Stockfish::Tools limits.depth = 0; } - void Gensfen::generate(uint64_t limit) + void TrainingDataGenerator::generate(uint64_t limit) { last_stats_report_time = 0; @@ -246,7 +246,7 @@ namespace Stockfish::Tools std::cout << std::endl; } - void Gensfen::generate_worker( + void TrainingDataGenerator::generate_worker( Thread& th, std::atomic& counter, uint64_t limit) @@ -449,7 +449,7 @@ namespace Stockfish::Tools } } - bool Gensfen::was_seen_before(const Position& pos) + bool TrainingDataGenerator::was_seen_before(const Position& pos) { // Look into the position hashtable to see if the same // position was seen before. @@ -470,7 +470,7 @@ namespace Stockfish::Tools } } - optional Gensfen::get_current_game_result( + optional TrainingDataGenerator::get_current_game_result( Position& pos, const vector& move_hist_scores) const { @@ -591,7 +591,7 @@ namespace Stockfish::Tools return nullopt; } - vector Gensfen::generate_random_move_flags(PRNG& prng) + vector TrainingDataGenerator::generate_random_move_flags(PRNG& prng) { vector random_move_flag; @@ -628,7 +628,7 @@ namespace Stockfish::Tools return random_move_flag; } - optional Gensfen::choose_random_move( + optional TrainingDataGenerator::choose_random_move( PRNG& prng, Position& pos, std::vector& random_move_flag, @@ -725,7 +725,7 @@ namespace Stockfish::Tools // 1 when winning. -1 when losing. Pass 0 for a draw. // Return value: true if the specified number of // sfens has already been reached and the process ends. - bool Gensfen::commit_psv( + bool TrainingDataGenerator::commit_psv( Thread& th, PSVector& sfens, int8_t result, @@ -770,7 +770,7 @@ namespace Stockfish::Tools return false; } - void Gensfen::report(uint64_t done, uint64_t new_done) + void TrainingDataGenerator::report(uint64_t done, uint64_t new_done) { const auto now_time = now(); const TimePoint elapsed = now_time - last_stats_report_time + 1; @@ -786,7 +786,7 @@ namespace Stockfish::Tools out = sync_region_cout.new_region(); } - void Gensfen::maybe_report(uint64_t done) + void TrainingDataGenerator::maybe_report(uint64_t done) { if (done % REPORT_DOT_EVERY == 0) { @@ -811,12 +811,12 @@ namespace Stockfish::Tools } // Command to generate a game record - void gensfen(istringstream& is) + void generate_training_data(istringstream& is) { // Number of generated game records default = 8 billion phases (Ponanza specification) uint64_t loop_max = 8000000000UL; - Gensfen::Params params; + TrainingDataGenerator::Params params; // Add a random number to the end of the file name. bool random_file_name = false; @@ -966,9 +966,9 @@ namespace Stockfish::Tools Threads.main()->ponder = false; - Gensfen gensfen(params); + TrainingDataGenerator gensfen(params); gensfen.generate(loop_max); - std::cout << "INFO: Gensfen finished." << endl; + std::cout << "INFO: TrainingDataGenerator finished." << endl; } } diff --git a/src/tools/gensfen.h b/src/tools/training_data_generator.h similarity index 75% rename from src/tools/gensfen.h rename to src/tools/training_data_generator.h index a8505474..9a105155 100644 --- a/src/tools/gensfen.h +++ b/src/tools/training_data_generator.h @@ -8,7 +8,7 @@ namespace Stockfish::Tools { // Automatic generation of teacher position - void gensfen(std::istringstream& is); + void generate_training_data(std::istringstream& is); } #endif \ No newline at end of file diff --git a/src/tools/gensfen_nonpv.cpp b/src/tools/training_data_generator_nonpv.cpp similarity index 95% rename from src/tools/gensfen_nonpv.cpp rename to src/tools/training_data_generator_nonpv.cpp index 9775f80e..247c18a4 100644 --- a/src/tools/gensfen_nonpv.cpp +++ b/src/tools/training_data_generator_nonpv.cpp @@ -1,4 +1,4 @@ -#include "gensfen_nonpv.h" +#include "training_data_generator_nonpv.h" #include "sfen_writer.h" #include "packed_sfen.h" @@ -37,7 +37,7 @@ using namespace std; namespace Stockfish::Tools { // Class to generate sfen with multiple threads - struct GensfenNonPv + struct TrainingDataGeneratorNonPv { struct Params { @@ -89,7 +89,7 @@ namespace Stockfish::Tools static constexpr uint64_t REPORT_STATS_EVERY = 200000; static_assert(REPORT_STATS_EVERY % REPORT_DOT_EVERY == 0); - GensfenNonPv( + TrainingDataGeneratorNonPv( const Params& prm ) : params(prm), @@ -148,7 +148,7 @@ namespace Stockfish::Tools void maybe_report(uint64_t done); }; - void GensfenNonPv::set_gensfen_search_limits() + void TrainingDataGeneratorNonPv::set_gensfen_search_limits() { // About Search::Limits // Be careful because this member variable is global and affects other threads. @@ -167,7 +167,7 @@ namespace Stockfish::Tools limits.depth = 0; } - void GensfenNonPv::generate(uint64_t limit) + void TrainingDataGeneratorNonPv::generate(uint64_t limit) { last_stats_report_time = 0; @@ -189,7 +189,7 @@ namespace Stockfish::Tools std::cout << std::endl; } - PSVector GensfenNonPv::do_exploration( + PSVector TrainingDataGeneratorNonPv::do_exploration( Thread& th, int count) { @@ -253,7 +253,7 @@ namespace Stockfish::Tools return psv; } - void GensfenNonPv::generate_worker( + void TrainingDataGeneratorNonPv::generate_worker( Thread& th, std::atomic& counter, uint64_t limit) @@ -323,7 +323,7 @@ namespace Stockfish::Tools // 1 when winning. -1 when losing. Pass 0 for a draw. // Return value: true if the specified number of // sfens has already been reached and the process ends. - bool GensfenNonPv::commit_psv( + bool TrainingDataGeneratorNonPv::commit_psv( Thread& th, PSVector& sfens, std::atomic& counter, @@ -347,7 +347,7 @@ namespace Stockfish::Tools return false; } - void GensfenNonPv::report(uint64_t done, uint64_t new_done) + void TrainingDataGeneratorNonPv::report(uint64_t done, uint64_t new_done) { const auto now_time = now(); const TimePoint elapsed = now_time - last_stats_report_time + 1; @@ -363,7 +363,7 @@ namespace Stockfish::Tools out = sync_region_cout.new_region(); } - void GensfenNonPv::maybe_report(uint64_t done) + void TrainingDataGeneratorNonPv::maybe_report(uint64_t done) { if (done % REPORT_DOT_EVERY == 0) { @@ -388,10 +388,10 @@ namespace Stockfish::Tools } // Command to generate a game record - void gensfen_nonpv(istringstream& is) + void generate_training_data_nonpv(istringstream& is) { // Number of generated game records default = 8 billion phases (Ponanza specification) - GensfenNonPv::Params params; + TrainingDataGeneratorNonPv::Params params; uint64_t count = 1'000'000; @@ -480,7 +480,7 @@ namespace Stockfish::Tools Threads.main()->ponder = false; - GensfenNonPv gensfen(params); + TrainingDataGeneratorNonPv gensfen(params); gensfen.generate(count); std::cout << "INFO: gensfen_nonpv finished." << endl; diff --git a/src/tools/gensfen_nonpv.h b/src/tools/training_data_generator_nonpv.h similarity index 71% rename from src/tools/gensfen_nonpv.h rename to src/tools/training_data_generator_nonpv.h index 842dd70b..8bd093cb 100644 --- a/src/tools/gensfen_nonpv.h +++ b/src/tools/training_data_generator_nonpv.h @@ -6,7 +6,7 @@ namespace Stockfish::Tools { // Automatic generation of teacher position - void gensfen_nonpv(std::istringstream& is); + void generate_training_data_nonpv(std::istringstream& is); } #endif \ No newline at end of file diff --git a/src/uci.cpp b/src/uci.cpp index fdce17aa..6f5b28a9 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -33,8 +33,8 @@ #include "tt.h" #include "uci.h" -#include "tools/gensfen.h" -#include "tools/gensfen_nonpv.h" +#include "tools/training_data_generator.h" +#include "tools/training_data_generator_nonpv.h" #include "tools/convert.h" #include "tools/transform.h" #include "tools/stats.h" @@ -209,14 +209,7 @@ void UCI::setoption(const std::string& name, const std::string& value) // The win rate model returns the probability (per mille) of winning given an eval // and a game-ply. The model fits rather accurately the LTC fishtest statistics. -int UCI::win_rate_model(Value v, int ply) { - // Return win rate in per mille (rounded to nearest) - return int(0.5 + win_rate_model_double(v, ply)); -} - -// The win rate model returns the probability (per mille) of winning given an eval -// and a game-ply. The model fits rather accurately the LTC fishtest statistics. -double UCI::win_rate_model_double(double v, int ply) { +int win_rate_model(Value v, int ply) { // The model captures only up to 240 plies, so limit input (and rescale) double m = std::min(240, ply) / 64.0; @@ -230,10 +223,10 @@ double UCI::win_rate_model_double(double v, int ply) { double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3]; // Transform eval to centipawns with limited range - double x = std::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0); + double x = std::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0); - // Return win rate in per mille - return 1000.0 / (1 + std::exp((a - x) / b)); + // Return win rate in per mille (rounded to nearest) + return int(0.5 + 1000 / (1 + std::exp((a - x) / b))); } // -------------------- @@ -327,8 +320,8 @@ void UCI::loop(int argc, char* argv[]) { else if (token == "eval") trace_eval(pos); else if (token == "compiler") sync_cout << compiler_info() << sync_endl; - else if (token == "gensfen") Tools::gensfen(is); - else if (token == "gensfen_nonpv") Tools::gensfen_nonpv(is); + else if (token == "generate_training_data") Tools::generate_training_data(is); + else if (token == "generate_training_data") Tools::generate_training_data_nonpv(is); else if (token == "convert") Tools::convert(is); else if (token == "convert_bin") Tools::convert_bin(is); else if (token == "convert_plain") Tools::convert_plain(is); diff --git a/src/uci.h b/src/uci.h index b27445aa..9e4c6e2f 100644 --- a/src/uci.h +++ b/src/uci.h @@ -74,8 +74,6 @@ std::string square(Square s); std::string move(Move m, bool chess960); std::string pv(const Position& pos, Depth depth, Value alpha, Value beta); std::string wdl(Value v, int ply); -int win_rate_model(Value v, int ply); -double win_rate_model_double(double v, int ply); Move to_move(const Position& pos, std::string& str); void setoption(const std::string& name, const std::string& value); diff --git a/stockfish.md b/stockfish.md deleted file mode 100644 index 823518d1..00000000 --- a/stockfish.md +++ /dev/null @@ -1,242 +0,0 @@ -## Overview - -[![Build Status](https://travis-ci.org/official-stockfish/Stockfish.svg?branch=master)](https://travis-ci.org/official-stockfish/Stockfish) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/official-stockfish/Stockfish?branch=master&svg=true)](https://ci.appveyor.com/project/mcostalba/stockfish/branch/master) - -[Stockfish](https://stockfishchess.org) is a free, powerful UCI chess engine -derived from Glaurung 2.1. It is not a complete chess program and requires a -UCI-compatible GUI (e.g. XBoard with PolyGlot, Scid, Cute Chess, eboard, Arena, -Sigma Chess, Shredder, Chess Partner or Fritz) in order to be used comfortably. -Read the documentation for your GUI of choice for information about how to use -Stockfish with it. - - -## Files - -This distribution of Stockfish consists of the following files: - - * Readme.md, the file you are currently reading. - - * Copying.txt, a text file containing the GNU General Public License version 3. - - * src, a subdirectory containing the full source code, including a Makefile - that can be used to compile Stockfish on Unix-like systems. - - -## UCI parameters - -Currently, Stockfish has the following UCI options: - - * #### Debug Log File - Write all communication to and from the engine into a text file. - - * #### Contempt - A positive value for contempt favors middle game positions and avoids draws. - - * #### Analysis Contempt - By default, contempt is set to prefer the side to move. Set this option to "White" - or "Black" to analyse with contempt for that side, or "Off" to disable contempt. - - * #### Threads - The number of CPU threads used for searching a position. For best performance, set - this equal to the number of CPU cores available. - - * #### Hash - The size of the hash table in MB. It is recommended to set Hash after setting Threads. - - * #### Clear Hash - Clear the hash table. - - * #### Ponder - Let Stockfish ponder its next move while the opponent is thinking. - - * #### MultiPV - Output the N best lines (principal variations, PVs) when searching. - Leave at 1 for best performance. - - * #### Skill Level - Lower the Skill Level in order to make Stockfish play weaker (see also UCI_LimitStrength). - Internally, MultiPV is enabled, and with a certain probability depending on the Skill Level a - weaker move will be played. - - * #### UCI_LimitStrength - Enable weaker play aiming for an Elo rating as set by UCI_Elo. This option overrides Skill Level. - - * #### UCI_Elo - If enabled by UCI_LimitStrength, aim for an engine strength of the given Elo. - This Elo rating has been calibrated at a time control of 60s+0.6s and anchored to CCRL 40/4. - - * #### UCI_ShowWDL - If enabled, show approximate WDL statistics as part of the engine output. - These WDL numbers model expected game outcomes for a given evaluation and - game ply for engine self-play at fishtest LTC conditions (60+0.6s per game). - - * #### Move Overhead - Assume a time delay of x ms due to network and GUI overheads. This is useful to - avoid losses on time in those cases. - - * #### Slow Mover - Lower values will make Stockfish take less time in games, higher values will - make it think longer. - - * #### nodestime - Tells the engine to use nodes searched instead of wall time to account for - elapsed time. Useful for engine testing. - - * #### UCI_Chess960 - An option handled by your GUI. If true, Stockfish will play Chess960. - - * #### UCI_AnalyseMode - An option handled by your GUI. - - * #### SyzygyPath - Path to the folders/directories storing the Syzygy tablebase files. Multiple - directories are to be separated by ";" on Windows and by ":" on Unix-based - operating systems. Do not use spaces around the ";" or ":". - - 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 - the .rtbz files on a regular HD. It is recommended to verify all md5 checksums - of the downloaded tablebase files (`md5sum -c checksum.md5`) as corruption will - lead to engine crashes. - - * #### SyzygyProbeDepth - Minimum remaining search depth for which a position is probed. Set this option - to a higher value to probe less agressively if you experience too much slowdown - (in terms of nps) due to TB probing. - - * #### Syzygy50MoveRule - Disable to let fifty-move rule draws detected by Syzygy tablebase probes count - as wins or losses. This is useful for ICCF correspondence games. - - * #### SyzygyProbeLimit - Limit Syzygy tablebase probing to positions with at most this many pieces left - (including kings and pawns). - - -## What to expect from Syzygybases? - -If the engine is searching a position that is not in the tablebases (e.g. -a position with 8 pieces), it will access the tablebases during the search. -If the engine reports a very large score (typically 153.xx), this means -that it has found a winning line into a tablebase position. - -If the engine is given a position to search that is in the tablebases, it -will use the tablebases at the beginning of the search to preselect all -good moves, i.e. all moves that preserve the win or preserve the draw while -taking into account the 50-move rule. -It will then perform a search only on those moves. **The engine will not move -immediately**, unless there is only a single good move. **The engine likely -will not report a mate score even if the position is known to be won.** - -It is therefore clear that this behaviour is not identical to what one might -be used to with Nalimov tablebases. There are technical reasons for this -difference, the main technical reason being that Nalimov tablebases use the -DTM metric (distance-to-mate), while Syzygybases use a variation of the -DTZ metric (distance-to-zero, zero meaning any move that resets the 50-move -counter). This special metric is one of the reasons that Syzygybases are -more compact than Nalimov tablebases, while still storing all information -needed for optimal play and in addition being able to take into account -the 50-move rule. - -## Large Pages - -Stockfish supports large pages on Linux and Windows. Large pages make -the hash access more efficient, improving the engine speed, especially -on large hash sizes. Typical increases are 5..10% in terms of nps, but -speed increases up to 30% have been measured. The support is -automatic. Stockfish attempts to use large pages when available and -will fall back to regular memory allocation when this is not the case. - -### Support on Linux - -Large page support on Linux is obtained by the Linux kernel -transparent huge pages functionality. Typically, transparent huge pages -are already enabled and no configuration is needed. - -### Support on Windows - -The use of large pages requires "Lock Pages in Memory" privilege. See -[Enable the Lock Pages in Memory Option (Windows)](https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows) -on how to enable this privilege. Logout/login may be needed -afterwards. Due to memory fragmentation, it may not always be -possible to allocate large pages even when enabled. A reboot -might alleviate this problem. To determine whether large pages -are in use, see the engine log. - -## Compiling Stockfish yourself from the sources - -Stockfish has support for 32 or 64-bit CPUs, certain hardware -instructions, big-endian machines such as Power PC, and other platforms. - -On Unix-like systems, it should be easy to compile Stockfish -directly from the source code with the included Makefile in the folder -`src`. In general it is recommended to run `make help` to see a list of make -targets with corresponding descriptions. - -``` - cd src - make help - make build ARCH=x86-64-modern -``` - -When not using the Makefile to compile (for instance with Microsoft MSVC) you -need to manually set/unset some switches in the compiler command line; see -file *types.h* for a quick reference. - -When reporting an issue or a bug, please tell us which version and -compiler you used to create your executable. These informations can -be found by typing the following commands in a console: - -``` - ./stockfish - compiler -``` - -## Understanding the code base and participating in the project - -Stockfish's improvement over the last couple of years has been a great -community effort. There are a few ways to help contribute to its growth. - -### Donating hardware - -Improving Stockfish requires a massive amount of testing. You can donate -your hardware resources by installing the [Fishtest Worker](https://github.com/glinscott/fishtest/wiki/Running-the-worker:-overview) -and view the current tests on [Fishtest](https://tests.stockfishchess.org/tests). - -### Improving the code - -If you want to help improve the code, there are several valuable resources: - -* [In this wiki,](https://www.chessprogramming.org) many techniques used in -Stockfish are explained with a lot of background information. - -* [The section on Stockfish](https://www.chessprogramming.org/Stockfish) -describes many features and techniques used by Stockfish. However, it is -generic rather than being focused on Stockfish's precise implementation. -Nevertheless, a helpful resource. - -* The latest source can always be found on [GitHub](https://github.com/official-stockfish/Stockfish). -Discussions about Stockfish take place in the [FishCooking](https://groups.google.com/forum/#!forum/fishcooking) -group and engine testing is done on [Fishtest](https://tests.stockfishchess.org/tests). -If you want to help improve Stockfish, please read this [guideline](https://github.com/glinscott/fishtest/wiki/Creating-my-first-test) -first, where the basics of Stockfish development are explained. - - -## Terms of use - -Stockfish is free, and distributed under the **GNU General Public License version 3** -(GPL v3). Essentially, this means that you are free to do almost exactly -what you want with the program, including distributing it among your -friends, making it available for download from your web site, selling -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. - -The only real limitation is that whenever you distribute Stockfish in -some way, you must always include the full source code, or a pointer -to where the source code can be found. If you make any changes to the -source code, these changes must also be made available under the GPL. - -For full details, read the copy of the GPL v3 found in the file named -*Copying.txt*. diff --git a/tests/instrumented.sh b/tests/instrumented.sh index 2f746a86..518d1087 100755 --- a/tests/instrumented.sh +++ b/tests/instrumented.sh @@ -24,7 +24,7 @@ case $1 in echo "valgrind-thread testing started" prefix='' exeprefix='valgrind --fair-sched=try --error-exitcode=42' - postfix='' + postfix='1>/dev/null' threads="2" bench_depth=5 go_depth=10 @@ -142,7 +142,57 @@ cat << EOF > syzygy.exp exit \$value EOF -for exp in game.exp +# generate_training_data testing 01 +cat << EOF > data_generation01.exp + set timeout 240 + spawn $exeprefix ./stockfish + + send "uci\n" + expect "uciok" + + send "setoption name Threads value $threads\n" + send "setoption name Use NNUE value false\n" + send "isready\n" + send "generate_training_data depth 3 count 100 keep_draws 1 eval_limit 32000 output_file_name training_data/training_data.bin output_format bin\n" + expect "INFO: Gensfen finished." + send "convert_plain targetfile training_data/training_data.bin output_file_name training_data.txt\n" + expect "all done" + send "generate_training_data depth 3 count 100 keep_draws 1 eval_limit 32000 output_file_name training_data/training_data.binpack output_format binpack\n" + expect "INFO: Gensfen finished." + + send "quit\n" + expect eof + + # return error code of the spawned program, useful for valgrind + lassign [wait] pid spawnid os_error_flag value + exit \$value +EOF + +# generate_training_data testing 02 +cat << EOF > data_generation02.exp + set timeout 240 + spawn $exeprefix ./stockfish + + send "uci\n" + expect "uciok" + + send "setoption name Threads value $threads\n" + send "setoption name Use NNUE value true\n" + send "isready\n" + send "generate_training_data depth 4 count 50 keep_draws 1 eval_limit 32000 output_file_name validation_data/validation_data.bin output_format bin\n" + expect "INFO: Gensfen finished." + send "generate_training_data depth 4 count 50 keep_draws 1 eval_limit 32000 output_file_name validation_data/validation_data.binpack output_format binpack\n" + expect "INFO: Gensfen finished." + + send "quit\n" + expect eof + + # return error code of the spawned program, useful for valgrind + lassign [wait] pid spawnid os_error_flag value + exit \$value +EOF + +for exp in game.exp data_generation01.exe data_generation02.exp do echo "$prefix expect $exp $postfix" diff --git a/tests/instrumented_learn.sh b/tests/instrumented_learn.sh deleted file mode 100755 index af8c8b17..00000000 --- a/tests/instrumented_learn.sh +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/bash -# check for errors under valgrind or sanitizers. - -error() -{ - echo "instrumented testing failed on line $1" - exit 1 -} -trap 'error ${LINENO}' ERR - -# define suitable post and prefixes for testing options -case $1 in - --valgrind) - echo "valgrind testing started" - prefix='' - exeprefix='valgrind --error-exitcode=42' - postfix='1>/dev/null' - threads="1" - ;; - --valgrind-thread) - echo "valgrind-thread testing started" - prefix='' - exeprefix='valgrind --fair-sched=try --error-exitcode=42' - postfix='1>/dev/null' - threads="2" - ;; - --sanitizer-undefined) - echo "sanitizer-undefined testing started" - prefix='!' - exeprefix='' - postfix='2>&1 | grep -A50 "runtime error:"' - threads="1" - ;; - --sanitizer-thread) - echo "sanitizer-thread testing started" - prefix='!' - exeprefix='' - postfix='2>&1 | grep -A50 "WARNING: ThreadSanitizer:"' - threads="2" - -cat << EOF > tsan.supp -race:TTEntry::move -race:TTEntry::depth -race:TTEntry::bound -race:TTEntry::save -race:TTEntry::value -race:TTEntry::eval -race:TTEntry::is_pv - -race:TranspositionTable::probe -race:TranspositionTable::hashfull - -EOF - - export TSAN_OPTIONS="suppressions=./tsan.supp" - - ;; - *) - echo "unknown testing started" - prefix='' - exeprefix='' - postfix='' - threads="1" - ;; -esac - -mkdir -p training_data -mkdir -p validation_data - -# gensfen testing 01 -cat << EOF > gensfen01.exp - set timeout 240 - spawn $exeprefix ./stockfish - - send "uci\n" - expect "uciok" - - send "setoption name Threads value $threads\n" - send "setoption name Use NNUE value false\n" - send "isready\n" - send "gensfen depth 3 loop 100 use_draw_in_training_data_generation 1 eval_limit 32000 output_file_name training_data/training_data.bin sfen_format bin\n" - expect "INFO: Gensfen finished." - send "convert_plain targetfile training_data/training_data.bin output_file_name training_data.txt\n" - expect "all done" - send "gensfen depth 3 loop 100 use_draw_in_training_data_generation 1 eval_limit 32000 output_file_name training_data/training_data.binpack sfen_format binpack\n" - expect "INFO: Gensfen finished." - - send "quit\n" - expect eof - - # return error code of the spawned program, useful for valgrind - lassign [wait] pid spawnid os_error_flag value - exit \$value -EOF - -# gensfen testing 02 -cat << EOF > gensfen02.exp - set timeout 240 - spawn $exeprefix ./stockfish - - send "uci\n" - expect "uciok" - - send "setoption name Threads value $threads\n" - send "setoption name Use NNUE value true\n" - send "isready\n" - send "gensfen depth 4 loop 50 use_draw_in_training_data_generation 1 eval_limit 32000 output_file_name validation_data/validation_data.bin sfen_format bin\n" - expect "INFO: Gensfen finished." - send "gensfen depth 4 loop 50 use_draw_in_training_data_generation 1 eval_limit 32000 output_file_name validation_data/validation_data.binpack sfen_format binpack\n" - expect "INFO: Gensfen finished." - - send "quit\n" - expect eof - - # return error code of the spawned program, useful for valgrind - lassign [wait] pid spawnid os_error_flag value - exit \$value -EOF - -# simple learning -cat << EOF > learn01.exp - set timeout 240 - spawn $exeprefix ./stockfish - - send "uci\n" - send "setoption name SkipLoadingEval value true\n" - send "setoption name Use NNUE value pure\n" - send "setoption name Threads value $threads\n" - send "isready\n" - send "learn targetdir training_data epochs 1 sfen_read_size 100 thread_buffer_size 10 batchsize 100 use_draw_in_training 1 use_draw_in_validation 1 lr 1 eval_limit 32000 nn_batch_size 30 newbob_decay 0.5 eval_save_interval 30 loss_output_interval 10 validation_set_file_name validation_data/validation_data.bin\n" - - expect "INFO (save_eval): Finished saving evaluation file in evalsave/final" - - send "quit\n" - expect eof - - # return error code of the spawned program, useful for valgrind - lassign [wait] pid spawnid os_error_flag value - exit \$value - -EOF - -for exp in gensfen01.exp gensfen02.exp learn01.exp -do - - echo "$prefix expect $exp $postfix" - eval "$prefix expect $exp $postfix" - - rm $exp - -done - -rm -f tsan.supp - -echo "instrumented learn testing OK"