X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=c66938d6ac7ed65db10745dbff4a3cbd86f4b5c0;hp=d20c7b70f1e12407a4b58a6524469422b252f040;hb=3542033342f15625f808013b69aa8c2d274a2f91;hpb=7f336dd59b3b1365943d73ee706a9610e18108bb diff --git a/src/evaluate.cpp b/src/evaluate.cpp index d20c7b70..c66938d6 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -50,9 +50,14 @@ namespace Eval { std::string eval_file = std::string(Options["EvalFile"]); if (useNNUE && eval_file_loaded != eval_file) { - std::cerr << "Use of NNUE evaluation, but the file " << eval_file << " was not loaded successfully. " - << "These network evaluation parameters must be available, compatible with this version of the code. " - << "The UCI option EvalFile might need to specify the full path, including the directory/folder name, to the file." << std::endl; + UCI::OptionsMap defaults; + UCI::init(defaults); + + sync_cout << "info string ERROR: NNUE evaluation used, but the network file " << eval_file << " was not loaded successfully." << sync_endl; + sync_cout << "info string ERROR: The UCI option EvalFile might need to specify the full path, including the directory/folder name, to the file." << sync_endl; + sync_cout << "info string ERROR: The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/"+std::string(defaults["EvalFile"]) << sync_endl; + sync_cout << "info string ERROR: If the UCI option Use NNUE is set to true, network evaluation parameters compatible with the program must be available." << sync_endl; + sync_cout << "info string ERROR: The engine will be terminated now." << sync_endl; std::exit(EXIT_FAILURE); } @@ -110,7 +115,8 @@ namespace { constexpr Value LazyThreshold1 = Value(1400); constexpr Value LazyThreshold2 = Value(1300); constexpr Value SpaceThreshold = Value(12222); - constexpr Value NNUEThreshold = Value(500); + constexpr Value NNUEThreshold1 = Value(550); + constexpr Value NNUEThreshold2 = Value(150); // KingAttackWeights[PieceType] contains king attack weights by piece type constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 }; @@ -345,7 +351,8 @@ namespace { { // Bonus if the piece is on an outpost square or can reach one // Reduced bonus for knights (BadOutpost) if few relevant targets - bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them); + bb = OutpostRanks & (attackedBy[Us][PAWN] | shift(pos.pieces(PAWN))) + & ~pe->pawn_attacks_span(Them); Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN); if ( Pt == KNIGHT @@ -922,9 +929,6 @@ make_v: // Side to move point of view v = (pos.side_to_move() == WHITE ? v : -v) + Tempo; - // Damp down the evaluation linearly when shuffling - v = v * (100 - pos.rule50_count()) / 100; - return v; } @@ -936,15 +940,21 @@ make_v: Value Eval::evaluate(const Position& pos) { - if (Eval::useNNUE) - { - Value balance = pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK); - balance += 200 * (pos.count(WHITE) - pos.count(BLACK)); - // Take NNUE eval only on balanced positions - if (abs(balance) < NNUEThreshold) - return NNUE::evaluate(pos) + Tempo; - } - return Evaluation(pos).value(); + bool classical = !Eval::useNNUE + || abs(eg_value(pos.psq_score())) * 16 > NNUEThreshold1 * (16 + pos.rule50_count()); + Value v = classical ? Evaluation(pos).value() + : NNUE::evaluate(pos) * 5 / 4 + Tempo; + + if (classical && Eval::useNNUE && abs(v) * 16 < NNUEThreshold2 * (16 + pos.rule50_count())) + v = NNUE::evaluate(pos) * 5 / 4 + Tempo; + + // Damp down the evaluation linearly when shuffling + v = v * (100 - pos.rule50_count()) / 100; + + // Guarantee evalution outside of TB range + v = Utility::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); + + return v; } /// trace() is like evaluate(), but instead of returning a value, it returns @@ -962,42 +972,47 @@ std::string Eval::trace(const Position& pos) { Value v; + std::memset(scores, 0, sizeof(scores)); + + pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt + + v = Evaluation(pos).value(); + + ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2) + << " Term | White | Black | Total \n" + << " | MG EG | MG EG | MG EG \n" + << " ------------+-------------+-------------+------------\n" + << " Material | " << Term(MATERIAL) + << " Imbalance | " << Term(IMBALANCE) + << " Pawns | " << Term(PAWN) + << " Knights | " << Term(KNIGHT) + << " Bishops | " << Term(BISHOP) + << " Rooks | " << Term(ROOK) + << " Queens | " << Term(QUEEN) + << " Mobility | " << Term(MOBILITY) + << " King safety | " << Term(KING) + << " Threats | " << Term(THREAT) + << " Passed | " << Term(PASSED) + << " Space | " << Term(SPACE) + << " Winnable | " << Term(WINNABLE) + << " ------------+-------------+-------------+------------\n" + << " Total | " << Term(TOTAL); + + v = pos.side_to_move() == WHITE ? v : -v; + + ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n"; + if (Eval::useNNUE) { v = NNUE::evaluate(pos); - } - else - { - std::memset(scores, 0, sizeof(scores)); - - pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt - - v = Evaluation(pos).value(); - - ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2) - << " Term | White | Black | Total \n" - << " | MG EG | MG EG | MG EG \n" - << " ------------+-------------+-------------+------------\n" - << " Material | " << Term(MATERIAL) - << " Imbalance | " << Term(IMBALANCE) - << " Pawns | " << Term(PAWN) - << " Knights | " << Term(KNIGHT) - << " Bishops | " << Term(BISHOP) - << " Rooks | " << Term(ROOK) - << " Queens | " << Term(QUEEN) - << " Mobility | " << Term(MOBILITY) - << " King safety | " << Term(KING) - << " Threats | " << Term(THREAT) - << " Passed | " << Term(PASSED) - << " Space | " << Term(SPACE) - << " Winnable | " << Term(WINNABLE) - << " ------------+-------------+-------------+------------\n" - << " Total | " << Term(TOTAL); + v = pos.side_to_move() == WHITE ? v : -v; + ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n"; } + v = evaluate(pos); v = pos.side_to_move() == WHITE ? v : -v; + ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n"; - ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n"; return ss.str(); }