From 87445881ec2862f95b5c49ce637d3cfbe8ba16c1 Mon Sep 17 00:00:00 2001 From: Hisayori Noda Date: Sun, 16 Jun 2019 11:11:16 +0900 Subject: [PATCH] Added #ifdef statements to switch the legacy evaluation function and NNUE evaluation function. --- src/eval/nnue/evaluate_nnue.cpp | 4 +++ src/evaluate.cpp | 7 +++++- src/evaluate.h | 2 ++ src/position.cpp | 44 +++++++++++++++++++++++++++++++++ src/position.h | 8 ++++++ src/types.h | 2 ++ src/uci.cpp | 2 ++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/eval/nnue/evaluate_nnue.cpp b/src/eval/nnue/evaluate_nnue.cpp index 6009d888..15d9194b 100644 --- a/src/eval/nnue/evaluate_nnue.cpp +++ b/src/eval/nnue/evaluate_nnue.cpp @@ -1,5 +1,7 @@ // NNUE評価関数の計算に関するコード +#if defined(EVAL_NNUE) + #include #include @@ -316,3 +318,5 @@ void print_eval_stat(Position& /*pos*/) { } } // namespace Eval + +#endif // defined(EVAL_NNUE) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 9e85e2ae..29ea65dc 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -865,8 +865,11 @@ namespace { /// evaluation of the position from the point of view of the side to move. Value Eval::evaluate(const Position& pos) { - //return Evaluation(pos).value(); +#if defined(EVAL_NNUE) return Eval::NNUE::evaluate(pos); +#else + return Evaluation(pos).value(); +#endif // defined(EVAL_NNUE) } @@ -910,6 +913,7 @@ std::string Eval::trace(const Position& pos) { return ss.str(); } +#if defined(EVAL_NNUE) namespace Eval { ExtBonaPiece kpp_board_index[PIECE_NB] = { { BONA_PIECE_ZERO, BONA_PIECE_ZERO }, @@ -978,3 +982,4 @@ bool EvalList::is_valid(const Position& pos) return true; } } +#endif // defined(EVAL_NNUE) diff --git a/src/evaluate.h b/src/evaluate.h index e9e13e7d..1b114179 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -35,6 +35,7 @@ std::string trace(const Position& pos); Value evaluate(const Position& pos); +#if defined(EVAL_NNUE) // ]֐t@CǂݍށB // ́A"is_ready"R}h̉1xĂяoB2xĂяoƂ͑z肵ĂȂB // (AEvalDir(]֐tH_)ύXɂȂƁAisreadyēxĂǂ݂ȂB) @@ -206,6 +207,7 @@ struct DirtyPiece int dirty_num; }; +#endif // defined(EVAL_NNUE) } #endif // #ifndef EVALUATE_H_INCLUDED diff --git a/src/position.cpp b/src/position.cpp index 43f986f9..23ce5168 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -243,6 +243,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE); st = si; +#if defined(EVAL_NNUE) // evalListclearBmemsetŃ[NAƂɃNAĂ邪cB evalList.clear(); @@ -256,6 +257,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th PIECE_NUMBER_ROOK, PIECE_NUMBER_QUEEN }; +#endif // defined(EVAL_NNUE) ss >> std::noskipws; @@ -273,11 +275,13 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th auto pc = Piece(idx); put_piece(pc, sq); +#if defined(EVAL_NNUE) PieceNumber piece_no = (idx == W_KING) ? PIECE_NUMBER_WKING : // (idx == B_KING) ? PIECE_NUMBER_BKING : // piece_no_count[type_of(Piece(idx))]++; // ȊO evalList.put_piece(piece_no, sq, pc); // sq̏pc̋zu +#endif // defined(EVAL_NNUE) ++sq; } @@ -341,7 +345,9 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th set_state(st); assert(pos_is_ok()); +#if defined(EVAL_NNUE) assert(evalList.is_valid(*this)); +#endif // defined(EVAL_NNUE) return *this; } @@ -762,8 +768,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { ++st->rule50; ++st->pliesFromNull; +#if defined(EVAL_NNUE) st->accumulator.computed_accumulation = false; st->accumulator.computed_score = false; +#endif // defined(EVAL_NNUE) Color us = sideToMove; Color them = ~us; @@ -776,8 +784,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us)); assert(type_of(captured) != KING); +#if defined(EVAL_NNUE) auto& dp = st->dirtyPiece; dp.dirty_num = 1; +#endif // defined(EVAL_NNUE) if (type_of(m) == CASTLING) { @@ -795,7 +805,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { { Square capsq = to; +#if defined(EVAL_NNUE) PieceNumber piece_no1; +#endif // defined(EVAL_NNUE) // If the captured piece is a pawn, update pawn hash key, otherwise // update non-pawn material. @@ -811,12 +823,16 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { assert(piece_on(to) == NO_PIECE); assert(piece_on(capsq) == make_piece(them, PAWN)); +#if defined(EVAL_NNUE) piece_no1 = piece_no_of(capsq); +#endif // defined(EVAL_NNUE) board[capsq] = NO_PIECE; // Not done by remove_piece() } else { +#if defined(EVAL_NNUE) piece_no1 = piece_no_of(capsq); +#endif // defined(EVAL_NNUE) } st->pawnKey ^= Zobrist::psq[captured][capsq]; @@ -824,7 +840,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { else { st->nonPawnMaterial[them] -= PieceValue[MG][captured]; +#if defined(EVAL_NNUE) piece_no1 = piece_no_of(capsq); +#endif // defined(EVAL_NNUE) } // Update board and piece lists @@ -838,6 +856,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // Reset rule 50 counter st->rule50 = 0; +#if defined(EVAL_NNUE) dp.dirty_num = 2; // 2 dp.pieceNo[1] = piece_no1; @@ -850,6 +869,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // will not be overritten to pc if the move type is enpassant. evalList.piece_no_list_board[capsq] = PIECE_NUMBER_NB; dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1); +#endif // defined(EVAL_NNUE) } // Update hash key @@ -872,14 +892,18 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { // Move the piece. The tricky Chess960 castling is handled earlier if (type_of(m) != CASTLING) { +#if defined(EVAL_NNUE) PieceNumber piece_no0 = piece_no_of(from); +#endif // defined(EVAL_NNUE) move_piece(pc, from, to); +#if defined(EVAL_NNUE) dp.pieceNo[0] = piece_no0; dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); evalList.put_piece(piece_no0, to, pc); dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0); +#endif // defined(EVAL_NNUE) } // If the moving piece is a pawn do some special extra work @@ -903,11 +927,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { remove_piece(pc, to); put_piece(promotion, to); +#if defined(EVAL_NNUE) PieceNumber piece_no0 = piece_no_of(to); dp.pieceNo[0] = piece_no0; dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); evalList.put_piece(piece_no0, to, promotion); dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0); +#endif // defined(EVAL_NNUE) // Update hash keys k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to]; @@ -960,7 +986,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { } assert(pos_is_ok()); +#if defined(EVAL_NNUE) assert(evalList.is_valid(*this)); +#endif // defined(EVAL_NNUE) } @@ -991,8 +1019,10 @@ void Position::undo_move(Move m) { pc = make_piece(us, PAWN); put_piece(pc, to); +#if defined(EVAL_NNUE) PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0]; evalList.put_piece(piece_no0, to, pc); +#endif // defined(EVAL_NNUE) } if (type_of(m) == CASTLING) @@ -1005,8 +1035,10 @@ void Position::undo_move(Move m) { move_piece(pc, to, from); // Put the piece back at the source square +#if defined(EVAL_NNUE) PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0]; evalList.put_piece(piece_no0, from, pc); +#endif // defined(EVAL_NNUE) if (st->capturedPiece) { @@ -1025,10 +1057,12 @@ void Position::undo_move(Move m) { put_piece(st->capturedPiece, capsq); // Restore the captured piece +#if defined(EVAL_NNUE) PieceNumber piece_no1 = st->dirtyPiece.pieceNo[1]; assert(evalList.bona_piece(piece_no1).fw == Eval::BONA_PIECE_ZERO); assert(evalList.bona_piece(piece_no1).fb == Eval::BONA_PIECE_ZERO); evalList.put_piece(piece_no1, capsq, st->capturedPiece); +#endif // defined(EVAL_NNUE) } } @@ -1037,7 +1071,9 @@ void Position::undo_move(Move m) { --gamePly; assert(pos_is_ok()); +#if defined(EVAL_NNUE) assert(evalList.is_valid(*this)); +#endif // defined(EVAL_NNUE) } @@ -1045,6 +1081,7 @@ void Position::undo_move(Move m) { /// is a bit tricky in Chess960 where from/to squares can overlap. template void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) { +#if defined(EVAL_NNUE) auto& dp = st->dirtyPiece; // vẐ߂ɈړStateInfoɋL^ĂB dp.dirty_num = 2; // 2 @@ -1056,16 +1093,19 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ piece_no0 = piece_no_of(from); piece_no1 = piece_no_of(to); } +#endif // defined(EVAL_NNUE) bool kingSide = to > from; rfrom = to; // Castling is encoded as "king captures friendly rook" rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1); to = relative_square(us, kingSide ? SQ_G1 : SQ_C1); +#if defined(EVAL_NNUE) if (!Do) { piece_no0 = piece_no_of(to); piece_no1 = piece_no_of(rto); } +#endif // defined(EVAL_NNUE) // Remove both pieces first since squares could overlap in Chess960 remove_piece(make_piece(us, KING), Do ? from : to); @@ -1074,6 +1114,7 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ put_piece(make_piece(us, KING), Do ? to : from); put_piece(make_piece(us, ROOK), Do ? rto : rfrom); +#if defined(EVAL_NNUE) if (Do) { dp.pieceNo[0] = piece_no0; dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); @@ -1089,6 +1130,7 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ evalList.put_piece(piece_no0, from, make_piece(us, KING)); evalList.put_piece(piece_no1, rfrom, make_piece(us, ROOK)); } +#endif // defined(EVAL_NNUE) } @@ -1426,6 +1468,7 @@ bool Position::pos_is_ok() const { return true; } +#if defined(EVAL_NNUE) PieceNumber Position::piece_no_of(Square sq) const { if (piece_on(sq) == NO_PIECE) { @@ -1436,3 +1479,4 @@ PieceNumber Position::piece_no_of(Square sq) const assert(is_ok(n)); return n; } +#endif // defined(EVAL_NNUE) diff --git a/src/position.h b/src/position.h index 8111c663..c6e4f9c9 100644 --- a/src/position.h +++ b/src/position.h @@ -59,10 +59,12 @@ struct StateInfo { Bitboard pinners[COLOR_NB]; Bitboard checkSquares[PIECE_TYPE_NB]; +#if defined(EVAL_NNUE) Eval::NNUE::Accumulator accumulator; // ]l̍vZ̊Ǘp Eval::DirtyPiece dirtyPiece; +#endif // defined(EVAL_NNUE) }; /// A list to keep track of the position states along the setup moves (from the @@ -174,6 +176,7 @@ public: bool pos_is_ok() const; void flip(); +#if defined(EVAL_NNUE) // --- StateInfo // ݂̋ǖʂɑΉStateInfoԂB @@ -182,6 +185,7 @@ public: // ]֐Ŏg߂́Aǂ̋ԍ̋ǂɂ邩Ȃǂ̏B const Eval::EvalList* eval_list() const { return &evalList; } +#endif // defined(EVAL_NNUE) private: // Initialization helpers (used while setting up a position) @@ -196,8 +200,10 @@ private: template void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto); +#if defined(EVAL_NNUE) // Տsq̏ɂPieceNumberԂB PieceNumber piece_no_of(Square sq) const; +#endif // defined(EVAL_NNUE) // Data members Piece board[SQUARE_NB]; @@ -216,8 +222,10 @@ private: StateInfo* st; bool chess960; +#if defined(EVAL_NNUE) // ]֐ŗp̃Xg Eval::EvalList evalList; +#endif // defined(EVAL_NNUE) }; namespace PSQT { diff --git a/src/types.h b/src/types.h index ef6cbb40..5270ccd6 100644 --- a/src/types.h +++ b/src/types.h @@ -464,6 +464,7 @@ constexpr bool is_ok(Move m) { return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE } +#if defined(EVAL_NNUE) // -------------------- //  // -------------------- @@ -493,5 +494,6 @@ inline PieceNumber& operator--(PieceNumber& d) { return d = PieceNumber(int8_t(d // PieceNumber̐̌BassertpB constexpr bool is_ok(PieceNumber pn) { return pn < PIECE_NUMBER_NB; } +#endif // defined(EVAL_NNUE) #endif // #ifndef TYPES_H_INCLUDED diff --git a/src/uci.cpp b/src/uci.cpp index bee5acd7..b47398ad 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -184,6 +184,7 @@ namespace { // ǖʂ͏Ȃ̂ŒӁB void is_ready(Position& pos, istringstream& is, StateListPtr& states) { +#if defined(EVAL_NNUE) // "isready"󂯎ƁA"readyok"Ԃ܂5bƂɉs𑗂悤ɏCB(keep aliveIȏ) // USI2.0̎dlB // -"isready"̂Ƃtime outԂ́A30bxƂB𒴂āA]֐̏Ahashe[ůmۂꍇA @@ -241,6 +242,7 @@ namespace { // keep alive𑗐M邽߂ɐXbhIAҋ@B ended = true; th.join(); +#endif // defined(EVAL_NNUE) sync_cout << "readyok" << sync_endl; }