From 7f51610103dd5a62d9fea37c809d54e331d52de3 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sat, 17 Jan 2015 23:01:10 +0000 Subject: [PATCH 01/15] Don't print fail-high or fail-lows in MultiPV mode Supposed to give a better user experience when using MultiPV mode No functional change Resolves #217 --- src/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index 564653ef..cdbf9897 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -365,7 +365,8 @@ namespace { // When failing high/low give some update (without cluttering // the UI) before a re-search. - if ( (bestValue <= alpha || bestValue >= beta) + if ( multiPV == 1 + && (bestValue <= alpha || bestValue >= beta) && Time::now() - SearchTime > 3000) sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl; From 1b62b47b6276a7eae1ea51d858c8d308ad34c675 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sun, 18 Jan 2015 09:04:49 +0000 Subject: [PATCH 02/15] Fix profile build for gcc on Mac OSX Switch back to using -fprofile-generate and -fprofile-use flags No functional change Resolves #219 Resolves #210 --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 53bbc1f4..1f4ce735 100644 --- a/src/Makefile +++ b/src/Makefile @@ -447,7 +447,7 @@ gcc-profile-prepare: gcc-profile-make: $(MAKE) ARCH=$(ARCH) COMP=$(COMP) \ - EXTRACXXFLAGS='-fprofile-arcs' \ + EXTRACXXFLAGS='-fprofile-generate' \ EXTRALDFLAGS='-lgcov' \ all @@ -456,7 +456,7 @@ gcc-profile-use: # "internal compiler error" for gcc versions 4.7.x @rm -f ucioption.gc* $(MAKE) ARCH=$(ARCH) COMP=$(COMP) \ - EXTRACXXFLAGS='-fbranch-probabilities' \ + EXTRACXXFLAGS='-fprofile-use' \ EXTRALDFLAGS='-lgcov' \ all From 97a034ad3e8b25f0e8e1dd03d31f4689180f7547 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sat, 17 Jan 2015 23:19:18 +0000 Subject: [PATCH 03/15] Stockfish 6 Release Candidate 1 Bench: 8080602 No functional change Resolves #218 --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 656b3155..9dbbe48a 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -31,7 +31,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = ""; +const string Version = "6 RC1"; /// Debug counters int64_t hits[2], means[2]; From 44643c277007e3902586418541c0c22ff110fde1 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Tue, 20 Jan 2015 09:13:30 +0100 Subject: [PATCH 04/15] Try hard to retrieve a ponder move In case we stop the search during a fail-high it is possible we return to GUI without a ponder move. This patch try harder to find a ponder move retrieving it from TT. This is important in games played with 'ponder on'. bench: 8080602 Resolves #221 --- src/search.cpp | 26 +++++++++++++++++++++++++- src/search.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index cdbf9897..da306a1a 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -276,7 +276,7 @@ void Search::think() { sync_cout << "bestmove " << UCI::move(RootMoves[0].pv[0], RootPos.is_chess960()); - if (RootMoves[0].pv.size() > 1) + if (RootMoves[0].pv.size() > 1 || RootMoves[0].extract_ponder_from_tt(RootPos)) std::cout << " ponder " << UCI::move(RootMoves[0].pv[1], RootPos.is_chess960()); std::cout << sync_endl; @@ -1491,6 +1491,30 @@ void RootMove::insert_pv_in_tt(Position& pos) { } +/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move before +/// exiting the search, for instance in case we stop the search during a fail high at +/// root. We try hard to have a ponder move to return to the GUI, otherwise in case of +/// 'ponder on' we have nothing to think on. + +Move RootMove::extract_ponder_from_tt(Position& pos) +{ + StateInfo st; + bool found; + + assert(pv.size() == 1); + + pos.do_move(pv[0], st); + TTEntry* tte = TT.probe(pos.key(), found); + Move m = found ? tte->move() : MOVE_NONE; + if (!MoveList(pos).contains(m)) + m = MOVE_NONE; + + pos.undo_move(pv[0]); + pv.push_back(m); + return m; +} + + /// Thread::idle_loop() is where the thread is parked when it has no work to do void Thread::idle_loop() { diff --git a/src/search.h b/src/search.h index 409e9e75..5a0ad5df 100644 --- a/src/search.h +++ b/src/search.h @@ -60,6 +60,7 @@ struct RootMove { bool operator<(const RootMove& m) const { return score > m.score; } // Ascending sort bool operator==(const Move& m) const { return pv[0] == m; } void insert_pv_in_tt(Position& pos); + Move extract_ponder_from_tt(Position& pos); Value score; Value previousScore; From 54b5b528d9ef6c4f14a2000eead9a5c0686f899e Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Tue, 20 Jan 2015 22:17:22 +0100 Subject: [PATCH 05/15] Don't use _pext_u64() directly This intrinsic to call BMI2 PEXT instruction is defined in immintrin.h. This header should be included only when USE_PEXT is defined, otherwise we define _pext_u64 as 0 forcing a nop. But under some mingw platforms, even if we don't include the header, immintrin.h gets included anyhow through an include chain that starts with STL header. So we end up both defining _pext_u64 function and at the same time defining _pext_u64 as 0 leading to a compile error. The correct solution is of not using _pext_u64 directly. This patch fixes a compile error with some mingw64 package when compiling with x86-64. No functional change. Resolves #222 --- src/bitboard.cpp | 2 +- src/bitboard.h | 2 +- src/types.h | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index 4a0e275b..32efaeda 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -275,7 +275,7 @@ namespace { reference[size] = sliding_attack(deltas, s, b); if (HasPext) - attacks[s][_pext_u64(b, masks[s])] = reference[size]; + attacks[s][pext(b, masks[s])] = reference[size]; size++; b = (b - masks[s]) & masks[s]; diff --git a/src/bitboard.h b/src/bitboard.h index 38ddc619..aa4e1711 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -238,7 +238,7 @@ FORCE_INLINE unsigned magic_index(Square s, Bitboard occupied) { unsigned* const Shifts = Pt == ROOK ? RookShifts : BishopShifts; if (HasPext) - return unsigned(_pext_u64(occupied, Masks[s])); + return unsigned(pext(occupied, Masks[s])); if (Is64Bit) return unsigned(((occupied & Masks[s]) * Magics[s]) >> Shifts[s]); diff --git a/src/types.h b/src/types.h index 2d769630..7c5776ab 100644 --- a/src/types.h +++ b/src/types.h @@ -65,8 +65,9 @@ #if defined(USE_PEXT) # include // Header for _pext_u64() intrinsic +# define pext(b, m) _pext_u64(b, m) #else -# define _pext_u64(b, m) (0) +# define pext(b, m) (0) #endif #ifdef _MSC_VER From 5154ac9cff432574eefd461c54eb646ddf6e96e6 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sat, 24 Jan 2015 19:38:59 +0000 Subject: [PATCH 06/15] Stockfish 6 Release Candidate 2 - Fix a compilation issue related to BMI2 PEXT instruction - Retrieve a ponder move from TT if PV is only one move long Bench: 8080602 No functional change --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 9dbbe48a..3306eca4 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -31,7 +31,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = "6 RC1"; +const string Version = "6 RC2"; /// Debug counters int64_t hits[2], means[2]; From 8ebf30d44a7ca1d708f2a1bb659d2817baaa6850 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 19 Jan 2015 08:11:43 +0100 Subject: [PATCH 07/15] Fix a MSVC warning at W4 Warning is C4512 (assignment operator could not be generated) Now, apart the foreign syzygy code, everything compiles without warnings at warning level 4. Backported from C++11 branch. No functional change. --- src/endgame.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/endgame.h b/src/endgame.h index 8a42eda2..d7a7681a 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -89,7 +89,7 @@ struct Endgame : public EndgameBase { T operator()(const Position&) const; private: - const Color strongSide, weakSide; + Color strongSide, weakSide; }; From ec36b8dea91f2a7a9c5914557fa06435e00e67db Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sun, 25 Jan 2015 21:46:02 +0000 Subject: [PATCH 08/15] Revert "Fix profile build for gcc on Mac OSX" Seems to be a performance regression for standard build. For SF6 people compiling on Mac OSX using profile-build option just need to make necessary adjustments manually... No functional change Resolves #223 --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 1f4ce735..53bbc1f4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -447,7 +447,7 @@ gcc-profile-prepare: gcc-profile-make: $(MAKE) ARCH=$(ARCH) COMP=$(COMP) \ - EXTRACXXFLAGS='-fprofile-generate' \ + EXTRACXXFLAGS='-fprofile-arcs' \ EXTRALDFLAGS='-lgcov' \ all @@ -456,7 +456,7 @@ gcc-profile-use: # "internal compiler error" for gcc versions 4.7.x @rm -f ucioption.gc* $(MAKE) ARCH=$(ARCH) COMP=$(COMP) \ - EXTRACXXFLAGS='-fprofile-use' \ + EXTRACXXFLAGS='-fbranch-probabilities' \ EXTRALDFLAGS='-lgcov' \ all From d8b3ad2208328e2ed35c34c450b539918ee5c87e Mon Sep 17 00:00:00 2001 From: Stefan Geschwentner Date: Sat, 24 Jan 2015 22:05:06 +0100 Subject: [PATCH 09/15] Fix a skill level problem: Don't allow move pruning at root node Bench: 8918745 Resolves #231 --- src/search.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index da306a1a..0ce836f7 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -831,7 +831,8 @@ moves_loop: // When in check and at SpNode search starts from here newDepth = depth - ONE_PLY + extension; // Step 13. Pruning at shallow depth - if ( !captureOrPromotion + if ( !RootNode + && !captureOrPromotion && !inCheck && !dangerous && bestValue > VALUE_MATED_IN_MAX_PLY) From c4518e395eb819bb7b96f30c148a51bfe78479e1 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Sun, 25 Jan 2015 22:03:57 +0000 Subject: [PATCH 10/15] Stockfish 6 Release Candidate 3 - Fix a skill level problem: Don't allow move pruning at root node - Revert "Fix profile build for gcc on Mac OSX". Results for a faster binary in x86-64. - Fix a MSVC warning Bench: 8918745 --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 3306eca4..78e8e442 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -31,7 +31,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = "6 RC2"; +const string Version = "6 RC3"; /// Debug counters int64_t hits[2], means[2]; From 5b555525d2f9cbff446b7461d1317948e8e21cd1 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Tue, 27 Jan 2015 20:27:38 +0000 Subject: [PATCH 11/15] Stockfish 6 Stockfish bench signature is: 8918745 --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 78e8e442..59511db3 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -31,7 +31,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = "6 RC3"; +const string Version = "6"; /// Debug counters int64_t hits[2], means[2]; From 9f0d5241bfcf454d4b21594b0af239bbe5990b84 Mon Sep 17 00:00:00 2001 From: Joona Kiiski Date: Wed, 28 Jan 2015 20:53:50 +0000 Subject: [PATCH 12/15] Restore development version No functional change --- src/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc.cpp b/src/misc.cpp index 59511db3..656b3155 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -31,7 +31,7 @@ namespace { /// Version number. If Version is left empty, then compile date in the format /// DD-MM-YY and show in engine_info. -const string Version = "6"; +const string Version = ""; /// Debug counters int64_t hits[2], means[2]; From 7837fb2aca6db425e5f7237f5cc714412fc0140d Mon Sep 17 00:00:00 2001 From: NicklasPersson Date: Wed, 28 Jan 2015 21:00:09 +0000 Subject: [PATCH 13/15] King safety tuning with values obtained by SPSA. Part I: LTC: LLR: 2.96 (-2.94,2.94) [0.00,4.00] Total: 11529 W: 2075 L: 1882 D: 7572 Part II: LTC: ELO: 2.07 +-2.1 (95%) LOS: 97.3% Total: 34859 W: 5967 L: 5759 D: 23133 Bench: 7374604 Resolves #228 --- src/evaluate.cpp | 30 +++++++++++++++--------------- src/pawns.cpp | 42 +++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 45c5b0a8..8e5a7f82 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -91,7 +91,7 @@ namespace { // Evaluation weights, indexed by evaluation term enum { Mobility, PawnStructure, PassedPawns, Space, KingSafety }; const struct Weight { int mg, eg; } Weights[] = { - {289, 344}, {233, 201}, {221, 273}, {46, 0}, {321, 0} + {289, 344}, {233, 201}, {221, 273}, {46, 0}, {324, 0} }; #define V(v) Value(v) @@ -186,15 +186,15 @@ namespace { // index to KingDanger[]. // // KingAttackWeights[PieceType] contains king attack weights by piece type - const int KingAttackWeights[] = { 0, 0, 6, 2, 5, 5 }; + const int KingAttackWeights[] = { 0, 0, 8, 4, 4, 1 }; // Bonuses for enemy's safe checks - const int QueenContactCheck = 92; - const int RookContactCheck = 68; - const int QueenCheck = 50; - const int RookCheck = 36; - const int BishopCheck = 7; - const int KnightCheck = 14; + const int QueenContactCheck = 89; + const int RookContactCheck = 72; + const int QueenCheck = 51; + const int RookCheck = 38; + const int BishopCheck = 5; + const int KnightCheck = 16; // KingDanger[attackUnits] contains the actual king danger weighted // scores, indexed by a calculated integer number. @@ -411,11 +411,11 @@ namespace { // number and types of the enemy's attacking pieces, the number of // attacked and undefended squares around our king and the quality of // the pawn shelter (current 'score' value). - attackUnits = std::min(77, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) - + 10 * ei.kingAdjacentZoneAttacksCount[Them] - + 19 * popcount(undefended) - + 9 * (ei.pinnedPieces[Us] != 0) - - mg_value(score) * 63 / 512 + attackUnits = std::min(74, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) + + 9 * ei.kingAdjacentZoneAttacksCount[Them] + + 25 * popcount(undefended) + + 10 * (ei.pinnedPieces[Us] != 0) + - mg_value(score) / 8 - !pos.count(Them) * 60; // Analyse the enemy's safe queen contact checks. Firstly, find the @@ -891,13 +891,13 @@ namespace Eval { void init() { - const double MaxSlope = 7.5; + const double MaxSlope = 8.5; const double Peak = 1280; double t = 0.0; for (int i = 1; i < 400; ++i) { - t = std::min(Peak, std::min(0.025 * i * i, t + MaxSlope)); + t = std::min(Peak, std::min(0.027 * i * i, t + MaxSlope)); KingDanger[i] = apply_weight(make_score(int(t), 0), Weights[KingSafety]); } } diff --git a/src/pawns.cpp b/src/pawns.cpp index 336638ea..eda707ff 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -63,33 +63,33 @@ namespace { // Weakness of our pawn shelter in front of the king by [distance from edge][rank] const Value ShelterWeakness[][RANK_NB] = { - { V(100), V(13), V(24), V(64), V(89), V( 93), V(104) }, - { V(110), V( 1), V(29), V(75), V(96), V(102), V(107) }, - { V(102), V( 0), V(39), V(74), V(88), V(101), V( 98) }, - { V( 88), V( 4), V(33), V(67), V(92), V( 94), V(107) } }; + { V( 99), V(23), V(24), V(54), V(85), V( 93), V(107) }, + { V(119), V( 2), V(28), V(72), V(96), V(104), V(114) }, + { V(103), V( 6), V(47), V(74), V(84), V(103), V( 94) }, + { V( 78), V(10), V(41), V(64), V(88), V( 92), V(115) } }; // Danger of enemy pawns moving toward our king by [type][distance from edge][rank] const Value StormDanger[][4][RANK_NB] = { - { { V( 0), V( 63), V( 128), V(43), V(27) }, - { V( 0), V( 62), V( 131), V(44), V(26) }, - { V( 0), V( 59), V( 121), V(50), V(28) }, - { V( 0), V( 62), V( 127), V(54), V(28) } }, - { { V(24), V( 40), V( 93), V(42), V(22) }, - { V(24), V( 28), V( 101), V(38), V(20) }, - { V(24), V( 32), V( 95), V(36), V(23) }, - { V(27), V( 24), V( 99), V(36), V(24) } }, - { { V( 0), V( 0), V( 81), V(16), V( 6) }, - { V( 0), V( 0), V( 165), V(29), V( 9) }, - { V( 0), V( 0), V( 163), V(23), V(12) }, - { V( 0), V( 0), V( 161), V(28), V(13) } }, - { { V( 0), V(-296), V(-299), V(55), V(25) }, - { V( 0), V( 67), V( 131), V(46), V(21) }, - { V( 0), V( 65), V( 135), V(50), V(31) }, - { V( 0), V( 62), V( 128), V(51), V(24) } } }; + { { V( 0), V( 65), V( 125), V(37), V(30) }, + { V( 0), V( 57), V( 136), V(39), V(24) }, + { V( 0), V( 50), V( 114), V(45), V(29) }, + { V( 0), V( 58), V( 129), V(56), V(34) } }, + { { V(20), V( 45), V( 91), V(47), V(20) }, + { V(25), V( 23), V( 105), V(38), V(14) }, + { V(21), V( 37), V( 99), V(35), V(21) }, + { V(30), V( 18), V( 105), V(38), V(28) } }, + { { V( 0), V( 0), V( 81), V(13), V( 4) }, + { V( 0), V( 0), V( 169), V(30), V( 4) }, + { V( 0), V( 0), V( 166), V(24), V( 6) }, + { V( 0), V( 0), V( 164), V(24), V(11) } }, + { { V( 0), V(-289), V(-297), V(57), V(29) }, + { V( 0), V( 66), V( 136), V(43), V(16) }, + { V( 0), V( 66), V( 141), V(50), V(31) }, + { V( 0), V( 63), V( 126), V(52), V(23) } } }; // Max bonus for king safety. Corresponds to start position with all the pawns // in front of the king and no enemy pawn on the horizon. - const Value MaxSafetyBonus = V(257); + const Value MaxSafetyBonus = V(252); #undef S #undef V From 8aa8608c2a30acc56c4bb4467309cef5089fb2bd Mon Sep 17 00:00:00 2001 From: Alain SAVARD Date: Mon, 26 Jan 2015 11:05:53 -0500 Subject: [PATCH 14/15] Simplify backward pawn definition Make use of 'lever' attribute No functional change Resolves #234 --- src/pawns.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/pawns.cpp b/src/pawns.cpp index eda707ff..798bc0a0 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -144,12 +144,11 @@ namespace { lever = theirPawns & pawnAttacksBB[s]; // Test for backward pawn. - // If the pawn is passed, isolated, or connected it cannot be + // If the pawn is passed, isolated, connected or a lever it cannot be // backward. If there are friendly pawns behind on adjacent files - // or if it can capture an enemy pawn it cannot be backward either. - if ( (passed | isolated | connected) - || (ourPawns & pawn_attack_span(Them, s)) - || (pos.attacks_from(s, Us) & theirPawns)) + // it cannot be backward either. + if ( (passed | isolated | connected | lever) + || (ourPawns & pawn_attack_span(Them, s))) backward = false; else { From ce0a95c2c013f4aa9d41a80b8f12f005fe162fcb Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sun, 25 Jan 2015 19:22:43 +0100 Subject: [PATCH 15/15] Simplify skill level and reduce ELO This patch has two positive effects: - Retire a hackish formula and leave just a natural, simple and plain one. - Reduce strenght at very low level, but don't impact medium/high levels. Actually even at level 0, SF is still too strong for many beginners (this was reported many times for instance on Droidfish user comments on Google Play). Test on fishtest shows that ELO drop is around 170 ELO at level 0 (good!), 130 ELO at level 1 and smoothly reduces (as expected) until level 10 where the drop is just of 8 ELO. No functional change. --- src/search.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 0ce836f7..3c32c4bb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1393,10 +1393,6 @@ moves_loop: // When in check and at SpNode search starts from here { int score = RootMoves[i].score; - // Don't allow crazy blunders even at very low skills - if (i > 0 && RootMoves[i - 1].score > score + 2 * PawnValueMg) - break; - // This is our magic formula score += ( weakness * int(RootMoves[0].score - score) + variance * (rng.rand() % weakness)) / 128;