diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 58319cb5..5d42d554 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -904,10 +904,11 @@ make_v: /// evaluation of the position from the point of view of the side to move. Value Eval::evaluate(const Position& pos) { + if (Eval::useNNUE) - return NNUE::evaluate(pos); + return NNUE::evaluate(pos); else - return Evaluation(pos).value(); + return Evaluation(pos).value(); } /// trace() is like evaluate(), but instead of returning a value, it returns @@ -927,36 +928,35 @@ std::string Eval::trace(const Position& pos) { if (Eval::useNNUE) { - v = NNUE::evaluate(pos); + v = NNUE::evaluate(pos); } else { - std::memset(scores, 0, sizeof(scores)); + std::memset(scores, 0, sizeof(scores)); - pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt + 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 = 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; diff --git a/src/position.cpp b/src/position.cpp index 16ca225f..00d63507 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -221,12 +221,12 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th if (Eval::useNNUE) { - // Kings get a fixed ID, other pieces get ID in order of placement - piece_id = - (idx == W_KING) ? PIECE_ID_WKING : - (idx == B_KING) ? PIECE_ID_BKING : - next_piece_id++; - evalList.put_piece(piece_id, sq, pc); + // Kings get a fixed ID, other pieces get ID in order of placement + piece_id = + (idx == W_KING) ? PIECE_ID_WKING : + (idx == B_KING) ? PIECE_ID_BKING : + next_piece_id++; + evalList.put_piece(piece_id, sq, pc); } ++sq; @@ -789,9 +789,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { remove_piece(capsq); if (type_of(m) == ENPASSANT) - { board[capsq] = NO_PIECE; - } // Update material hash key and prefetch access to materialTable k ^= Zobrist::psq[captured][capsq]; @@ -1005,28 +1003,30 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ if (Eval::useNNUE) { - PieceId dp0, dp1; - auto& dp = st->dirtyPiece; - dp.dirty_num = 2; // 2 pieces moved + PieceId dp0, dp1; + auto& dp = st->dirtyPiece; + dp.dirty_num = 2; // 2 pieces moved - if (Do) { - dp0 = piece_id_on(from); - dp1 = piece_id_on(rfrom); - dp.pieceId[0] = dp0; - dp.old_piece[0] = evalList.piece_with_id(dp0); - evalList.put_piece(dp0, to, make_piece(us, KING)); - dp.new_piece[0] = evalList.piece_with_id(dp0); - dp.pieceId[1] = dp1; - dp.old_piece[1] = evalList.piece_with_id(dp1); - evalList.put_piece(dp1, rto, make_piece(us, ROOK)); - dp.new_piece[1] = evalList.piece_with_id(dp1); - } - else { - dp0 = piece_id_on(to); - dp1 = piece_id_on(rto); - evalList.put_piece(dp0, from, make_piece(us, KING)); - evalList.put_piece(dp1, rfrom, make_piece(us, ROOK)); - } + if (Do) + { + dp0 = piece_id_on(from); + dp1 = piece_id_on(rfrom); + dp.pieceId[0] = dp0; + dp.old_piece[0] = evalList.piece_with_id(dp0); + evalList.put_piece(dp0, to, make_piece(us, KING)); + dp.new_piece[0] = evalList.piece_with_id(dp0); + dp.pieceId[1] = dp1; + dp.old_piece[1] = evalList.piece_with_id(dp1); + evalList.put_piece(dp1, rto, make_piece(us, ROOK)); + dp.new_piece[1] = evalList.piece_with_id(dp1); + } + else + { + dp0 = piece_id_on(to); + dp1 = piece_id_on(rto); + evalList.put_piece(dp0, from, make_piece(us, KING)); + evalList.put_piece(dp1, rfrom, make_piece(us, ROOK)); + } } // Remove both pieces first since squares could overlap in Chess960 @@ -1048,11 +1048,11 @@ void Position::do_null_move(StateInfo& newSt) { if (Eval::useNNUE) { - std::memcpy(&newSt, st, sizeof(StateInfo)); - st->accumulator.computed_score = false; + std::memcpy(&newSt, st, sizeof(StateInfo)); + st->accumulator.computed_score = false; } else - std::memcpy(&newSt, st, offsetof(StateInfo, accumulator)); + std::memcpy(&newSt, st, offsetof(StateInfo, accumulator)); newSt.previous = st; st = &newSt; @@ -1395,19 +1395,3 @@ bool Position::pos_is_ok() const { return true; } - -StateInfo* Position::state() const { - return st; -} - -const EvalList* Position::eval_list() const { - return &evalList; -} - -PieceId Position::piece_id_on(Square sq) const -{ - assert(piece_on(sq) != NO_PIECE); - PieceId pid = evalList.piece_id_list[sq]; - assert(is_ok(pid)); - return pid; -} diff --git a/src/position.h b/src/position.h index 39f614d6..7708c653 100644 --- a/src/position.h +++ b/src/position.h @@ -443,4 +443,25 @@ inline void Position::do_move(Move m, StateInfo& newSt) { do_move(m, newSt, gives_check(m)); } +inline StateInfo* Position::state() const { + + return st; +} + +inline const EvalList* Position::eval_list() const { + + return &evalList; +} + +inline PieceId Position::piece_id_on(Square sq) const +{ + + assert(piece_on(sq) != NO_PIECE); + + PieceId pid = evalList.piece_id_list[sq]; + assert(is_ok(pid)); + + return pid; +} + #endif // #ifndef POSITION_H_INCLUDED diff --git a/src/types.h b/src/types.h index 988911f6..8a342756 100644 --- a/src/types.h +++ b/src/types.h @@ -213,6 +213,7 @@ enum PieceId { }; inline PieceId operator++(PieceId& d, int) { + PieceId x = d; d = PieceId(int(d) + 1); return x; @@ -272,8 +273,7 @@ enum Rank : int { }; // unique number for each piece type on each square -enum PieceSquare : uint32_t -{ +enum PieceSquare : uint32_t { PS_NONE = 0, PS_W_PAWN = 1, PS_B_PAWN = 1 * SQUARE_NB + 1, @@ -291,8 +291,7 @@ enum PieceSquare : uint32_t PS_END2 = 12 * SQUARE_NB + 1 }; -struct ExtPieceSquare -{ +struct ExtPieceSquare { PieceSquare from[COLOR_NB]; }; @@ -303,63 +302,63 @@ constexpr bool is_ok(PieceId pid); constexpr Square rotate180(Square sq); // Structure holding which tracked piece (PieceId) is where (PieceSquare) -class EvalList -{ +class EvalList { + public: - // Max. number of pieces without kings is 30 but must be a multiple of 4 in AVX2 - static const int MAX_LENGTH = 32; + // Max. number of pieces without kings is 30 but must be a multiple of 4 in AVX2 + static const int MAX_LENGTH = 32; - // Array that holds the piece id for the pieces on the board - PieceId piece_id_list[SQUARE_NB]; + // Array that holds the piece id for the pieces on the board + PieceId piece_id_list[SQUARE_NB]; - // List of pieces, separate from White and Black POV - PieceSquare* piece_list_fw() const { return const_cast(pieceListFw); } - PieceSquare* piece_list_fb() const { return const_cast(pieceListFb); } + // List of pieces, separate from White and Black POV + PieceSquare* piece_list_fw() const { return const_cast(pieceListFw); } + PieceSquare* piece_list_fb() const { return const_cast(pieceListFb); } - // Place the piece pc with piece_id on the square sq on the board - void put_piece(PieceId piece_id, Square sq, Piece pc) - { - assert(is_ok(piece_id)); - if (pc != NO_PIECE) - { + // Place the piece pc with piece_id on the square sq on the board + void put_piece(PieceId piece_id, Square sq, Piece pc) + { + assert(is_ok(piece_id)); + if (pc != NO_PIECE) + { pieceListFw[piece_id] = PieceSquare(kpp_board_index[pc].from[WHITE] + sq); pieceListFb[piece_id] = PieceSquare(kpp_board_index[pc].from[BLACK] + rotate180(sq)); piece_id_list[sq] = piece_id; - } - else - { + } + else + { pieceListFw[piece_id] = PS_NONE; pieceListFb[piece_id] = PS_NONE; piece_id_list[sq] = piece_id; - } - } + } + } - // Convert the specified piece_id piece to ExtPieceSquare type and return it - ExtPieceSquare piece_with_id(PieceId piece_id) const - { - ExtPieceSquare eps; - eps.from[WHITE] = pieceListFw[piece_id]; - eps.from[BLACK] = pieceListFb[piece_id]; - return eps; - } + // Convert the specified piece_id piece to ExtPieceSquare type and return it + ExtPieceSquare piece_with_id(PieceId piece_id) const + { + ExtPieceSquare eps; + eps.from[WHITE] = pieceListFw[piece_id]; + eps.from[BLACK] = pieceListFb[piece_id]; + return eps; + } private: - PieceSquare pieceListFw[MAX_LENGTH]; - PieceSquare pieceListFb[MAX_LENGTH]; + PieceSquare pieceListFw[MAX_LENGTH]; + PieceSquare pieceListFb[MAX_LENGTH]; }; // For differential evaluation of pieces that changed since last turn -struct DirtyPiece -{ - // Number of changed pieces - int dirty_num; +struct DirtyPiece { - // The ids of changed pieces, max. 2 pieces can change in one move - PieceId pieceId[2]; + // Number of changed pieces + int dirty_num; - // What changed from the piece with that piece number - ExtPieceSquare old_piece[2]; - ExtPieceSquare new_piece[2]; + // The ids of changed pieces, max. 2 pieces can change in one move + PieceId pieceId[2]; + + // What changed from the piece with that piece number + ExtPieceSquare old_piece[2]; + ExtPieceSquare new_piece[2]; }; /// Score enum stores a middlegame and an endgame value in a single integer (enum). @@ -499,7 +498,7 @@ inline Color color_of(Piece pc) { return Color(pc >> 3); } -constexpr bool is_ok(PieceId pid) { +constexpr bool is_ok(PieceId pid) { return pid < PIECE_ID_NONE; } diff --git a/src/uci.cpp b/src/uci.cpp index 19299b19..5a8e0cb7 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -250,7 +250,7 @@ void UCI::loop(int argc, char* argv[]) { pos.set(StartFEN, false, &states->back(), Threads.main()); if (argc > 1) - init_nnue(Options["EvalFile"]); + init_nnue(Options["EvalFile"]); for (int i = 1; i < argc; ++i) cmd += std::string(argv[i]) + " "; diff --git a/src/ucioption.cpp b/src/ucioption.cpp index a163c49d..9029a3a1 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -46,15 +46,16 @@ void on_tb_path(const Option& o) { Tablebases::init(o); } void on_use_nnue(const Option& o) { if (o) - std::cout << "info string NNUE eval used" << std::endl; + std::cout << "info string NNUE eval used" << std::endl; else - std::cout << "info string classic eval used" << std::endl; + std::cout << "info string classic eval used" << std::endl; Eval::useNNUE = o; init_nnue(Options["EvalFile"]); } void on_eval_file(const Option& o) { + load_eval_finished = false; init_nnue(o); }