Update to Stockfish 11

This commit is contained in:
Peter Osterlund
2020-01-18 08:00:03 +01:00
parent c19a3b3777
commit 9c1d76faa1
38 changed files with 1777 additions and 1605 deletions

View File

@@ -1,7 +1,7 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (c) 2013 Ronald de Man
Copyright (C) 2016-2018 Marco Costalba, Lucas Braesch
Copyright (C) 2016-2020 Marco Costalba, Lucas Braesch
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,12 +27,12 @@
#include <list>
#include <sstream>
#include <type_traits>
#include <mutex>
#include "../bitboard.h"
#include "../movegen.h"
#include "../position.h"
#include "../search.h"
#include "../thread_win32.h"
#include "../types.h"
#include "../uci.h"
@@ -45,7 +45,9 @@
#include <sys/stat.h>
#else
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#ifndef NOMINMAX
# define NOMINMAX // Disable macros min() and max()
#endif
#include <windows.h>
#endif
@@ -214,39 +216,57 @@ public:
return *baseAddress = nullptr, nullptr;
fstat(fd, &statbuf);
if (statbuf.st_size % 64 != 16)
{
std::cerr << "Corrupt tablebase file " << fname << std::endl;
exit(EXIT_FAILURE);
}
*mapping = statbuf.st_size;
*baseAddress = mmap(nullptr, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
madvise(*baseAddress, statbuf.st_size, MADV_RANDOM);
::close(fd);
if (*baseAddress == MAP_FAILED) {
if (*baseAddress == MAP_FAILED)
{
std::cerr << "Could not mmap() " << fname << std::endl;
exit(1);
exit(EXIT_FAILURE);
}
#else
// Note FILE_FLAG_RANDOM_ACCESS is only a hint to Windows and as such may get ignored.
HANDLE fd = CreateFile(fname.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr);
if (fd == INVALID_HANDLE_VALUE)
return *baseAddress = nullptr, nullptr;
DWORD size_high;
DWORD size_low = GetFileSize(fd, &size_high);
if (size_low % 64 != 16)
{
std::cerr << "Corrupt tablebase file " << fname << std::endl;
exit(EXIT_FAILURE);
}
HANDLE mmap = CreateFileMapping(fd, nullptr, PAGE_READONLY, size_high, size_low, nullptr);
CloseHandle(fd);
if (!mmap) {
if (!mmap)
{
std::cerr << "CreateFileMapping() failed" << std::endl;
exit(1);
exit(EXIT_FAILURE);
}
*mapping = (uint64_t)mmap;
*baseAddress = MapViewOfFile(mmap, FILE_MAP_READ, 0, 0, 0);
if (!*baseAddress) {
if (!*baseAddress)
{
std::cerr << "MapViewOfFile() failed, name = " << fname
<< ", error = " << GetLastError() << std::endl;
exit(1);
exit(EXIT_FAILURE);
}
#endif
uint8_t* data = (uint8_t*)*baseAddress;
@@ -254,7 +274,8 @@ public:
constexpr uint8_t Magics[][4] = { { 0xD7, 0x66, 0x0C, 0xA5 },
{ 0x71, 0xE8, 0x23, 0x5D } };
if (memcmp(data, Magics[type == WDL], 4)) {
if (memcmp(data, Magics[type == WDL], 4))
{
std::cerr << "Corrupted table in file " << fname << std::endl;
unmap(*baseAddress, *mapping);
return *baseAddress = nullptr, nullptr;
@@ -348,7 +369,7 @@ TBTable<WDL>::TBTable(const std::string& code) : TBTable() {
hasPawns = pos.pieces(PAWN);
hasUniquePieces = false;
for (Color c = WHITE; c <= BLACK; ++c)
for (Color c : { WHITE, BLACK })
for (PieceType pt = PAWN; pt < KING; ++pt)
if (popcount(pos.pieces(c, pt)) == 1)
hasUniquePieces = true;
@@ -415,7 +436,7 @@ class TBTables {
}
}
std::cerr << "TB hash table size too low!" << std::endl;
exit(1);
exit(EXIT_FAILURE);
}
public:
@@ -664,7 +685,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
bool blackStronger = (pos.material_key() != entry->key);
int flipColor = (symmetricBlackToMove || blackStronger) * 8;
int flipSquares = (symmetricBlackToMove || blackStronger) * 070;
int flipSquares = (symmetricBlackToMove || blackStronger) * 56;
int stm = (symmetricBlackToMove || blackStronger) ^ pos.side_to_move();
// For pawns, TB files store 4 separate tables according if leading pawn is on
@@ -687,9 +708,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
std::swap(squares[0], *std::max_element(squares, squares + leadPawnsCnt, pawns_comp));
tbFile = file_of(squares[0]);
if (tbFile > FILE_D)
tbFile = file_of(squares[0] ^ 7); // Horizontal flip: SQ_H1 -> SQ_A1
tbFile = map_to_queenside(file_of(squares[0]));
}
// DTZ tables are one-sided, i.e. they store positions only for white to
@@ -713,8 +732,8 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
// Then we reorder the pieces to have the same sequence as the one stored
// in pieces[i]: the sequence that ensures the best compression.
for (int i = leadPawnsCnt; i < size; ++i)
for (int j = i; j < size; ++j)
for (int i = leadPawnsCnt; i < size - 1; ++i)
for (int j = i + 1; j < size; ++j)
if (d->pieces[i] == pieces[j])
{
std::swap(pieces[i], pieces[j]);
@@ -745,7 +764,7 @@ Ret do_probe_table(const Position& pos, T* entry, WDLScore wdl, ProbeState* resu
// piece is below RANK_5.
if (rank_of(squares[0]) > RANK_4)
for (int i = 0; i < size; ++i)
squares[i] ^= 070; // Vertical flip: SQ_A8 -> SQ_A1
squares[i] ^= SQ_A8; // Vertical flip: SQ_A8 -> SQ_A1
// Look for the first piece of the leading group not on the A1-D4 diagonal
// and ensure it is mapped below the diagonal.
@@ -1043,8 +1062,8 @@ void set(T& e, uint8_t* data) {
enum { Split = 1, HasPawns = 2 };
assert(e.hasPawns == !!(*data & HasPawns));
assert((e.key != e.key2) == !!(*data & Split));
assert(e.hasPawns == bool(*data & HasPawns));
assert((e.key != e.key2) == bool(*data & Split));
data++; // First byte stores flags
@@ -1107,14 +1126,14 @@ void set(T& e, uint8_t* data) {
template<TBType Type>
void* mapped(TBTable<Type>& e, const Position& pos) {
static Mutex mutex;
static std::mutex mutex;
// Use 'aquire' to avoid a thread reads 'ready' == true while another is
// still working, this could happen due to compiler reordering.
// Use 'acquire' to avoid a thread reading 'ready' == true while
// another is still working. (compiler reordering may cause this).
if (e.ready.load(std::memory_order_acquire))
return e.baseAddress; // Could be nullptr if file does not exsist
return e.baseAddress; // Could be nullptr if file does not exist
std::unique_lock<Mutex> lk(mutex);
std::unique_lock<std::mutex> lk(mutex);
if (e.ready.load(std::memory_order_relaxed)) // Recheck under lock
return e.baseAddress;