Merged the training data generator and the machine learning logic from YaneuraOu.

This commit is contained in:
Hisayori Noda
2019-06-18 08:48:05 +09:00
parent 87445881ec
commit bcd6985871
37 changed files with 6306 additions and 139 deletions
+60 -62
View File
@@ -37,12 +37,10 @@ using namespace std;
extern vector<string> setup_bench(const Position&, istream&);
// FEN string of the initial position, normal chess
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
namespace {
// FEN string of the initial position, normal chess
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
// position() is called when engine receives the "position" UCI command.
// The function sets up the position described in the given FEN string ("fen")
// or the starting position ("startpos") and then makes the moves given in the
@@ -179,74 +177,74 @@ namespace {
// check sumを計算したとき、それを保存しておいてあとで次回以降、整合性のチェックを行なう。
uint64_t eval_sum;
} // namespace
// is_ready_cmd()を外部から呼び出せるようにしておく。(benchコマンドなどから呼び出したいため)
// 局面は初期化されないので注意。
void is_ready(Position& pos, istringstream& is, StateListPtr& states)
{
// is_ready_cmd()を外部から呼び出せるようにしておく。(benchコマンドなどから呼び出したいため)
// 局面は初期化されないので注意。
void is_ready(bool skipCorruptCheck)
{
#if defined(EVAL_NNUE)
// "isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。(keep alive的な処理)
// USI2.0の仕様より。
// -"isready"のあとのtime out時間は、30秒程度とする。これを超えて、評価関数の初期化、hashテーブルの確保をしたい場合、
// 思考エンジン側から定期的に何らかのメッセージ(改行可)を送るべきである。
// -ShogiGUIではすでにそうなっているので、MyShogiもそれに追随する。
// -また、やねうら王のエンジン側は、"isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。
// "isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。(keep alive的な処理)
// USI2.0の仕様より。
// -"isready"のあとのtime out時間は、30秒程度とする。これを超えて、評価関数の初期化、hashテーブルの確保をしたい場合、
// 思考エンジン側から定期的に何らかのメッセージ(改行可)を送るべきである。
// -ShogiGUIではすでにそうなっているので、MyShogiもそれに追随する。
// -また、やねうら王のエンジン側は、"isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。
auto ended = false;
auto th = std::thread([&ended] {
int count = 0;
while (!ended)
auto ended = false;
auto th = std::thread([&ended] {
int count = 0;
while (!ended)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (++count >= 50 /* 5秒 */)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (++count >= 50 /* 5秒 */)
{
count = 0;
sync_cout << sync_endl; // 改行を送信する。
}
count = 0;
sync_cout << sync_endl; // 改行を送信する。
}
});
// 評価関数の読み込みなど時間のかかるであろう処理はこのタイミングで行なう。
// 起動時に時間のかかる処理をしてしまうと将棋所がタイムアウト判定をして、思考エンジンとしての認識をリタイアしてしまう。
if (!UCI::load_eval_finished)
{
// 評価関数の読み込み
Eval::load_eval();
// チェックサムの計算と保存(その後のメモリ破損のチェックのため)
eval_sum = Eval::calc_check_sum();
// ソフト名の表示
Eval::print_softname(eval_sum);
UCI::load_eval_finished = true;
}
else
{
// メモリが破壊されていないかを調べるためにチェックサムを毎回調べる。
// 時間が少しもったいない気もするが.. 0.1秒ぐらいのことなので良しとする。
if (eval_sum != Eval::calc_check_sum())
sync_cout << "Error! : EVAL memory is corrupted" << sync_endl;
}
});
// isreadyに対してはreadyokを返すまで次のコマンドが来ないことは約束されているので
// このタイミングで各種変数の初期化もしておく
// 評価関数の読み込みなど時間のかかるであろう処理はこのタイミングで行なう。
// 起動時に時間のかかる処理をしてしまうと将棋所がタイムアウト判定をして、思考エンジンとしての認識をリタイアしてしまう
if (!UCI::load_eval_finished)
{
// 評価関数の読み込み
Eval::load_eval();
TT.resize(Options["Hash"]);
Search::clear();
Time.availableNodes = 0;
// チェックサムの計算と保存(その後のメモリ破損のチェックのため)
eval_sum = Eval::calc_check_sum();
Threads.stop = false;
// ソフト名の表示
Eval::print_softname(eval_sum);
// keep aliveを送信するために生成したスレッドを終了させ、待機する。
ended = true;
th.join();
UCI::load_eval_finished = true;
}
else
{
// メモリが破壊されていないかを調べるためにチェックサムを毎回調べる。
// 時間が少しもったいない気もするが.. 0.1秒ぐらいのことなので良しとする。
if (!skipCorruptCheck && eval_sum != Eval::calc_check_sum())
sync_cout << "Error! : EVAL memory is corrupted" << sync_endl;
}
// isreadyに対してはreadyokを返すまで次のコマンドが来ないことは約束されているので
// このタイミングで各種変数の初期化もしておく。
TT.resize(Options["Hash"]);
Search::clear();
Time.availableNodes = 0;
Threads.stop = false;
// keep aliveを送信するために生成したスレッドを終了させ、待機する。
ended = true;
th.join();
#endif // defined(EVAL_NNUE)
sync_cout << "readyok" << sync_endl;
}
} // namespace
sync_cout << "readyok" << sync_endl;
}
/// UCI::loop() waits for a command from stdin, parses it and calls the appropriate
@@ -296,7 +294,7 @@ void UCI::loop(int argc, char* argv[]) {
else if (token == "go") go(pos, is, states);
else if (token == "position") position(pos, is, states);
else if (token == "ucinewgame") Search::clear();
else if (token == "isready") is_ready(pos, is, states);
else if (token == "isready") is_ready();
// Additional custom non-UCI commands, mainly for debugging
else if (token == "flip") pos.flip();