Skip to content

Commit ee08b3b

Browse files
authored
Merge pull request LeelaChessZero#8 from Ergodice/uncertainty-weighting
Uncertainty weighting
2 parents 0b7266a + 3afb105 commit ee08b3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2134
-915
lines changed

.circleci/config.yml

+5-7
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ jobs:
77
- checkout
88
- run:
99
name: "Pull Submodules"
10-
command: |
11-
git submodule init
12-
git submodule update --remote
10+
command: git submodule update --init
1311
- run:
1412
name: Update Meson
1513
command: pip3 install --upgrade meson==0.58.1
@@ -31,15 +29,15 @@ jobs:
3129
- checkout
3230
- run:
3331
name: "Pull Submodules"
34-
command: |
35-
git submodule init
36-
git submodule update --remote
32+
command: git submodule update --init
3733
- run:
3834
name: Install build tools
3935
command: |
4036
pip3 install meson==0.63
4137
pip3 install ninja
42-
brew install ispc
38+
curl -LJOs https://github.com/ispc/ispc/releases/download/v1.21.0/ispc-v1.21.0-macOS.universal.tar.gz
39+
tar xf ispc-v1.21.0-macOS.universal.tar.gz
40+
cp ispc-v1.21.0-macOS.universal/bin/ispc /usr/local/bin
4341
- run:
4442
name: Build lc0
4543
command: |

README.md

+57-13
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,83 @@
44
# Lc0
55

66
Lc0 is a UCI-compliant chess engine designed to play chess via neural network, specifically those of the [LeelaChessZero project](https://lczero.org).
7-
This is an experimental repository for testing new features to the Lc0 chess engine. Updates are made frequently so there may be bugs. Please report any issues you find to the Lc0 Discord. All elo measurements were calculated on A100.
7+
This is an experimental repository for testing new features to the Lc0 chess engine. Updates are made frequently so there may be bugs. Please report any issues you find to the Lc0 Discord. All elo measurements were calculated on A100 with unbalanced human openings.
88
Many of these features are taken from the Katago engine. A detailed description of these methods can be found [here](https://github.com/lightvector/KataGo/blob/master/docs/KataGoMethods.md). A list of the improvements follows.
99

1010

1111
## New features in this fork
1212

13+
### Node reporting
14+
15+
The nps statistic used to represent the number of playouts per second, which may not be what the user wants. The new `--reported-nodes` option specifies what the node count and nps statistic represent.
16+
The default is `nodes` for LowNodes. The other options are `queries` for neural network queries and `playouts` or `legacy` for playouts (what we used to use).
17+
18+
1319
### 50 move rule caching
1420

1521
The first 64 plies out of 100 are partitioned into 8 equally sized buckets. Before a position is queried for NN evaluation, the 50 move rule ply is checked. If the bucket containing the position already has nodes, the eval is copied from the one with the most visits.
16-
The speedup can be anywhere from 5% to 50% depending on how transposition-heavy the position is. The gain was measured at 20 elo on STC.
22+
The speedup can be anywhere from 5% to 50% depending on how transposition-heavy the position is. The gain was measured at 20 elo on STC. The nodes per second statistic is now calculated by the number of true nodes (called LowNode in the code) rather than edges (technically playouts, called Node in the code) so the reported value may be lower than on previous dag versions.
23+
24+
This feature is enabled by default and can be disabled by specifying `--move-rule-bucketing=false` in the config.
25+
26+
### Multiple output heads
27+
28+
The BT3 generation of nets now has multiple value and policy heads that you can choose among. You always want the `winner` head for value. There are two policy heads, `vanilla` and `optimistic`.
29+
The vanilla head is similar to what we used before, and the optimistic head upweights moves that the net believes may be exceptionally strong, an idea taken from the Katago engine. The optimistic head is recommended as it adds roughly 20 elo at LTC. The Katago team observed that this improvement is similar to increasing the net size by roughly 40%.
30+
31+
The head you choose is specified in the backend options. For example, if you have a single GPU and want to use the optimistic policy head and winner value head, then you can use this can easily be specified as `--backend-opts=policy_head=vanilla,value_head=winner`.
32+
33+
If you have are using more than one GPU then you have to set up the backend for each GPU. An example is
34+
`--backend-opts=(gpu0,policy_head=optimistic,value_head=winner),(gpu1,policy_head=optimistic,value_head=winner)`.
35+
36+
### Uncertainty Weighting
37+
38+
Identical to the [Katago implementation](https://github.com/lightvector/KataGo/blob/master/docs/KataGoMethods.md#uncertainty-weighted-mcts-playouts), but the error uses only the winrate. The new parameters are
39+
40+
```
41+
--uncertainty-weighting-cap
42+
--uncertainty-weighting-coefficient
43+
--uncertainty-weighting-exponent
44+
--use-uncertainty-weighting
45+
```
46+
47+
48+
You must set `--use-uncertainty-weighting=true` to turn it on. With BT3, the gain was 20 elo at LTC with
49+
50+
```
51+
--uncertainty-weighting-cap=1.03
52+
--uncertainty-weighting-coefficient=0.13
53+
--uncertainty-weighting-exponent=-0.88
54+
--use-uncertainty-weighting=true
55+
```
56+
57+
58+
1759

1860
### CPUCT Utility Variance Scaling
1961

2062
Identical to the [Katago implementation](https://github.com/lightvector/KataGo/blob/master/docs/KataGoMethods.md#dynamic-variance-scaled-cpuct). The new parameters are
2163

2264
```
23-
CPuctUtilityStdevPrior
24-
CPuctUtilityStdevScale
25-
CPuctUtilityStdevPriorWeight
65+
--cpuct-utility-stdev-prior
66+
--cpuct-utility-stdev-scale
67+
--cpuct-utility-stdev-prior-weight
68+
--use-variance-scaling
2669
```
2770

28-
and the tuned values are
71+
and the tuned values (excluding the prior weight) for masterkni's T1 are
2972

3073
```
31-
CPuct 2.3097
32-
FpuValue 0.5619
33-
CPuctUtilityStdevPrior 0.2289
34-
CPuctUtilityStdevScale 0.3437
35-
CPuctUtilityStdevPriorWeight 10.0 (default, not tuned)
36-
WDLCalibrationElo 3400
74+
--cpuct=2.3097
75+
--fpu-value=0.5619
76+
--cpuct-utility-stdev-prior=0.2289
77+
--cpuct-utility-stdev-scale=0.3437
78+
--cpuct-utility-stdev-prior-weight=10.0
79+
--wdl-calibration-elo=3400
80+
--use-variance-scaling=true
3781
```
3882

39-
The gain is around 10 elo on STC and LTC.
83+
You must set `--use-variance-scaling=true` to turn it on. The gain is around 10 elo on STC and 5 elo on LTC, but more testing is needed. For now the setting is NOT RECOMMENDED except for personal use.
4084

4185

4286

appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ before_build:
124124
- cmd: SET EXTRA=
125125
- cmd: IF %ANDROID%==false SET EXTRA=-Db_vscrt=md
126126
- cmd: IF %ONNX_DML%==true SET EXTRA=-Db_vscrt=md -Donnx_libdir=C:\cache\%ONNX_NAME%\lib -Donnx_include=C:\cache\%ONNX_NAME%\include
127-
- cmd: IF %ANDROID%==false meson build --backend vs2017 --buildtype release -Dgtest=%GTEST% -Dopencl=%OPENCL% -Dblas=%BUILD_BLAS% -Ddnnl=true -Ddx=%DX% -Dcudnn=%CUDNN% -Donednn=%ONEDNN% -Dispc_native_only=false -Dpopcnt=%POPCNT% -Df16c=%F16C% -Dcudnn_include="%CUDA_PATH%\include","%CUDA_PATH%\cuda\include" -Dcudnn_libdirs="%CUDA_PATH%\lib\x64","%CUDA_PATH%\cuda\lib\x64" -Dopenblas_include="%PKG_FOLDER%\OpenBLAS\dist64\include" -Dopenblas_libdirs="%PKG_FOLDER%\OpenBLAS\dist64\lib" -Ddnnl_dir="%PKG_FOLDER%\%DNNL_NAME%" -Dopencl_include="%PKG_FOLDER%\opencl-nug.0.777.77\build\native\include" -Dopencl_libdirs="%PKG_FOLDER%\opencl-nug.0.777.77\build\native\lib\x64" -Ddefault_library=static -Dmalloc=mimalloc -Dmimalloc_libdir="%MIMALLOC_PATH%"\out\msvc-x64\Release %EXTRA%
127+
- cmd: IF %ANDROID%==false meson build --backend vs2017 --buildtype release -Dgtest=%GTEST% -Dopencl=%OPENCL% -Dblas=%BUILD_BLAS% -Ddnnl=true -Ddx=%DX% -Dcudnn=%CUDNN% -Donednn=%ONEDNN% -Dispc_native_only=false -Dnative_cuda=false -Dpopcnt=%POPCNT% -Df16c=%F16C% -Dcudnn_include="%CUDA_PATH%\include","%CUDA_PATH%\cuda\include" -Dcudnn_libdirs="%CUDA_PATH%\lib\x64","%CUDA_PATH%\cuda\lib\x64" -Dopenblas_include="%PKG_FOLDER%\OpenBLAS\dist64\include" -Dopenblas_libdirs="%PKG_FOLDER%\OpenBLAS\dist64\lib" -Ddnnl_dir="%PKG_FOLDER%\%DNNL_NAME%" -Dopencl_include="%PKG_FOLDER%\opencl-nug.0.777.77\build\native\include" -Dopencl_libdirs="%PKG_FOLDER%\opencl-nug.0.777.77\build\native\lib\x64" -Ddefault_library=static -Dmalloc=mimalloc -Dmimalloc_libdir="%MIMALLOC_PATH%"\out\msvc-x64\Release %EXTRA%
128128
- cmd: IF %ANDROID%==true meson arm64-v8a --buildtype release -Dgtest=false -Dopenblas_include="%PKG_FOLDER%\OpenBLAS\android-aarch64\include" -Dopenblas_libdirs="%PKG_FOLDER%\OpenBLAS\android-aarch64\lib" -Dembed=%EMBED% -Ddefault_library=static --cross-file crossfile-aarch64
129129
- cmd: IF %ANDROID%==true meson armeabi-v7a --buildtype release -Dgtest=false -Dopenblas_include="%PKG_FOLDER%\OpenBLAS\android-armv7a\include" -Dopenblas_libdirs="%PKG_FOLDER%\OpenBLAS\android-armv7a\lib" -Dembed=%EMBED% -Ddefault_library=static --cross-file crossfile-armv7a -Dispc=false -Dneon=false
130130
build_script:

build.cmd

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ set EIGEN=false
1313
set TEST=false
1414

1515
rem 2. Edit the paths for the build dependencies.
16-
set CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0
16+
set CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.2
1717
set CUDNN_PATH=%CUDA_PATH%
1818
set OPENBLAS_PATH=C:\OpenBLAS
1919
set MKL_PATH=C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\mkl
@@ -63,7 +63,7 @@ meson build --backend %backend% --buildtype release -Ddx=%DX12% -Dcudnn=%CUDNN%
6363
-Dmkl_include="%MKL_PATH%\include" -Dmkl_libdirs="%MKL_PATH%\lib\intel64" -Ddnnl_dir="%DNNL_PATH%" ^
6464
-Dopencl_libdirs="%OPENCL_LIB_PATH%" -Dopencl_include="%OPENCL_INCLUDE_PATH%" ^
6565
-Dopenblas_include="%OPENBLAS_PATH%\include" -Dopenblas_libdirs="%OPENBLAS_PATH%\lib" ^
66-
-Ddefault_library=static
66+
-Ddefault_library=static
6767

6868
if errorlevel 1 exit /b
6969

build.sh

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ else
2828
fi
2929

3030
"${MESON}" compile -C "${BUILDDIR}"
31-
[ -n "${INSTALL_PREFIX}" ] && "${MESON}" install -C "${BUILDDIR}"
31+
32+
if [ -n "${INSTALL_PREFIX}" ]
33+
then
34+
"${MESON}" install -C "${BUILDDIR}"
35+
fi

libs/lczero-common

meson.build

+37-29
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,9 @@ if get_option('build_backends')
448448
if get_option('cudnn') and cu_dnn.found()
449449
deps += cu_dnn
450450
cuda_files += 'src/neural/cuda/network_cudnn.cc'
451+
cuda_files += 'src/neural/cuda/network_cuda.cc' # To support newer nets.
451452
add_project_arguments('-DUSE_CUDNN', language : 'cpp')
452-
endif
453-
if get_option('plain_cuda')
453+
elif get_option('plain_cuda')
454454
cuda_files += 'src/neural/cuda/network_cuda.cc'
455455
endif
456456
foreach d : get_option('cudnn_include')
@@ -461,8 +461,9 @@ if get_option('build_backends')
461461
includes += include_directories('src/neural/cuda/')
462462

463463
cuda_arguments = ['-c', '@INPUT@', '-o', '@OUTPUT@',
464-
'-I', meson.source_root() + '/subprojects/abseil-cpp-20211102.0',
464+
'-I', meson.source_root() + '/subprojects/abseil-cpp-20220623.0',
465465
'-I', meson.current_source_dir() + '/src']
466+
nvcc_help = run_command(nvcc, '-h').stdout()
466467
if host_machine.system() == 'windows'
467468
if get_option('b_vscrt') == 'mt'
468469
cuda_arguments += ['-Xcompiler', '-MT']
@@ -483,6 +484,8 @@ if get_option('build_backends')
483484
nvcc_extra_args = []
484485
if cuda_cc != ''
485486
nvcc_extra_args = ['-arch=compute_' + cuda_cc, '-code=sm_' + cuda_cc]
487+
elif get_option('native_cuda') and nvcc_help.contains('-arch=native')
488+
nvcc_extra_args = ['-arch=native']
486489
endif
487490
foreach x : get_option('cudnn_include')
488491
cuda_arguments += ['-I', x]
@@ -500,23 +503,24 @@ if get_option('build_backends')
500503
command : [nvcc, nvcc_extra_args, cuda_arguments]
501504
)
502505

503-
# Handling of fp16 cuda code.
504-
nvcc_sm_list = ['80', '75', '86', '70', '89', '90']
505-
if host_machine.system() != 'windows'
506-
nvcc_sm_list += ['60']
507-
if ['arm', 'aarch64'].contains(host_machine.cpu_family())
508-
# Add Jetson versions to the list.
509-
message('Jetson support enabled.')
510-
nvcc_sm_list += ['72', '62', '53', '87']
506+
# Handling of fp16 cuda code: If nvcc_extra_args is empty add options to
507+
# generate code for the major fp16 capable architectures.
508+
if nvcc_extra_args == []
509+
nvcc_arch = '-arch=compute_70'
510+
nvcc_sm_list = ['sm_70', 'sm_75', 'sm_80', 'sm_90']
511+
if host_machine.system() != 'windows'
512+
nvcc_arch = '-arch=compute_60'
513+
nvcc_sm_list += ['sm_60']
514+
if ['arm', 'aarch64'].contains(host_machine.cpu_family())
515+
message('Compiling for Jetson.')
516+
nvcc_arch = '-arch=compute_53'
517+
nvcc_sm_list = ['sm_53', 'sm_62', 'sm_72', 'sm_87']
518+
endif
511519
endif
512-
endif
513-
# Ignore the given CC for fp16 when it is not in the supported list.
514-
if cuda_cc == '' or not nvcc_sm_list.contains('sm_' + cuda_cc)
515-
nvcc_extra_args = []
516-
nvcc_help = run_command(nvcc, '-h').stdout()
520+
nvcc_extra_args = [nvcc_arch]
517521
foreach x : nvcc_sm_list
518-
if nvcc_help.contains('sm_' + x)
519-
nvcc_extra_args += '-gencode=arch=compute_' + x + ',code=sm_' + x
522+
if nvcc_help.contains(x)
523+
nvcc_extra_args += '-code=' + x
520524
endif
521525
endforeach
522526
# For forward compatibility.
@@ -573,19 +577,23 @@ if get_option('build_backends')
573577
## ONNX
574578
## ~~~~~~~~~~
575579
if get_option('onnx_libdir') != '' and get_option('onnx_include') != ''
576-
onnx_lib = cc.find_library('onnxruntime',
577-
dirs: get_option('onnx_libdir'),
578-
required: true)
580+
deps += cc.find_library('onnxruntime', dirs: get_option('onnx_libdir'),
581+
required: true)
579582
includes += include_directories(get_option('onnx_include'), is_system: true)
580-
cc.has_header('onnxruntime_cxx_api.h',
581-
required: true,
583+
cc.has_header('onnxruntime_cxx_api.h', required: true,
582584
args: '-I' + get_option('onnx_include'))
583-
deps += [onnx_lib]
584-
585-
files += [
586-
'src/neural/onnx/network_onnx.cc',
587-
]
588-
585+
if not cc.has_header('cpu_provider_factory.h',
586+
args: '-I' + get_option('onnx_include'))
587+
cc.has_header('../providers/cpu/cpu_provider_factory.h', required: true,
588+
args: '-I' + get_option('onnx_include'))
589+
includes += include_directories(get_option('onnx_include') + '/../providers/cpu',
590+
is_system: true)
591+
endif
592+
files += 'src/neural/onnx/network_onnx.cc'
593+
if cc.find_library('onnxruntime_providers_rocm',
594+
dirs: get_option('onnx_libdir'), required: false).found()
595+
add_project_arguments('-DUSE_ROCM', language : 'cpp')
596+
endif
589597
has_backends = true
590598
endif
591599

meson_options.txt

+5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ option('ispc_native_only',
6363
value: true,
6464
description: 'use ispc and enable native arch only')
6565

66+
option('native_cuda',
67+
type: 'boolean',
68+
value: true,
69+
description: 'build cuda code for native arch only (if supported)')
70+
6671
option('cudnn',
6772
type: 'boolean',
6873
value: true,

scripts/appveyor_win_package.cmd

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
7z a lc0-%APPVEYOR_REPO_TAG_NAME%-windows-%NAME%.zip %APPVEYOR_BUILD_FOLDER%\build\lc0.exe
2-
appveyor DownloadFile "https://ci.appveyor.com/api/projects/LeelaChessZero/lczero-client/artifacts/lc0-training-client.exe?branch=release&pr=false&job=Environment%%3A%%20NAME%%3D.exe%%2C%%20GOOS%%3Dwindows"
3-
7z a lc0-%APPVEYOR_REPO_TAG_NAME%-windows-%NAME%.zip lc0-training-client.exe
2+
IF %NAME%==gpu-nvidia-cuda appveyor DownloadFile "https://github.com/LeelaChessZero/lczero-client/releases/latest/download/lc0-training-client.exe"
3+
IF %NAME%==gpu-nvidia-cuda 7z a lc0-%APPVEYOR_REPO_TAG_NAME%-windows-%NAME%.zip lc0-training-client.exe
44
type COPYING |more /P > dist\COPYING
55
7z a lc0-%APPVEYOR_REPO_TAG_NAME%-windows-%NAME%.zip .\dist\COPYING
66
7z a lc0-%APPVEYOR_REPO_TAG_NAME%-windows-%NAME%.zip c:\cache\%NET%.pb.gz

src/benchmark/benchmark.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ void Benchmark::Run() {
106106
std::make_unique<CallbackUciResponder>(
107107
std::bind(&Benchmark::OnBestMove, this, std::placeholders::_1),
108108
std::bind(&Benchmark::OnInfo, this, std::placeholders::_1)),
109-
MoveList(), start, std::move(stopper), false, option_dict, &cache,
110-
nullptr);
109+
MoveList(), start, std::move(stopper), false, false, option_dict,
110+
&cache, nullptr);
111111
search->StartThreads(option_dict.Get<int>(kThreadsOptionId));
112112
search->Wait();
113113
const auto end = std::chrono::steady_clock::now();

src/chess/uciloop.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const std::unordered_map<std::string, std::unordered_set<std::string>>
5454
{{"position"}, {"fen", "startpos", "moves"}},
5555
{{"go"},
5656
{"infinite", "wtime", "btime", "winc", "binc", "movestogo", "depth",
57-
"nodes", "movetime", "searchmoves", "ponder"}},
57+
"mate", "nodes", "movetime", "searchmoves", "ponder"}},
5858
{{"start"}, {}},
5959
{{"stop"}, {}},
6060
{{"ponderhit"}, {}},
@@ -192,6 +192,7 @@ bool UciLoop::DispatchCommand(
192192
UCIGOOPTION(binc);
193193
UCIGOOPTION(movestogo);
194194
UCIGOOPTION(depth);
195+
UCIGOOPTION(mate);
195196
UCIGOOPTION(nodes);
196197
UCIGOOPTION(movetime);
197198
#undef UCIGOOPTION

src/chess/uciloop.h

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct GoParams {
4545
std::optional<std::int64_t> binc;
4646
std::optional<int> movestogo;
4747
std::optional<int> depth;
48+
std::optional<int> mate;
4849
std::optional<int> nodes;
4950
std::optional<std::int64_t> movetime;
5051
bool infinite = false;

src/engine.cc

+16-5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include "mcts/search.h"
3535
#include "mcts/stoppers/factory.h"
36+
#include "utils/commandline.h"
3637
#include "utils/configfile.h"
3738
#include "utils/logging.h"
3839

@@ -51,7 +52,7 @@ const OptionId kSyzygyTablebaseId{
5152
"List of Syzygy tablebase directories, list entries separated by system "
5253
"separator (\";\" for Windows, \":\" for Linux).",
5354
's'};
54-
const OptionId kPonderId{"ponder", "Ponder",
55+
const OptionId kPonderId{"", "Ponder",
5556
"This option is ignored. Here to please chess GUIs."};
5657
const OptionId kUciChess960{
5758
"chess960", "UCI_Chess960",
@@ -93,12 +94,21 @@ EngineController::EngineController(std::unique_ptr<UciResponder> uci_responder,
9394

9495
void EngineController::PopulateOptions(OptionsParser* options) {
9596
using namespace std::placeholders;
96-
97+
const bool is_simple =
98+
CommandLine::BinaryName().find("simple") != std::string::npos;
9799
NetworkFactory::PopulateOptions(options);
98100
options->Add<IntOption>(kThreadsOptionId, 1, 128) = kDefaultThreads;
99101
options->Add<IntOption>(kNNCacheSizeId, 0, 999999999) = 2000;
100102
SearchParams::Populate(options);
101103

104+
ConfigFile::PopulateOptions(options);
105+
if (is_simple) {
106+
options->HideAllOptions();
107+
options->UnhideOption(kThreadsOptionId);
108+
options->UnhideOption(NetworkFactory::kWeightsId);
109+
options->UnhideOption(SearchParams::kContemptId);
110+
options->UnhideOption(SearchParams::kMultiPvId);
111+
}
102112
options->Add<StringOption>(kSyzygyTablebaseId);
103113
// Add "Ponder" option to signal to GUIs that we support pondering.
104114
// This option is currently not used by lc0 in any way.
@@ -107,8 +117,8 @@ void EngineController::PopulateOptions(OptionsParser* options) {
107117
options->Add<BoolOption>(kShowWDL) = false;
108118
options->Add<BoolOption>(kShowMovesleft) = false;
109119

110-
ConfigFile::PopulateOptions(options);
111-
PopulateTimeManagementOptions(RunType::kUci, options);
120+
PopulateTimeManagementOptions(is_simple ? RunType::kSimpleUci : RunType::kUci,
121+
options);
112122

113123
options->Add<BoolOption>(kStrictUciTiming) = false;
114124
options->HideOption(kStrictUciTiming);
@@ -238,6 +248,7 @@ class PonderResponseTransformer : public TransformingUciResponder {
238248
if (ponder_info.score) ponder_info.score = -*ponder_info.score;
239249
if (ponder_info.depth > 1) ponder_info.depth--;
240250
if (ponder_info.seldepth > 1) ponder_info.seldepth--;
251+
if (ponder_info.wdl) std::swap(ponder_info.wdl->w, ponder_info.wdl->l);
241252
ponder_info.pv.clear();
242253
}
243254
if (!info.pv.empty() && info.pv[0].as_string() == ponder_move_) {
@@ -298,7 +309,7 @@ void EngineController::Go(const GoParams& params) {
298309
search_ = std::make_unique<Search>(
299310
tree_.get(), network_.get(), std::move(responder),
300311
StringsToMovelist(params.searchmoves, tree_->HeadPosition().GetBoard()),
301-
*move_start_time_, std::move(stopper), params.infinite || params.ponder,
312+
*move_start_time_, std::move(stopper), params.infinite, params.ponder,
302313
options_, &cache_, syzygy_tb_.get());
303314

304315
LOGFILE << "Timer started at "

0 commit comments

Comments
 (0)