More comment translation

including 11 files in /src
This commit is contained in:
FireFather
2020-06-29 17:31:35 +02:00
committed by nodchip
parent f5cc77bc7c
commit 8f31d74cf6
11 changed files with 293 additions and 293 deletions
+76 -75
View File
@@ -1938,60 +1938,61 @@ void Tablebases::rank_root_moves(Position& pos, Search::RootMoves& rootMoves) {
}
}
// --- 学習時に用いる、depth固定探索などの関数を外部に対して公開
// --- expose the functions such as fixed depth search used for learning to the outside
#if defined (EVAL_LEARN)
namespace Learner
{
// 学習用に、1つのスレッドからsearch,qsearch()を呼び出せるようなスタブを用意する。
// いまにして思えば、AperyのようにSearcherを持ってスレッドごとに置換表などを用意するほうが
// 良かったかも知れない。
// For learning, prepare a stub that can call search,qsearch() from one thread.
// From now on, it is better to have a Searcher and prepare a substitution table for each thread like Apery.
// It might have been good.
// 学習のための初期化。
// Learner::search(),Learner::qsearch()から呼び出される。
// Initialization for learning.
// Called from Learner::search(),Learner::qsearch().
void init_for_search(Position& pos, Stack* ss)
{
// RootNodess->ply == 0がその条件。
// ゼロクリアするので、ss->ply == 0となるので大丈夫…。
// RootNode requires ss->ply == 0.
// Because it clears to zero, ss->ply == 0, so it's okay...
std::memset(ss - 7, 0, 10 * sizeof(Stack));
// Search::Limitsに関して
// このメンバー変数はglobalなので他のスレッドに影響を及ぼすので気をつけること。
// About Search::Limits
// Be careful because this member variable is global and affects other threads.
{
auto& limits = Search::Limits;
// 探索を"go infinite"コマンド相当にする。(time managementされると困るため)
// Make the search equivalent to the "go infinite" command. (Because it is troublesome if time management is done)
limits.infinite = true;
// PVを表示されると邪魔なので消しておく。
// Since PV is an obstacle when displayed, erase it.
limits.silent = true;
// これを用いると各スレッドのnodesを積算したものと比較されてしまう。ゆえに使用しない。
// If you use this, it will be compared with the accumulated nodes of each thread. Therefore, do not use it.
limits.nodes = 0;
// depthも、Learner::search()の引数として渡されたもので処理する。
// depth is also processed by the one passed as an argument of Learner::search().
limits.depth = 0;
// 引き分け付近の手数で引き分けの値が返るのを防ぐために大きな値にしておく。
// Set a large value to prevent the draw value from being returned due to the number of moves near the draw.
//limits.max_game_ply = 1 << 16;
// 入玉ルールも入れておかないと引き分けになって決着つきにくい。
// If you do not include the ball entry rule, it will be a draw and it will be difficult to settle.
//limits.enteringKingRule = EnteringKingRule::EKR_27_POINT;
}
// DrawValueの設定
// Set DrawValue
{
// スレッドごとに用意してないので
// 他のスレッドで上書きされかねない。仕方がないが。
// どうせそうなるなら、0にすべきだと思う。
// Because it is not prepared for each thread
// May be overwritten by another thread. There is no help for it.
// If that happens, I think it should be 0.
//drawValueTable[REPETITION_DRAW][BLACK] = VALUE_ZERO;
//drawValueTable[REPETITION_DRAW][WHITE] = VALUE_ZERO;
}
// this_threadに関して。
// Regarding this_thread.
{
auto th = pos.this_thread();
@@ -1999,10 +2000,10 @@ namespace Learner
th->selDepth = 0;
th->rootDepth = 0;
// 探索ノード数のゼロ初期化
// Zero initialization of the number of search nodes
th->nodes = 0;
// history類を全部クリアする。この初期化は少し時間がかかるし、探索の精度はむしろ下がるので善悪はよくわからない。
// Clear all history types. This initialization takes a little time, and the accuracy of the search is rather low, so the good and bad are not well understood.
// th->clear();
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
@@ -2023,57 +2024,57 @@ namespace Learner
for (int i = 7; i > 0; i--)
(ss - i)->continuationHistory = &th->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel
// rootMovesの設定
// set rootMoves
auto& rootMoves = th->rootMoves;
rootMoves.clear();
for (auto m : MoveList<LEGAL>(pos))
for (auto m: MoveList<LEGAL>(pos))
rootMoves.push_back(Search::RootMove(m));
assert(!rootMoves.empty());
//#if defined(USE_GLOBAL_OPTIONS)
// 探索スレッドごとの置換表の世代を管理しているはずなので、
// 新規の探索であるから、このスレッドに対する置換表の世代を増やす。
// Since the generation of the substitution table for each search thread should be managed,
// Increase the generation of the substitution table for this thread because it is a new search.
//TT.new_search(th->thread_id());
// ↑ここでnew_searchを呼び出すと1手前の探索結果が使えなくて損ということはあるのでは…。
// ここでこれはやらずに、呼び出し側で1局ごとにTT.new_search(th->thread_id())をやるべきでは…。
// ↑ If you call new_search here, it may be a loss because you can't use the previous search result.
// Do not do this here, but caller should do TT.new_search(th->thread_id()) for each station ...
// → 同一の終局図に至るのを回避したいので、教師生成時には置換表は全スレ共通で使うようにする。
// →Because we want to avoid reaching the same final diagram, use the substitution table commonly for all threads when generating teachers.
//#endif
}
}
// 読み筋と評価値のペア。Learner::search(),Learner::qsearch()が返す。
// A pair of reader and evaluation value. Returned by Learner::search(),Learner::qsearch().
typedef std::pair<Value, std::vector<Move> > ValueAndPV;
// 静止探索。
// Stationary search.
//
// 前提条件) pos.set_this_thread(Threads[thread_id])で探索スレッドが設定されていること。
//  また、Threads.stopが来ると探索を中断してしまうので、そのときのPVは正しくない。
//  search()から戻ったあと、Threads.stop == trueなら、その探索結果を用いてはならない。
//  あと、呼び出し前は、Threads.stop == falseの状態で呼び出さないと、探索を中断して返ってしまうので注意。
// Precondition) Search thread is set by pos.set_this_thread(Threads[thread_id]).
// Also, when Threads.stop arrives, the search is interrupted, so the PV at that time is not correct.
// After returning from search(), if Threads.stop == true, do not use the search result.
// Also, note that before calling, if you do not call it with Threads.stop == false, the search will be interrupted and it will return.
//
// 詰まされている場合は、PV配列にMOVE_RESIGNが返る。
// If it is clogged, MOVE_RESIGN is returned in the PV array.
//
// 引数でalpha,betaを指定できるようにしていたが、これがその窓で探索したときの結果を
// 置換表に書き込むので、その窓に対して枝刈りが出来るような値が書き込まれて学習のときに
// 悪い影響があるので、窓の範囲を指定できるようにするのをやめることにした。
//Although it was possible to specify alpha and beta with arguments, this will show the result when searching in that window
// Because it writes to the substitution table, the value that can be pruned is written to that window when learning
// As it has a bad effect, I decided to stop allowing the window range to be specified.
ValueAndPV qsearch(Position& pos)
{
Stack stack[MAX_PLY + 10], * ss = stack + 7;
Move pv[MAX_PLY + 1];
init_for_search(pos, ss);
ss->pv = pv; // とりあえずダミーでどこかバッファがないといけない。
ss->pv = pv; // For the time being, it must be a dummy and somewhere with a buffer.
if (pos.is_draw(0)) {
// Return draw value if draw.
return { VALUE_DRAW, {} };
}
// 詰まされているのか
// Is it stuck?
if (MoveList<LEGAL>(pos).size() == 0)
{
// Return the mated value if checkmated.
@@ -2082,7 +2083,7 @@ namespace Learner
auto bestValue = ::qsearch<PV>(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, 0);
// 得られたPVを返す。
// Returns the PV obtained.
std::vector<Move> pvs;
for (Move* p = &ss->pv[0]; is_ok(*p); ++p)
pvs.push_back(*p);
@@ -2090,21 +2091,21 @@ namespace Learner
return ValueAndPV(bestValue, pvs);
}
// 通常探索。深さdepth(整数で指定)。
// 3手読み時のスコアが欲しいなら、
// auto v = search(pos,3);
// のようにすべし。
// v.firstに評価値、v.secondにPVが得られる。
// multi pvが有効のときは、pos.this_thread()->rootMoves[N].pvにそのPV(読み筋)の配列が得られる。
// multi pvの指定はこの関数の引数multiPVで行なう。(Options["MultiPV"]の値は無視される)
//
// rootでの宣言勝ち判定はしないので(扱いが面倒なので)、ここでは行わない。
// 呼び出し側で処理すること。
// Normal search. Depth depth (specified as an integer).
// 3 If you want a score for hand reading,
// auto v = search(pos,3);
// Do something like
// Evaluation value is obtained in v.first and PV is obtained in v.second.
// When multi pv is enabled, you can get the PV (reading line) array in pos.this_thread()->rootMoves[N].pv.
// Specify multi pv with the argument multiPV of this function. (The value of Options["MultiPV"] is ignored)
//
// 前提条件) pos.set_this_thread(Threads[thread_id])で探索スレッドが設定されていること。
//  また、Threads.stopが来ると探索を中断してしまうので、そのときのPVは正しくない。
//  search()から戻ったあと、Threads.stop == trueなら、その探索結果を用いてはならない。
//  あと、呼び出し前は、Threads.stop == falseの状態で呼び出さないと、探索を中断して返ってしまうので注意。
// Declaration win judgment is not done as root (because it is troublesome to handle), so it is not done here.
// Handle it by the caller.
//
// Precondition) Search thread is set by pos.set_this_thread(Threads[thread_id]).
// Also, when Threads.stop arrives, the search is interrupted, so the PV at that time is not correct.
// After returning from search(), if Threads.stop == true, do not use the search result.
// Also, note that before calling, if you do not call it with Threads.stop == false, the search will be interrupted and it will return.
ValueAndPV search(Position& pos, int depth_, size_t multiPV /* = 1 */, uint64_t nodesLimit /* = 0 */)
{
@@ -2122,9 +2123,9 @@ namespace Learner
init_for_search(pos, ss);
ss->pv = pv; // とりあえずダミーでどこかバッファがないといけない。
ss->pv = pv; // For the time being, it must be a dummy and somewhere with a buffer.
// this_threadに関連する変数の初期化
// Initialize the variables related to this_thread
auto th = pos.this_thread();
auto& rootDepth = th->rootDepth;
auto& pvIdx = th->pvIdx;
@@ -2133,13 +2134,13 @@ namespace Learner
auto& completedDepth = th->completedDepth;
auto& selDepth = th->selDepth;
// bestmoveとしてしこの局面の上位N個を探索する機能
//size_t multiPV = Options["MultiPV"];
// A function to search the top N of this stage as best move
//size_t multiPV = Options["MultiPV"];
// この局面での指し手の数を上回ってはいけない
// Do not exceed the number of moves in this situation
multiPV = std::min(multiPV, rootMoves.size());
// ノード制限にMultiPVの値を掛けておかないと、depth固定、MultiPVありにしたときに1つの候補手に同じnodeだけ思考したことにならない。
// If you do not multiply the node limit by the value of MultiPV, you will not be thinking about the same node for one candidate hand when you fix the depth and have MultiPV.
nodesLimit *= multiPV;
Value alpha = -VALUE_INFINITE;
@@ -2148,9 +2149,9 @@ namespace Learner
Value bestValue = -VALUE_INFINITE;
while ((rootDepth += 1) <= depth
// node制限を超えた場合もこのループを抜ける
// 探索ノード数は、この関数の引数で渡されている。
&& !(nodesLimit /*node制限あり*/ && th->nodes.load(std::memory_order_relaxed) >= nodesLimit)
// exit this loop even if the node limit is exceeded
// The number of search nodes is passed in the argument of this function.
&& !(nodesLimit /* limited nodes */ && th->nodes.load(std::memory_order_relaxed) >= nodesLimit)
)
{
for (RootMove& rm : rootMoves)
@@ -2170,10 +2171,10 @@ namespace Learner
break;
}
// それぞれのdepthとPV lineに対するUSI infoで出力するselDepth
// selDepth output with USI info for each depth and PV line
selDepth = 0;
// depth 5以上においてはaspiration searchに切り替える。
// Switch to aspiration search for depth 5 and above.
if (rootDepth >= 5 * 1)
{
delta = Value(20);
@@ -2194,8 +2195,8 @@ namespace Learner
stable_sort(rootMoves.begin() + pvIdx, rootMoves.end());
//my_stable_sort(pos.this_thread()->thread_id(),&rootMoves[0] + pvIdx, rootMoves.size() - pvIdx);
// fail low/highに対してaspiration windowを広げる。
// ただし、引数で指定されていた値になっていたら、もうfail low/high扱いとしてbreakする。
// Expand aspiration window for fail low/high.
// However, if it is the value specified by the argument, it will be treated as fail low/high and break.
if (bestValue <= alpha)
{
beta = (alpha + beta) / 2;
@@ -2217,7 +2218,7 @@ namespace Learner
delta += delta / 4 + 5;
assert(-VALUE_INFINITE <= alpha && beta <= VALUE_INFINITE);
// 暴走チェック
// runaway check
//assert(th->nodes.load(std::memory_order_relaxed) <= 1000000 );
}
@@ -2229,9 +2230,9 @@ namespace Learner
completedDepth = rootDepth;
}
// このPV、途中でNULL_MOVEの可能性があるかも知れないので排除するためにis_ok()を通す。
// → PVなのでNULL_MOVEはしないことになっているはずだし、
// MOVE_WINも突っ込まれていることはない。(いまのところ)
// Pass PV_is(ok) to eliminate this PV, there may be NULL_MOVE in the middle.
// → PV should not be NULL_MOVE because it is PV
// MOVE_WIN has never been thrust. (For now)
for (Move move : rootMoves[0].pv)
{
if (!is_ok(move))
@@ -2241,7 +2242,7 @@ namespace Learner
//sync_cout << rootDepth << sync_endl;
// multiPV時を考慮して、rootMoves[0]のscoreをbestValueとして返す。
// Considering multiPV, the score of rootMoves[0] is returned as bestValue.
bestValue = rootMoves[0].score;
return ValueAndPV(bestValue, pvs);