diff --git a/.github/ci/matrix.json b/.github/ci/matrix.json index f72451f5b..e9215269b 100644 --- a/.github/ci/matrix.json +++ b/.github/ci/matrix.json @@ -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" } } ] diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c2280f0b4..f0da51e7e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -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 diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 136b4031e..039e384c9 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -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(game.size()); ++i) { - const float correctedTime = getCorrectedTime(ply); + const float correctedTime = float(getCorrectedTime(ply)); totalTime += correctedTime; ply += 1; } diff --git a/src/evaluate.h b/src/evaluate.h index 853aeb5b2..8ed2eb994 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -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 { diff --git a/src/history.h b/src/history.h index a605ae417..87004ead9 100644 --- a/src/history.h +++ b/src/history.h @@ -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 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, Sizes...>; // see https://www.chessprogramming.org/Butterfly_Boards using ButterflyHistory = Stats; -// 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; diff --git a/src/misc.cpp b/src/misc.cpp index d21497280..886544b6c 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -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 diff --git a/src/misc.h b/src/misc.h index db5f701e9..c9951e555 100644 --- a/src/misc.h +++ b/src/misc.h @@ -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& 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 diff --git a/src/nnue/nnue_accumulator.cpp b/src/nnue/nnue_accumulator.cpp index 358a4b278..763fb7a5e 100644 --- a/src/nnue/nnue_accumulator.cpp +++ b/src/nnue/nnue_accumulator.cpp @@ -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(&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(&featureTransformer.threatWeights[offset]); + size_t index = removed[i]; + const size_t offset = Dimensions * index; + auto* column = reinterpret_cast(&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(&featureTransformer.threatWeights[offset]); + size_t index = added[i]; + const size_t offset = Dimensions * index; + auto* column = reinterpret_cast(&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( + size_t index = removed[i]; + const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; + auto* columnPsqt = reinterpret_cast( &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( + size_t index = added[i]; + const size_t offset = PSQTBuckets * index + j * Tiling::PsqtTileHeight; + auto* columnPsqt = reinterpret_cast( &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(&featureTransformer.weights[offsetR]); - IndexType indexA = added[i]; - const IndexType offsetA = Dimensions * indexA + j * Tiling::TileHeight; - auto* columnA = reinterpret_cast(&featureTransformer.weights[offsetA]); + size_t indexR = removed[i]; + const size_t offsetR = Dimensions * indexR; + auto* columnR = reinterpret_cast(&weights[offsetR]); + size_t indexA = added[i]; + const size_t offsetA = Dimensions * indexA; + auto* columnA = reinterpret_cast(&weights[offsetA]); for (IndexType k = 0; k < Tiling::NumRegs; ++k) acc[k] = fused(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(&featureTransformer.weights[offset]); + size_t index = removed[i]; + const size_t offset = Dimensions * index; + auto* column = reinterpret_cast(&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(&featureTransformer.weights[offset]); + size_t index = added[i]; + const size_t offset = Dimensions * index; + auto* column = reinterpret_cast(&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(&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(&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(&featureTransformer.threatWeights[offset]); + size_t index = active[i]; + const size_t offset = Dimensions * index; + auto* column = reinterpret_cast(&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(&featureTransformer.threatPsqtWeights[offset]); for (std::size_t k = 0; k < Tiling::NumPsqtRegs; ++k) diff --git a/src/nnue/nnue_accumulator.h b/src/nnue/nnue_accumulator.h index 69ab49632..1ccab5f2f 100644 --- a/src/nnue/nnue_accumulator.h +++ b/src/nnue/nnue_accumulator.h @@ -157,7 +157,6 @@ class AccumulatorStack { [[nodiscard]] const AccumulatorState& latest() const noexcept; void reset() noexcept; - void push(const DirtyBoardData& dirtyBoardData) noexcept; std::pair push() noexcept; void pop() noexcept; diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 1f328fff4..ce23bdf0e 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -164,22 +164,13 @@ class FeatureTransformer { if (UseThreats) { - auto combinedWeights = - std::make_unique>(); + read_little_endian(stream, threatWeights.data(), + ThreatInputDimensions * HalfDimensions); + read_leb_128(stream, weights); + auto combinedPsqtWeights = std::make_unique>(); - read_leb_128(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(stream, *combinedPsqtWeights); std::copy(combinedPsqtWeights->begin(), @@ -218,21 +209,13 @@ class FeatureTransformer { if (UseThreats) { - auto combinedWeights = - std::make_unique>(); + write_little_endian(stream, copy->threatWeights.data(), + ThreatInputDimensions * HalfDimensions); + write_leb_128(stream, copy->weights); + auto combinedPsqtWeights = std::make_unique>(); - 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(stream, *combinedWeights); - std::copy(std::begin(copy->threatPsqtWeights), std::begin(copy->threatPsqtWeights) + ThreatInputDimensions * PSQTBuckets, combinedPsqtWeights->begin()); diff --git a/src/position.cpp b/src/position.cpp index 049c72682..a4286b86a 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -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 -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(s, occupied); const Bitboard bAttacks = attacks_bb(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(s, WHITE) & blackPawns) | (attacks_bb(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(*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); } diff --git a/src/position.h b/src/position.h index 7a029ce18..e5d3f6d28 100644 --- a/src/position.h +++ b/src/position.h @@ -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 void do_castling(Color us, diff --git a/src/search.cpp b/src/search.cpp index 7d621cc8f..8a48f4e09 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -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(pos, ss + 1, -beta, -alpha, newDepth, false); diff --git a/src/syzygy/tbprobe.cpp b/src/syzygy/tbprobe.cpp index f6c4e1215..107a522ea 100644 --- a/src/syzygy/tbprobe.cpp +++ b/src/syzygy/tbprobe.cpp @@ -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 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); diff --git a/src/thread.cpp b/src/thread.cpp index c1b1db8bf..abddaa19b 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -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); diff --git a/src/timeman.cpp b/src/timeman.cpp index 5840e2556..e82a1f6bf 100644 --- a/src/timeman.cpp +++ b/src/timeman.cpp @@ -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 = diff --git a/src/tt.cpp b/src/tt.cpp index 953348987..d7f7dbdef 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -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--; } diff --git a/src/types.h b/src/types.h index c6613f2f2..1bb8bd3cc 100644 --- a/src/types.h +++ b/src/types.h @@ -306,24 +306,25 @@ struct DirtyThreat { | (threatened_sq << ThreatenedSqOffset) | (pc_sq << PcSqOffset); } - Piece pc() const { return static_cast(data >> 20 & 0xf); } - Piece threatened_pc() const { return static_cast(data >> 16 & 0xf); } - Square threatened_sq() const { return static_cast(data >> 8 & 0xff); } - Square pc_sq() const { return static_cast(data & 0xff); } - bool add() const { return data >> 31; } + Piece pc() const { return static_cast(data >> PcOffset & 0xf); } + Piece threatened_pc() const { return static_cast(data >> ThreatenedPcOffset & 0xf); } + Square threatened_sq() const { return static_cast(data >> ThreatenedSqOffset & 0xff); } + Square pc_sq() const { return static_cast(data >> PcSqOffset & 0xff); } + bool add() const { return data >> 31; } uint32_t raw() const { return data; } private: uint32_t data; }; -using DirtyThreatList = ValueList; - // 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; 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); } diff --git a/src/uci.cpp b/src/uci.cpp index 0cdda0c4f..6d4f5331a 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -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(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) {