X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fevaluate.cpp;h=40c43d230434a910e9451b926d4f5fba5ae39ca3;hb=07bd8adcbce41f076c36f4b65c7f9a786de0b02d;hp=6d5a8a0ce158ad5ab0b55b04bef349b9024832b7;hpb=1cdc0f78bd937637128ad10f5168cdb80390f6fb;p=stockfish diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 6d5a8a0c..40c43d23 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -36,7 +36,7 @@ #include "timeman.h" #include "uci.h" #include "incbin/incbin.h" - +#include "nnue/evaluate_nnue.h" // Macro to embed the default efficiently updatable neural network (NNUE) file // data in the engine binary (using incbin.h, by Dale Weiler). @@ -82,8 +82,6 @@ namespace Eval { eval_file = EvalFileDefaultName; #if defined(DEFAULT_NNUE_DIRECTORY) - #define stringify2(x) #x - #define stringify(x) stringify2(x) vector dirs = { "" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) }; #else vector dirs = { "" , "" , CommandLine::binaryDirectory }; @@ -95,7 +93,7 @@ namespace Eval { if (directory != "") { ifstream stream(directory + eval_file, ios::binary); - if (load_eval(eval_file, stream)) + if (NNUE::load_eval(eval_file, stream)) currentEvalFileName = eval_file; } @@ -111,7 +109,7 @@ namespace Eval { (void) gEmbeddedNNUEEnd; // Silence warning on unused variable istream stream(&buffer); - if (load_eval(eval_file, stream)) + if (NNUE::load_eval(eval_file, stream)) currentEvalFileName = eval_file; } } @@ -193,8 +191,8 @@ using namespace Trace; namespace { // Threshold for lazy and space evaluation - constexpr Value LazyThreshold1 = Value(3631); - constexpr Value LazyThreshold2 = Value(2084); + constexpr Value LazyThreshold1 = Value(3622); + constexpr Value LazyThreshold2 = Value(1962); constexpr Value SpaceThreshold = Value(11551); // KingAttackWeights[PieceType] contains king attack weights by piece type @@ -1048,22 +1046,24 @@ make_v: /// evaluate() is the evaluator for the outer world. It returns a static /// evaluation of the position from the point of view of the side to move. -Value Eval::evaluate(const Position& pos, int* complexity) { +Value Eval::evaluate(const Position& pos) { + + assert(!pos.checkers()); Value v; Value psq = pos.psq_eg_stm(); // We use the much less accurate but faster Classical eval when the NNUE // option is set to false. Otherwise we use the NNUE eval unless the - // PSQ advantage is decisive and several pieces remain. (~3 Elo) - bool useClassical = !useNNUE || (pos.count() > 7 && abs(psq) > 1781); + // PSQ advantage is decisive. (~4 Elo at STC, 1 Elo at LTC) + bool useClassical = !useNNUE || abs(psq) > 2048; if (useClassical) v = Evaluation(pos).value(); else { int nnueComplexity; - int scale = 1076 + 96 * pos.non_pawn_material() / 5120; + int npm = pos.non_pawn_material() / 64; Color stm = pos.side_to_move(); Value optimism = pos.this_thread()->optimism[stm]; @@ -1071,17 +1071,10 @@ Value Eval::evaluate(const Position& pos, int* complexity) { Value nnue = NNUE::evaluate(pos, true, &nnueComplexity); // Blend nnue complexity with (semi)classical complexity - nnueComplexity = ( 406 * nnueComplexity - + 424 * abs(psq - nnue) - + int(optimism) * int(psq - nnue) - ) / 1024; + nnueComplexity = 25 * (nnueComplexity + abs(psq - nnue)) / 64; - // Return hybrid NNUE complexity to caller - if (complexity) - *complexity = nnueComplexity; - - optimism = optimism * (272 + nnueComplexity) / 256; - v = (nnue * scale + optimism * (scale - 748)) / 1024; + optimism += optimism * nnueComplexity / 256; + v = (nnue * (945 + npm) + optimism * (174 + npm)) / 1024; } // Damp down the evaluation linearly when shuffling @@ -1090,10 +1083,6 @@ Value Eval::evaluate(const Position& pos, int* complexity) { // Guarantee evaluation does not hit the tablebase range v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); - // When not using NNUE, return classical complexity to caller - if (complexity && useClassical) - *complexity = abs(v - psq); - return v; }