mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-23 05:07:14 +00:00
Merge commit 'c467fe5ba42545827d769c360aa404767308ac18' into cluster
This commit is contained in:
+12
-12
@@ -20,8 +20,8 @@
|
||||
"archive_ext": "tar"
|
||||
},
|
||||
{
|
||||
"name": "macOS 14 Apple Clang M1",
|
||||
"os": "macos-14",
|
||||
"name": "macOS 15 Apple Clang M1",
|
||||
"os": "macos-15",
|
||||
"simple_name": "macos-m1",
|
||||
"compiler": "clang++",
|
||||
"comp": "clang",
|
||||
@@ -71,49 +71,49 @@
|
||||
{
|
||||
"binaries": "x86-64",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-sse41-popcnt",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-avx2",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-bmi2",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-avxvnni",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-avx512",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-vnni512",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
"binaries": "x86-64-avx512icl",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -245,7 +245,7 @@
|
||||
{
|
||||
"binaries": "armv8",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -275,7 +275,7 @@
|
||||
{
|
||||
"binaries": "armv8-dotprod",
|
||||
"config": {
|
||||
"os": "macos-14"
|
||||
"os": "macos-15"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -62,8 +62,8 @@ jobs:
|
||||
comp: clang
|
||||
run_64bit_tests: true
|
||||
shell: bash
|
||||
- name: macOS 14 Apple Clang M1
|
||||
os: macos-14
|
||||
- name: macOS 15 Apple Clang M1
|
||||
os: macos-15
|
||||
compiler: clang++
|
||||
comp: clang
|
||||
run_64bit_tests: false
|
||||
|
||||
+2
-2
@@ -454,7 +454,7 @@ BenchmarkSetup setup_benchmark(std::istream& is) {
|
||||
int desiredTimeS;
|
||||
|
||||
if (!(is >> setup.threads))
|
||||
setup.threads = get_hardware_concurrency();
|
||||
setup.threads = int(get_hardware_concurrency());
|
||||
else
|
||||
setup.originalInvocation += std::to_string(setup.threads);
|
||||
|
||||
@@ -486,7 +486,7 @@ BenchmarkSetup setup_benchmark(std::istream& is) {
|
||||
int ply = 1;
|
||||
for (int i = 0; i < static_cast<int>(game.size()); ++i)
|
||||
{
|
||||
const float correctedTime = getCorrectedTime(ply);
|
||||
const float correctedTime = float(getCorrectedTime(ply));
|
||||
totalTime += correctedTime;
|
||||
ply += 1;
|
||||
}
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ namespace Eval {
|
||||
// for the build process (profile-build and fishtest) to work. Do not change the
|
||||
// name of the macro or the location where this macro is defined, as it is used
|
||||
// in the Makefile/Fishtest.
|
||||
#define EvalFileDefaultNameBig "nn-2962dca31855.nnue"
|
||||
#define EvalFileDefaultNameBig "nn-c288c895ea92.nnue"
|
||||
#define EvalFileDefaultNameSmall "nn-37f18f62d772.nnue"
|
||||
|
||||
namespace NNUE {
|
||||
|
||||
+6
-4
@@ -48,13 +48,15 @@ inline int pawn_history_index(const Position& pos) {
|
||||
return pos.pawn_key() & (PAWN_HISTORY_SIZE - 1);
|
||||
}
|
||||
|
||||
inline uint16_t pawn_correction_history_index(const Position& pos) { return pos.pawn_key(); }
|
||||
inline uint16_t pawn_correction_history_index(const Position& pos) {
|
||||
return uint16_t(pos.pawn_key());
|
||||
}
|
||||
|
||||
inline uint16_t minor_piece_index(const Position& pos) { return pos.minor_piece_key(); }
|
||||
inline uint16_t minor_piece_index(const Position& pos) { return uint16_t(pos.minor_piece_key()); }
|
||||
|
||||
template<Color c>
|
||||
inline uint16_t non_pawn_index(const Position& pos) {
|
||||
return pos.non_pawn_key(c);
|
||||
return uint16_t(pos.non_pawn_key(c));
|
||||
}
|
||||
|
||||
// StatsEntry is the container of various numerical statistics. We use a class
|
||||
@@ -100,7 +102,7 @@ using Stats = MultiArray<StatsEntry<T, D>, Sizes...>;
|
||||
// see https://www.chessprogramming.org/Butterfly_Boards
|
||||
using ButterflyHistory = Stats<std::int16_t, 7183, COLOR_NB, UINT_16_HISTORY_SIZE>;
|
||||
|
||||
// LowPlyHistory is addressed by play and move's from and to squares, used
|
||||
// LowPlyHistory is addressed by ply and move's from and to squares, used
|
||||
// to improve move ordering near the root
|
||||
using LowPlyHistory = Stats<std::int16_t, 7183, LOW_PLY_HISTORY_SIZE, UINT_16_HISTORY_SIZE>;
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ constexpr std::string_view version = "dev";
|
||||
|
||||
// Our fancy logging facility. The trick here is to replace cin.rdbuf() and
|
||||
// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We
|
||||
// can toggle the logging of std::cout and std:cin at runtime whilst preserving
|
||||
// can toggle the logging of std::cout and std::cin at runtime whilst preserving
|
||||
// usual I/O functionality, all without changing a single line of code!
|
||||
// Idea from http://groups.google.com/group/comp.lang.c++/msg/1d941c0f26ea0d81
|
||||
|
||||
|
||||
+2
-1
@@ -134,6 +134,7 @@ class ValueList {
|
||||
|
||||
public:
|
||||
std::size_t size() const { return size_; }
|
||||
int ssize() const { return int(size_); }
|
||||
void push_back(const T& value) {
|
||||
assert(size_ < MaxSize);
|
||||
values_[size_++] = value;
|
||||
@@ -424,7 +425,7 @@ void move_to_front(std::vector<T>& vec, Predicate pred) {
|
||||
#elif defined(_MSC_VER)
|
||||
#define sf_always_inline __forceinline
|
||||
#else
|
||||
// do nothign for other compilers
|
||||
// do nothing for other compilers
|
||||
#define sf_always_inline
|
||||
#endif
|
||||
|
||||
|
||||
@@ -360,6 +360,8 @@ struct AccumulatorUpdateContext {
|
||||
vec_t acc[Tiling::NumRegs];
|
||||
psqt_vec_t psqt[Tiling::NumPsqtRegs];
|
||||
|
||||
const auto* threatWeights = &featureTransformer.threatWeights[0];
|
||||
|
||||
for (IndexType j = 0; j < Dimensions / Tiling::TileHeight; ++j)
|
||||
{
|
||||
auto* fromTile = reinterpret_cast<const vec_t*>(&fromAcc[j * Tiling::TileHeight]);
|
||||
@@ -368,12 +370,11 @@ struct AccumulatorUpdateContext {
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = fromTile[k];
|
||||
|
||||
for (IndexType i = 0; i < removed.size(); ++i)
|
||||
for (int i = 0; i < removed.ssize(); ++i)
|
||||
{
|
||||
IndexType index = removed[i];
|
||||
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
|
||||
auto* column =
|
||||
reinterpret_cast<const vec_i8_t*>(&featureTransformer.threatWeights[offset]);
|
||||
size_t index = removed[i];
|
||||
const size_t offset = Dimensions * index;
|
||||
auto* column = reinterpret_cast<const vec_i8_t*>(&threatWeights[offset]);
|
||||
|
||||
#ifdef USE_NEON
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k += 2)
|
||||
@@ -387,12 +388,11 @@ struct AccumulatorUpdateContext {
|
||||
#endif
|
||||
}
|
||||
|
||||
for (IndexType i = 0; i < added.size(); ++i)
|
||||
for (int i = 0; i < added.ssize(); ++i)
|
||||
{
|
||||
IndexType index = added[i];
|
||||
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
|
||||
auto* column =
|
||||
reinterpret_cast<const vec_i8_t*>(&featureTransformer.threatWeights[offset]);
|
||||
size_t index = added[i];
|
||||
const size_t offset = Dimensions * index;
|
||||
auto* column = reinterpret_cast<const vec_i8_t*>(&threatWeights[offset]);
|
||||
|
||||
#ifdef USE_NEON
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k += 2)
|
||||
@@ -408,6 +408,8 @@ struct AccumulatorUpdateContext {
|
||||
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k++)
|
||||
vec_store(&toTile[k], acc[k]);
|
||||
|
||||
threatWeights += Tiling::TileHeight;
|
||||
}
|
||||
|
||||
for (IndexType j = 0; j < PSQTBuckets / Tiling::PsqtTileHeight; ++j)
|
||||
@@ -420,22 +422,22 @@ struct AccumulatorUpdateContext {
|
||||
for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
psqt[k] = fromTilePsqt[k];
|
||||
|
||||
for (IndexType i = 0; i < removed.size(); ++i)
|
||||
for (int i = 0; i < removed.ssize(); ++i)
|
||||
{
|
||||
IndexType index = removed[i];
|
||||
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt = reinterpret_cast<const psqt_vec_t*>(
|
||||
size_t index = removed[i];
|
||||
const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt = reinterpret_cast<const psqt_vec_t*>(
|
||||
&featureTransformer.threatPsqtWeights[offset]);
|
||||
|
||||
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
psqt[k] = vec_sub_psqt_32(psqt[k], columnPsqt[k]);
|
||||
}
|
||||
|
||||
for (IndexType i = 0; i < added.size(); ++i)
|
||||
for (int i = 0; i < added.ssize(); ++i)
|
||||
{
|
||||
IndexType index = added[i];
|
||||
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt = reinterpret_cast<const psqt_vec_t*>(
|
||||
size_t index = added[i];
|
||||
const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt = reinterpret_cast<const psqt_vec_t*>(
|
||||
&featureTransformer.threatPsqtWeights[offset]);
|
||||
|
||||
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
@@ -691,6 +693,8 @@ void update_accumulator_refresh_cache(Color pers
|
||||
vec_t acc[Tiling::NumRegs];
|
||||
psqt_vec_t psqt[Tiling::NumPsqtRegs];
|
||||
|
||||
const auto* weights = &featureTransformer.weights[0];
|
||||
|
||||
for (IndexType j = 0; j < Dimensions / Tiling::TileHeight; ++j)
|
||||
{
|
||||
auto* accTile =
|
||||
@@ -700,33 +704,33 @@ void update_accumulator_refresh_cache(Color pers
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = entryTile[k];
|
||||
|
||||
IndexType i = 0;
|
||||
for (; i < std::min(removed.size(), added.size()); ++i)
|
||||
int i = 0;
|
||||
for (; i < std::min(removed.ssize(), added.ssize()); ++i)
|
||||
{
|
||||
IndexType indexR = removed[i];
|
||||
const IndexType offsetR = Dimensions * indexR + j * Tiling::TileHeight;
|
||||
auto* columnR = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offsetR]);
|
||||
IndexType indexA = added[i];
|
||||
const IndexType offsetA = Dimensions * indexA + j * Tiling::TileHeight;
|
||||
auto* columnA = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offsetA]);
|
||||
size_t indexR = removed[i];
|
||||
const size_t offsetR = Dimensions * indexR;
|
||||
auto* columnR = reinterpret_cast<const vec_t*>(&weights[offsetR]);
|
||||
size_t indexA = added[i];
|
||||
const size_t offsetA = Dimensions * indexA;
|
||||
auto* columnA = reinterpret_cast<const vec_t*>(&weights[offsetA]);
|
||||
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = fused<Vec16Wrapper, Add, Sub>(acc[k], columnA[k], columnR[k]);
|
||||
}
|
||||
for (; i < removed.size(); ++i)
|
||||
for (; i < removed.ssize(); ++i)
|
||||
{
|
||||
IndexType index = removed[i];
|
||||
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
|
||||
auto* column = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offset]);
|
||||
size_t index = removed[i];
|
||||
const size_t offset = Dimensions * index;
|
||||
auto* column = reinterpret_cast<const vec_t*>(&weights[offset]);
|
||||
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = vec_sub_16(acc[k], column[k]);
|
||||
}
|
||||
for (; i < added.size(); ++i)
|
||||
for (; i < added.ssize(); ++i)
|
||||
{
|
||||
IndexType index = added[i];
|
||||
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
|
||||
auto* column = reinterpret_cast<const vec_t*>(&featureTransformer.weights[offset]);
|
||||
size_t index = added[i];
|
||||
const size_t offset = Dimensions * index;
|
||||
auto* column = reinterpret_cast<const vec_t*>(&weights[offset]);
|
||||
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = vec_add_16(acc[k], column[k]);
|
||||
@@ -736,6 +740,8 @@ void update_accumulator_refresh_cache(Color pers
|
||||
vec_store(&entryTile[k], acc[k]);
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k++)
|
||||
vec_store(&accTile[k], acc[k]);
|
||||
|
||||
weights += Tiling::TileHeight;
|
||||
}
|
||||
|
||||
for (IndexType j = 0; j < PSQTBuckets / Tiling::PsqtTileHeight; ++j)
|
||||
@@ -748,21 +754,21 @@ void update_accumulator_refresh_cache(Color pers
|
||||
for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
psqt[k] = entryTilePsqt[k];
|
||||
|
||||
for (IndexType i = 0; i < removed.size(); ++i)
|
||||
for (int i = 0; i < removed.ssize(); ++i)
|
||||
{
|
||||
IndexType index = removed[i];
|
||||
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
size_t index = removed[i];
|
||||
const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
reinterpret_cast<const psqt_vec_t*>(&featureTransformer.psqtWeights[offset]);
|
||||
|
||||
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
psqt[k] = vec_sub_psqt_32(psqt[k], columnPsqt[k]);
|
||||
}
|
||||
for (IndexType i = 0; i < added.size(); ++i)
|
||||
for (int i = 0; i < added.ssize(); ++i)
|
||||
{
|
||||
IndexType index = added[i];
|
||||
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
size_t index = added[i];
|
||||
const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
reinterpret_cast<const psqt_vec_t*>(&featureTransformer.psqtWeights[offset]);
|
||||
|
||||
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
@@ -820,6 +826,8 @@ void update_threats_accumulator_full(Color persp
|
||||
vec_t acc[Tiling::NumRegs];
|
||||
psqt_vec_t psqt[Tiling::NumPsqtRegs];
|
||||
|
||||
const auto* threatWeights = &featureTransformer.threatWeights[0];
|
||||
|
||||
for (IndexType j = 0; j < Dimensions / Tiling::TileHeight; ++j)
|
||||
{
|
||||
auto* accTile =
|
||||
@@ -828,14 +836,13 @@ void update_threats_accumulator_full(Color persp
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; ++k)
|
||||
acc[k] = vec_zero();
|
||||
|
||||
IndexType i = 0;
|
||||
int i = 0;
|
||||
|
||||
for (; i < active.size(); ++i)
|
||||
for (; i < active.ssize(); ++i)
|
||||
{
|
||||
IndexType index = active[i];
|
||||
const IndexType offset = Dimensions * index + j * Tiling::TileHeight;
|
||||
auto* column =
|
||||
reinterpret_cast<const vec_i8_t*>(&featureTransformer.threatWeights[offset]);
|
||||
size_t index = active[i];
|
||||
const size_t offset = Dimensions * index;
|
||||
auto* column = reinterpret_cast<const vec_i8_t*>(&threatWeights[offset]);
|
||||
|
||||
#ifdef USE_NEON
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k += 2)
|
||||
@@ -851,6 +858,8 @@ void update_threats_accumulator_full(Color persp
|
||||
|
||||
for (IndexType k = 0; k < Tiling::NumRegs; k++)
|
||||
vec_store(&accTile[k], acc[k]);
|
||||
|
||||
threatWeights += Tiling::TileHeight;
|
||||
}
|
||||
|
||||
for (IndexType j = 0; j < PSQTBuckets / Tiling::PsqtTileHeight; ++j)
|
||||
@@ -861,11 +870,11 @@ void update_threats_accumulator_full(Color persp
|
||||
for (IndexType k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
psqt[k] = vec_zero_psqt();
|
||||
|
||||
for (IndexType i = 0; i < active.size(); ++i)
|
||||
for (int i = 0; i < active.ssize(); ++i)
|
||||
{
|
||||
IndexType index = active[i];
|
||||
const IndexType offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
size_t index = active[i];
|
||||
const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight;
|
||||
auto* columnPsqt =
|
||||
reinterpret_cast<const psqt_vec_t*>(&featureTransformer.threatPsqtWeights[offset]);
|
||||
|
||||
for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k)
|
||||
|
||||
@@ -157,7 +157,6 @@ class AccumulatorStack {
|
||||
[[nodiscard]] const AccumulatorState<T>& latest() const noexcept;
|
||||
|
||||
void reset() noexcept;
|
||||
void push(const DirtyBoardData& dirtyBoardData) noexcept;
|
||||
std::pair<DirtyPiece&, DirtyThreats&> push() noexcept;
|
||||
void pop() noexcept;
|
||||
|
||||
|
||||
@@ -164,22 +164,13 @@ class FeatureTransformer {
|
||||
|
||||
if (UseThreats)
|
||||
{
|
||||
auto combinedWeights =
|
||||
std::make_unique<std::array<WeightType, HalfDimensions * TotalInputDimensions>>();
|
||||
read_little_endian<ThreatWeightType>(stream, threatWeights.data(),
|
||||
ThreatInputDimensions * HalfDimensions);
|
||||
read_leb_128<WeightType>(stream, weights);
|
||||
|
||||
auto combinedPsqtWeights =
|
||||
std::make_unique<std::array<PSQTWeightType, TotalInputDimensions * PSQTBuckets>>();
|
||||
|
||||
read_leb_128<WeightType>(stream, *combinedWeights);
|
||||
|
||||
std::copy(combinedWeights->begin(),
|
||||
combinedWeights->begin() + ThreatInputDimensions * HalfDimensions,
|
||||
std::begin(threatWeights));
|
||||
|
||||
std::copy(combinedWeights->begin() + ThreatInputDimensions * HalfDimensions,
|
||||
combinedWeights->begin()
|
||||
+ (ThreatInputDimensions + InputDimensions) * HalfDimensions,
|
||||
std::begin(weights));
|
||||
|
||||
read_leb_128<PSQTWeightType>(stream, *combinedPsqtWeights);
|
||||
|
||||
std::copy(combinedPsqtWeights->begin(),
|
||||
@@ -218,21 +209,13 @@ class FeatureTransformer {
|
||||
|
||||
if (UseThreats)
|
||||
{
|
||||
auto combinedWeights =
|
||||
std::make_unique<std::array<WeightType, HalfDimensions * TotalInputDimensions>>();
|
||||
write_little_endian<ThreatWeightType>(stream, copy->threatWeights.data(),
|
||||
ThreatInputDimensions * HalfDimensions);
|
||||
write_leb_128<WeightType>(stream, copy->weights);
|
||||
|
||||
auto combinedPsqtWeights =
|
||||
std::make_unique<std::array<PSQTWeightType, TotalInputDimensions * PSQTBuckets>>();
|
||||
|
||||
std::copy(std::begin(copy->threatWeights),
|
||||
std::begin(copy->threatWeights) + ThreatInputDimensions * HalfDimensions,
|
||||
combinedWeights->begin());
|
||||
|
||||
std::copy(std::begin(copy->weights),
|
||||
std::begin(copy->weights) + InputDimensions * HalfDimensions,
|
||||
combinedWeights->begin() + ThreatInputDimensions * HalfDimensions);
|
||||
|
||||
write_leb_128<WeightType>(stream, *combinedWeights);
|
||||
|
||||
std::copy(std::begin(copy->threatPsqtWeights),
|
||||
std::begin(copy->threatPsqtWeights) + ThreatInputDimensions * PSQTBuckets,
|
||||
combinedPsqtWeights->begin());
|
||||
|
||||
+13
-39
@@ -911,7 +911,7 @@ void Position::do_move(Move m,
|
||||
|
||||
if (more_than_one(pawns))
|
||||
{
|
||||
// If there are two pawns potentially being abled to capture and at least one
|
||||
// If there are two pawns potentially being able to capture and at least one
|
||||
// is not pinned, ep is legal as there are no horizontal exposed checks
|
||||
if (!more_than_one(blockers_for_king(them) & pawns))
|
||||
{
|
||||
@@ -1093,10 +1093,10 @@ void write_multiple_dirties(const Position& p,
|
||||
#endif
|
||||
|
||||
template<bool PutPiece, bool ComputeRay>
|
||||
void Position::update_piece_threats(Piece pc,
|
||||
Square s,
|
||||
DirtyThreats* const dts,
|
||||
Bitboard noRaysContaining) {
|
||||
void Position::update_piece_threats(Piece pc,
|
||||
Square s,
|
||||
DirtyThreats* const dts,
|
||||
[[maybe_unused]] Bitboard noRaysContaining) const {
|
||||
const Bitboard occupied = pieces();
|
||||
const Bitboard rookQueens = pieces(ROOK, QUEEN);
|
||||
const Bitboard bishopQueens = pieces(BISHOP, QUEEN);
|
||||
@@ -1108,35 +1108,8 @@ void Position::update_piece_threats(Piece pc,
|
||||
const Bitboard rAttacks = attacks_bb<ROOK>(s, occupied);
|
||||
const Bitboard bAttacks = attacks_bb<BISHOP>(s, occupied);
|
||||
|
||||
Bitboard qAttacks = Bitboard(0);
|
||||
if constexpr (ComputeRay)
|
||||
qAttacks = rAttacks | bAttacks;
|
||||
else if (type_of(pc) == QUEEN)
|
||||
qAttacks = rAttacks | bAttacks;
|
||||
|
||||
Bitboard threatened;
|
||||
|
||||
switch (type_of(pc))
|
||||
{
|
||||
case PAWN :
|
||||
threatened = PseudoAttacks[color_of(pc)][s];
|
||||
break;
|
||||
case BISHOP :
|
||||
threatened = bAttacks;
|
||||
break;
|
||||
case ROOK :
|
||||
threatened = rAttacks;
|
||||
break;
|
||||
case QUEEN :
|
||||
threatened = qAttacks;
|
||||
break;
|
||||
|
||||
default :
|
||||
threatened = PseudoAttacks[type_of(pc)][s];
|
||||
}
|
||||
|
||||
threatened &= occupied;
|
||||
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
|
||||
Bitboard threatened = attacks_bb(pc, s, occupied) & occupied;
|
||||
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
|
||||
Bitboard incoming_threats =
|
||||
(PseudoAttacks[KNIGHT][s] & knights) | (attacks_bb<PAWN>(s, WHITE) & blackPawns)
|
||||
| (attacks_bb<PAWN>(s, BLACK) & whitePawns) | (PseudoAttacks[KING][s] & kings);
|
||||
@@ -1159,8 +1132,11 @@ void Position::update_piece_threats(Piece pc,
|
||||
if (!all_attackers)
|
||||
return; // Square s is threatened iff there's at least one attacker
|
||||
|
||||
dts->threatenedSqs |= square_bb(s);
|
||||
dts->threateningSqs |= all_attackers;
|
||||
if constexpr (PutPiece)
|
||||
{
|
||||
dts->threatenedSqs |= square_bb(s);
|
||||
dts->threateningSqs |= all_attackers;
|
||||
}
|
||||
|
||||
DirtyThreat dt_template{NO_PIECE, pc, Square(0), s, PutPiece};
|
||||
write_multiple_dirties<DirtyThreat::PcSqOffset, DirtyThreat::PcOffset>(*this, all_attackers,
|
||||
@@ -1186,7 +1162,7 @@ void Position::update_piece_threats(Piece pc,
|
||||
Piece slider = piece_on(sliderSq);
|
||||
|
||||
const Bitboard ray = RayPassBB[sliderSq][s] & ~BetweenBB[sliderSq][s];
|
||||
const Bitboard discovered = ray & qAttacks & occupied;
|
||||
const Bitboard discovered = ray & (rAttacks | bAttacks) & occupied;
|
||||
|
||||
assert(!more_than_one(discovered));
|
||||
if (discovered && (RayPassBB[sliderSq][s] & noRaysContaining) != noRaysContaining)
|
||||
@@ -1249,8 +1225,6 @@ void Position::do_castling(Color us,
|
||||
// Remove both pieces first since squares could overlap in Chess960
|
||||
remove_piece(Do ? from : to, dts);
|
||||
remove_piece(Do ? rfrom : rto, dts);
|
||||
board[Do ? from : to] = board[Do ? rfrom : rto] =
|
||||
NO_PIECE; // remove_piece does not do this for us
|
||||
put_piece(make_piece(us, KING), Do ? to : from, dts);
|
||||
put_piece(make_piece(us, ROOK), Do ? rto : rfrom, dts);
|
||||
}
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@ class Position {
|
||||
void update_piece_threats(Piece pc,
|
||||
Square s,
|
||||
DirtyThreats* const dts,
|
||||
Bitboard noRaysContaining = -1ULL);
|
||||
Bitboard noRaysContaining = -1ULL) const;
|
||||
void move_piece(Square from, Square to, DirtyThreats* const dts = nullptr);
|
||||
template<bool Do>
|
||||
void do_castling(Color us,
|
||||
|
||||
+7
-15
@@ -142,9 +142,8 @@ void update_all_stats(const Position& pos,
|
||||
Move TTMove,
|
||||
int moveCount);
|
||||
|
||||
bool isShuffling(Move move, Stack* const ss, const Position& pos) {
|
||||
if (type_of(pos.moved_piece(move)) == PAWN || pos.capture_stage(move)
|
||||
|| pos.rule50_count() < 10)
|
||||
bool is_shuffling(Move move, Stack* const ss, const Position& pos) {
|
||||
if (pos.capture_stage(move) || pos.rule50_count() < 10)
|
||||
return false;
|
||||
if (pos.state()->pliesFromNull <= 6 || ss->ply < 20)
|
||||
return false;
|
||||
@@ -747,18 +746,12 @@ Value Search::Worker::search(
|
||||
ss->ttPv = excludedMove ? ss->ttPv : PvNode || (ttHit && ttData.is_pv);
|
||||
ttCapture = ttData.move && pos.capture_stage(ttData.move);
|
||||
|
||||
// At this point, if excluded, skip straight to step 6, static eval. However,
|
||||
// to save indentation, we list the condition in all code between here and there.
|
||||
|
||||
// Step 6. Static evaluation of the position
|
||||
Value unadjustedStaticEval = VALUE_NONE;
|
||||
const auto correctionValue = correction_value(*this, pos, ss);
|
||||
// Skip early pruning when in check
|
||||
if (ss->inCheck)
|
||||
{
|
||||
// Skip early pruning when in check
|
||||
ss->staticEval = eval = (ss - 2)->staticEval;
|
||||
improving = false;
|
||||
}
|
||||
else if (excludedMove)
|
||||
unadjustedStaticEval = eval = ss->staticEval;
|
||||
else if (ss->ttHit)
|
||||
@@ -923,9 +916,8 @@ Value Search::Worker::search(
|
||||
auto futility_margin = [&](Depth d) {
|
||||
Value futilityMult = 76 - 23 * !ss->ttHit;
|
||||
|
||||
return futilityMult * d //
|
||||
- 2474 * improving * futilityMult / 1024 //
|
||||
- 331 * opponentWorsening * futilityMult / 1024 //
|
||||
return futilityMult * d
|
||||
- (2474 * improving + 331 * opponentWorsening) * futilityMult / 1024 //
|
||||
+ std::abs(correctionValue) / 174665;
|
||||
};
|
||||
|
||||
@@ -1174,7 +1166,7 @@ moves_loop: // When in check, search starts here
|
||||
// and lower extension margins scale well.
|
||||
if (!rootNode && move == ttData.move && !excludedMove && depth >= 6 + ss->ttPv
|
||||
&& is_valid(ttData.value) && !is_decisive(ttData.value) && (ttData.bound & BOUND_LOWER)
|
||||
&& ttData.depth >= depth - 3 && !isShuffling(move, ss, pos))
|
||||
&& ttData.depth >= depth - 3 && !is_shuffling(move, ss, pos))
|
||||
{
|
||||
Value singularBeta = ttData.value - (53 + 75 * (ss->ttPv && !PvNode)) * depth / 60;
|
||||
Depth singularDepth = newDepth / 2;
|
||||
@@ -1325,7 +1317,7 @@ moves_loop: // When in check, search starts here
|
||||
// decisive score handling improves mate finding and retrograde analysis.
|
||||
if (move == ttData.move
|
||||
&& ((is_valid(ttData.value) && is_decisive(ttData.value) && ttData.depth > 0)
|
||||
|| (ttData.depth > 1 && rootDepth > 8)))
|
||||
|| ttData.depth > 1))
|
||||
newDepth = std::max(newDepth, 1);
|
||||
|
||||
value = -search<PV>(pos, ss + 1, -beta, -alpha, newDepth, false);
|
||||
|
||||
@@ -586,7 +586,7 @@ int decompress_pairs(PairsData* d, uint64_t idx) {
|
||||
// idx = k * d->span + idx % d->span (2)
|
||||
//
|
||||
// So from (1) and (2) we can compute idx - I(K):
|
||||
int diff = idx % d->span - d->span / 2;
|
||||
int diff = int(idx % d->span - d->span / 2);
|
||||
|
||||
// Sum the above to offset to find the offset corresponding to our idx
|
||||
offset += diff;
|
||||
@@ -1094,7 +1094,7 @@ uint8_t* set_sizes(PairsData* d, uint8_t* data) {
|
||||
// See https://web.archive.org/web/20201106232444/http://www.larsson.dogma.net/dcc99.pdf
|
||||
std::vector<bool> visited(d->symlen.size());
|
||||
|
||||
for (std::size_t sym = 0; sym < d->symlen.size(); ++sym)
|
||||
for (Sym sym = 0; sym < d->symlen.size(); ++sym)
|
||||
if (!visited[sym])
|
||||
d->symlen[sym] = set_symlen(d, sym, visited);
|
||||
|
||||
|
||||
+2
-2
@@ -286,8 +286,8 @@ void ThreadPool::start_thinking(const OptionsMap& options,
|
||||
{
|
||||
th->run_custom_job([&]() {
|
||||
th->worker->limits = limits;
|
||||
th->worker->nodes = th->worker->tbHits = th->worker->nmpMinPly =
|
||||
th->worker->bestMoveChanges = 0;
|
||||
th->worker->nodes = th->worker->tbHits = th->worker->bestMoveChanges = 0;
|
||||
th->worker->nmpMinPly = 0;
|
||||
th->worker->rootDepth = th->worker->completedDepth = 0;
|
||||
th->worker->rootMoves = rootMoves;
|
||||
th->worker->rootPos.set(pos.fen(), pos.is_chess960(), &th->worker->rootState);
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ void TimeManagement::init(Search::LimitsType& limits,
|
||||
|
||||
// If less than one second, gradually reduce mtg
|
||||
if (scaledTime < 1000)
|
||||
centiMTG = scaledTime * 5.051;
|
||||
centiMTG = int(scaledTime * 5.051);
|
||||
|
||||
// Make sure timeLeft is > 0 since we may use it as a divisor
|
||||
TimePoint timeLeft =
|
||||
|
||||
@@ -110,8 +110,6 @@ void TTEntry::save(
|
||||
value16 = int16_t(v);
|
||||
eval16 = int16_t(ev);
|
||||
}
|
||||
else if (depth8 + DEPTH_ENTRY_OFFSET >= 5 && Bound(genBound8 & 0x3) != BOUND_EXACT)
|
||||
depth8--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+9
-13
@@ -306,24 +306,25 @@ struct DirtyThreat {
|
||||
| (threatened_sq << ThreatenedSqOffset) | (pc_sq << PcSqOffset);
|
||||
}
|
||||
|
||||
Piece pc() const { return static_cast<Piece>(data >> 20 & 0xf); }
|
||||
Piece threatened_pc() const { return static_cast<Piece>(data >> 16 & 0xf); }
|
||||
Square threatened_sq() const { return static_cast<Square>(data >> 8 & 0xff); }
|
||||
Square pc_sq() const { return static_cast<Square>(data & 0xff); }
|
||||
bool add() const { return data >> 31; }
|
||||
Piece pc() const { return static_cast<Piece>(data >> PcOffset & 0xf); }
|
||||
Piece threatened_pc() const { return static_cast<Piece>(data >> ThreatenedPcOffset & 0xf); }
|
||||
Square threatened_sq() const { return static_cast<Square>(data >> ThreatenedSqOffset & 0xff); }
|
||||
Square pc_sq() const { return static_cast<Square>(data >> PcSqOffset & 0xff); }
|
||||
bool add() const { return data >> 31; }
|
||||
uint32_t raw() const { return data; }
|
||||
|
||||
private:
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
using DirtyThreatList = ValueList<DirtyThreat, 96>;
|
||||
|
||||
// A piece can be involved in at most 8 outgoing attacks and 16 incoming attacks.
|
||||
// Moving a piece also can reveal at most 8 discovered attacks.
|
||||
// This implies that a non-castling move can change at most (8 + 16) * 3 + 8 = 80 features.
|
||||
// By similar logic, a castling move can change at most (5 + 1 + 3 + 9) * 2 = 36 features.
|
||||
// Thus, 80 should work as an upper bound.
|
||||
// Thus, 80 should work as an upper bound. Finally, 16 entries are added to accommodate
|
||||
// unmasked vector stores near the end of the list.
|
||||
|
||||
using DirtyThreatList = ValueList<DirtyThreat, 96>;
|
||||
|
||||
struct DirtyThreats {
|
||||
DirtyThreatList list;
|
||||
@@ -333,11 +334,6 @@ struct DirtyThreats {
|
||||
Bitboard threatenedSqs, threateningSqs;
|
||||
};
|
||||
|
||||
struct DirtyBoardData {
|
||||
DirtyPiece dp;
|
||||
DirtyThreats dts;
|
||||
};
|
||||
|
||||
#define ENABLE_INCR_OPERATORS_ON(T) \
|
||||
constexpr T& operator++(T& d) { return d = T(int(d) + 1); } \
|
||||
constexpr T& operator--(T& d) { return d = T(int(d) - 1); }
|
||||
|
||||
+7
-6
@@ -319,8 +319,8 @@ void UCIEngine::benchmark(std::istream& args) {
|
||||
|
||||
Benchmark::BenchmarkSetup setup = Benchmark::setup_benchmark(args);
|
||||
|
||||
const int numGoCommands = count_if(setup.commands.begin(), setup.commands.end(),
|
||||
[](const std::string& s) { return s.find("go ") == 0; });
|
||||
const auto numGoCommands = count_if(setup.commands.begin(), setup.commands.end(),
|
||||
[](const std::string& s) { return s.find("go ") == 0; });
|
||||
|
||||
TimePoint totalTime = 0;
|
||||
|
||||
@@ -367,13 +367,14 @@ void UCIEngine::benchmark(std::istream& args) {
|
||||
|
||||
int numHashfullReadings = 0;
|
||||
constexpr int hashfullAges[] = {0, 999}; // Only normal hashfull and touched hash.
|
||||
int totalHashfull[std::size(hashfullAges)] = {0};
|
||||
int maxHashfull[std::size(hashfullAges)] = {0};
|
||||
constexpr int hashfullAgeCount = std::size(hashfullAges);
|
||||
int totalHashfull[hashfullAgeCount] = {0};
|
||||
int maxHashfull[hashfullAgeCount] = {0};
|
||||
|
||||
auto updateHashfullReadings = [&]() {
|
||||
numHashfullReadings += 1;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(std::size(hashfullAges)); ++i)
|
||||
for (int i = 0; i < hashfullAgeCount; ++i)
|
||||
{
|
||||
const int hashfull = engine.get_hashfull(hashfullAges[i]);
|
||||
maxHashfull[i] = std::max(maxHashfull[i], hashfull);
|
||||
@@ -561,7 +562,7 @@ int UCIEngine::to_cp(Value v, const Position& pos) {
|
||||
|
||||
auto [a, b] = win_rate_params(pos);
|
||||
|
||||
return std::round(100 * int(v) / a);
|
||||
return int(std::round(100 * int(v) / a));
|
||||
}
|
||||
|
||||
std::string UCIEngine::wdl(Value v, const Position& pos) {
|
||||
|
||||
Reference in New Issue
Block a user