やねうら王の更新履歴2022まで - mizar/YaneuraOu GitHub Wiki

2022年


■ 2022/06/01


- clusterのroot_split、クラスを分離して、このコードは実際には使わないことにする。(勝率が悪かったため)
- BookTools::feed_position_string()のバグ修正した影響でmakebook2021のコンパイルが通らなかったの修正。


■ 2022/05/31

- BookTools::feed_position_string()のバグ修正。
  - vectorやめてdequeに変更。
- ↑のUnitTest追加。
- OptimisticOption追加。
  - clusterコマンドにroot_splitなどを追加。
  - istreamstreamやめてLineScannerで解析するように変更。
- LineScanner::get_text()でスペースが複数ある場合に""が返るバグ修正。


■ 2022/05/30

- yo_cluster 楽観合議、"stop"を送るようにした。
	- 持時間が秒数固定でなくともうまく動くようになった。


■ 2022/05/29

- yo_cluster 楽観合議 動くようなった。
  - EngineNegotiatorでlog出力フラグが条件が逆になっていた。

// single ponder VS 楽観合議
  → 計測中。

// ponderhit修正後
engine1 = nnue/YaneuraOuNNUE_V720_avx2.exe , eval = .
engine2 = cluster/YaneuraOu-nnue-cluster.exe , eval = .
T1,b1000,705 - 80 - 2215(24.14% R-198.87[-211.23,-186.52]) winrate black , white = 50.89% , 49.11%


- yo_cluster 楽観合議
  - parse_bestmove()追加
  - isready前のエンジンからのメッセージをGUIに送信する時には、engine idを付与する。
  - LinerScanner::get_rest()追加。
  - parse_usi_info()追加。
  - OptimisticConsultationStrategy実装。(楽観合議)
    - デバッグ中
  - SinglePonderEngineStrategyでponderhitした時に持時間渡せていなかったの修正。

// 通常ponder
engine1 = nnue/YaneuraOuNNUE_V720_avx2.exe , eval = .
engine2 = cluster/YaneuraOu-nnue-cluster.exe , eval = .
T1,b1000,700 - 70 - 2230(23.89% R-201.28[-213.66,-188.91]) winrate black , white = 51.98% , 48.02%
  ↑修正前


■ 2022/05/28

- "cluster ignore_setoption"追加。

// GUI側から送られてきた"setoption"を無視する。
// エンジン設定を個別に"engine_options.txt"を用いて設定する場合、
// GUI側から全部のエンジンにbroadcastされると迷惑なのでこのオプションを用意した。


■ 2022/05/28


- yo_cluster "cluster mode ponder"実装。

- EngineMode::SEND_INFO_BEFORE_GAME_0/ANY → 廃止。
  - EngineMode::SEND_INFO_BEFORE_GAMEに統一。

- SingleEngineStrategyのテスト
  単体エンジン vs yo_cluster(SingleEngineStrategy)
  T1,b1000,1117 - 69 - 1154(49.19% R-5.66[-17.65,6.33]) winrate black , white = 51.12% , 48.88%
  - うまく動いている。

- SinglePonderEngineStrategy実装。
  - "cluster mode ponder"
  単体エンジン vs yo_cluster(SinglePonderEngineStrategy)
  T1,b1000,748 - 81 - 2161(25.71% R-184.3[-196.42,-172.18]) winrate black , white = 49.98% , 50.02%


- yo_cluster
  - bestmoveはClusterObserverの責任でGUIに返す。
  - EngineNegotiator::get_bestmove() → pull_bestmove()にrename。
  - ClusterStrategy追加。
    - SingleEngineStrategy実装。
  - yo_cluster.cpp → ClusterObserver.h/.cpp に分ける。
  - cluster filelog → cluster logに変更。


■ 2022/05/23


- Androidでyo_clusterのビルドが通らなかったの修正。


- Android: yo_cluster #247
  - Mizarさんのプルリク
  - yo_clusterの追加ソースファイル指定


- yo_cluster大改修
  - ClusterCommon.h/cpp追加。
    - file log書き出し時のmutex忘れてたの修正。
  - ProcessNegotiator
    - DebugMessageCommon()で標準出力に出力していなかったの修正。
  - EngineNegotiator.h/cpp追加。
  - fixed_size_vector削除。

	// ---------------------------------------
	//          コンテナ
	// ---------------------------------------

	// 固定長のvector
	// 
	// 通常のvectorはコンテナにcopy,moveが可能なことを要求するのだが、それをされたくない。
	// かと言って、shared_ptrで配列確保するのも嫌。vectorのように使えて欲しい。
	// 次善策としては、vector<shared_ptr<T>>なんだけど、ことあるごとに .get() とか -> とか書きたくない。
	template <typename T>
	class fixed_size_vector
	{
	public:

		size_t size() const       { return s; }
		void   resize(size_t n)   { release(); ptr = new T[n]; s = n; }
		void   release()          { if (ptr) { delete[] ptr; ptr=nullptr; } }

		T& operator[](size_t n)   { return ptr[n]; }

		typedef T* iterator;
		typedef const T* const_iterator;

		iterator       begin()       { return ptr    ; }
		iterator       end  ()       { return ptr + s; }
		const_iterator begin() const { return ptr    ; }
		const_iterator end  () const { return ptr + s; }

		~fixed_size_vector()    { release(); }

	private:
		T*     ptr = nullptr;
		size_t s   = 0;
	};


- remove gensfen, enable evallearn on 
YANEURAOU_ENGINE_MATERIAL #246
	- Mizarさんのプルリク。
	- ビルド周りの構成(VisualStudio向けのプロジェクト設定を除く)からgensfen周りを削除
	- YANEURAOU_ENGINE_MATERIAL では代わりに evallearn ビルドを有効化


■ 2022/05/21


- 大会に参加する時の設定追加。


- ビルド関連の修正 #244
  - Mizarさんのプルリク
  linux: llvm.sh all コマンドによる openmp 関連パッケージを含めた clang 関連パッケージの一括インストール
  linux: clang++-15 ビルドターゲットの有効化
  リンク切れしていたURLの修正 https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md → https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md



■ 2022/05/20


- ビルド関連修正 #243
  - Mizarさんのプルリク
  Android.mk: ソース追加
  ふかうら王: CUDA 11.7, cuDNN 8.4.0, TensorRT 8.2.5.1
  cuDNN 8.4.0 に併せて、 zlibwapi.dll への言及を追加
  cuDNN, TensorRT, zlib を C:\ProgramData\YaneuraOu\ 以下に配置する想定に変更
  msys2: base-devel 追加
  base-develに含まれる、ビルドに必要な make コマンドが不足していたため。


■ 2022/05/19


- やねうら王質問箱のリンク追加。


- やねうら王遊び方、やねうら王Wikiに移動。


- やねうら大定跡の資料、やねうら王Wikiに移動。


- ふかうら王の資料、やねうら王Wikiに移動。


- 探索部の計測資料、やねうら王Wikiに移動。


■ 2022/05/18


- やねうら王のGitHubのトップページにやねうら王プロジェクト関連のリンクを追加。


- 過去のサブプロジェクトのテキストをやねうら王Wikiに移動。


- ふかうら王、MKL版を削除。
  - CPU版と性能何も変わらなかった。


- やねうら王Wikiのリンク修正。ごめん。もっかい。
- やねうら王Wikiのリンク修正。その2。
- やねうら王Wikiのリンク修正。


■ 2022/05/14


- yo_cluster for Linux
  - fprintf()でコンパイル時に警告出ていたの修正。
  - makefileにProcessNegotiator.cpp追加するの忘れていたの修正。
  - ProcessNegotiator.cpp、#elseを#elifと書いていたの修正。
  - Linux用のProcessNegotiator、EngineNegotiatorと書いていたの修正。
  - Linux用のProcessNegotiatorがコンパイルエラーになっていたの諸々修正。
  - これでWindows版と同等に動くようになった。


- docs/にあったコンテンツ、やねうら王Wikiに移動させた。
- readme.mdでやねうら王Wikiのほうの記事を紹介するようにした。


■ 2022/05/13


- ProcessNegotiator、Linux対応。
  - yo_cluster、これでLinuxでも動くかも。
  - まだコンパイル&動作テストはやってない。
  - 動作テストは明日やる。


■ 2022/05/12


- ProcessNegotiatorをIProcessNegotiator,ProcessNegotiatorImplに分離。

- EngineNegotiator、copy, move可能に。
	// これcopyされてはかなわんので、copyとmoveを禁止しておく。
	EngineNegotiator(const EngineNegotiator& other)         = delete;
	EngineNegotiator&& operator = (const EngineNegotiator&) = delete;

- fixed_size_vector廃止。

#if 0
	// 固定長のvector
	// 
	// 通常のvectorはコンテナにcopy,moveが可能なことを要求するのだが、それをされたくない。
	// かと言って、shared_ptrで配列確保するのも嫌。vectorのように使えて欲しい。
	// 次善策としては、vector<shared_ptr<T>>なんだけど、ことあるごとに .get() とか -> とか書きたくない。
	template <typename T>
	class fixed_size_vector
	{
	public:

		size_t size() const       { return s; }
		void   resize(size_t n)   { release(); ptr = new T[n]; s = n; }
		void   release()          { if (ptr) { delete[] ptr; ptr=nullptr; } }

		T& operator[](size_t n)   { return ptr[n]; }

		typedef T* iterator;
		typedef const T* const_iterator;

		iterator       begin()       { return ptr    ; }
		iterator       end  ()       { return ptr + s; }
		const_iterator begin() const { return ptr    ; }
		const_iterator end  () const { return ptr + s; }

		~fixed_size_vector()    { release(); }

	private:
		T*     ptr = nullptr;
		size_t s   = 0;
	};
#endif


	// ムーブコンストラクタ
	ProcessNegotiator(ProcessNegotiator&& o) noexcept : ptr(std::move(o.ptr)){}

	// ムーブ代入演算子
	ProcessNegotiator& operator=(ProcessNegotiator&& o) noexcept { ptr = std::move(o.ptr); }



- V7.62
  - ふかうら王、Softmax_Temperatureをdlshogiに合わせて千分率から百分率で指定するように変更。
  - ふかうら王、Eval_Coefのデフォルト値を756→285に変更。
  - Mizarさん、プルリク、なんやかや。


- ふかうら王、Softmax_Temperatureをdlshogiに合わせて千分率から百分率で指定するように変更。


- ふかうら王、Eval_Coefのデフォルト値を756→285に変更。
  - cf. dlshogiの評価値のスケール調整 : https://tadaoyamaoka.hatenablog.com/entry/2021/10/19/230601


-DORT_NO_EXCEPTIONS #242
  - Mizarさんのプルリク
  Makefile経由のonnxruntime使用時、-DORT_NO_EXCEPTIONS コンパイルオプションを指定して例外を抑止する
  cf. https://onnxruntime.ai/docs/api/c/struct_ort_1_1_exception.html
  -lonnxruntimeリンカオプションの指定をMakefileに移動  


■ 2022/05/11


- DeepLearning for Ubuntu Linux ビルドテストの修正・追加 (#241)
  - Mizarさんのプルリク
* - actions:make-deep-ubuntu: add cuda path, add ORT_CPU
* - build.sh: YANEURAOU_ENGINE_DEEP_ORT_CPU


- ORT model filename #240
  - Mizarさんのプルリク
  - Linux環境でモデルファイル名を渡すための修正。


- types.hでコンパイラの警告が出るようになっていたの修正。


- Makefile修正 #239
  - Mizarさんのプルリク


- V7.61
  - ふかうら王のメモリリークの問題が解決したので。


- FastAlloc削除
	#define USE_FAST_ALLOC

// 高速なmemory allocator
// これをdefineすると、FastAllocが使えるようになる。
// 
// これは、ふかうら王で、
//   1. メモリを高速にnew/deleteする必要があった。
//   2. USI_Hashで事前に確保したmemory poolから割り当てたかった。
// ので開発した。
//#define USE_FAST_ALLOC

#if defined(USE_FAST_ALLOC)
	// memory allocatorに確保する場合。
	FAST_ALLOC.memory_alloc(size_t(Options["USI_Hash"]));
#endif

#if defined(USE_FAST_ALLOC)
		// --- use custom memory allocator

		static void* operator new     (std::size_t size) /* throw(std::bad_alloc) */ { return FAST_ALLOC.alloc(size); }
	    static void* operator new[]   (std::size_t size) /* throw(std::bad_alloc) */ { return FAST_ALLOC.alloc(size); }
	    static void  operator delete  (void* p         ) /* throw(              ) */ {        FAST_ALLOC.free (p   ); }
	    static void  operator delete[](void* p         ) /* throw(              ) */ {        FAST_ALLOC.free (p   ); }
#endif

	bool use_fast_alloc =
#if defined(USE_FAST_ALLOC)
		true;
#else
		false;
#endif

	config += o2("USE_FAST_ALLOC"           , use_fast_alloc     );

  #if defined(USE_FAST_ALLOC)
			<< " hashfull " << FAST_ALLOC.hashfull();
			// → 専用のメモリアロケーターからメモリを割り当てるようにしたので正確に残り空き容量を出力できる。
#else



- ふかうら王、局面が進んだ時のメモリ開放ロジック、間違えていた(気がする)。
  - dlshogiと同じように書いたらメモリちゃんと開放されるようになった。
  - FAST_ALLOC使わないことにする。(従来通りに戻す)


- DirectML 1.8.2 #238
  - Mizarさんからのプルリク。


- V7.60
- fast_alloc.cppがClangでコンパイルエラーになっていたの修正。


- エンジンオプションのデフォルト値を現代に合わせて変更。
  - ConsiderationMode → デフォルトでオンに変更。
  - USI_Hash → デフォルトで 1024に変更。


- 入力特徴量の転送量削減 #237
  - Mizarさんのプルリク
  TadaoYamaoka/DeepLearningShogi@1053b87
  https://tadaoyamaoka.hatenablog.com/entry/2022/01/10/212539


- WebAssemblyビルドの調整 #236
  - Mizarさんのプルリク

  Node.js 18.1.0 で実行できない問題の回避。
  lib,src: implement WebAssembly Web API nodejs/node#42701
  Fails with Node.js v18.1.0 antelle/argon2-browser#81
  Node.js implemented WebAssembly.instantiateStreaming in v18.1.0 emscripten-core/emscripten#16913
  emcc output does not work in Node.js 18. emscripten-core/emscripten#16915
  Fixes #16913: Don't use fetch() in Node.js environment emscripten-core/emscripten#16917
  PROXY_TO_PTHREAD ビルドオプションの無効化。(標準出力への出力順が狂う場合があったため)


- clusterのコード、engineフォルダに移動。(整理中)


- FastAlloc, LargeMemory対応。
- FastAlloc、メモリ使用率が90%超えてたらクリアしたいのだが、
  Garbageが別スレッドで回っているので簡単ではないな…。
// V7.55


■ 2022/05/10


- FastAlloc開発
  - 超高速なメモリアロケーターを書いた。
  - ふかうら王ではTTを使わないように書き換える。
  - ふかうら王では、Node,ChildNodeのallocateにFastAllocを用いるように書き換える。
  - ふかうら王ではUSI_Hashを用いるように変更した。
    - hashfullが1000になるとメモリに空きがないので思考できなくなる。
    - goした時点で900ぐらいなら、そこでお掃除したほうが良いのでは…。(考え中)
    - 15分切れ負けでponderありならUSI_Hash、8GBぐらいでギリ足りる感じ。(16GBぐらいあったほうが安心)

  ===================================================
   FastAllocは、たぬきさんにレビューしていただきました。
        この場をお借りして、感謝申し上げます。
  ===================================================

■ 2022/05/09


- ふかうら王
  - winに代入する時にWinTypeにcastしてから代入するように。
  - ChildNodeのmove constructorでwinのmove忘れていたの修正。
  - Node::select_interval、いったん削除。また実験してから導入を考える。

- 廃止したコード
		// SelectMaxUcbChild()の高速化のために前回選択した子ノードのindexを記憶しておく。
		// 調べる間隔は、select_intervalにする。
		u16 last_best_child;
		u16 select_interval;

    SelectMaxUcbChild()

		// 訪問回数が多いなら、そう簡単に子ノードは変化しないのでしばらくは前回と同じbest_childを返す。
		if (current->select_interval)
		{
			--current->select_interval;
			return current->last_best_child;
		}

		// 訪問回数に応じてチェックの回数を減らす。root付近でのnodeのlock時間を減らす考え。
		// A100×8とかでnpsが少し改善するかも…。(GeForce RTX 3090×1だとやらないほうがマシレベル…)
		current->select_interval = (u16)std::min(current->move_count / 16384, (NodeCountType)7);

	// 勝ちが確定しているため、親からは、この子ノードを選択する
	current->last_best_child = i;


- HASH_KEY_BITSが128,256の時にkeyコマンドを使ったら全桁表示されるように。


- makeでのお勧めビルドの説明修正。


■ 2022/05/07


- USI拡張コマンド.txt、書き直す。
- 解説.txt、書き直す。
  - GitHub wikiを使う。


- yo_cluster 専用のフォルダ作成。
  部品ごとに分解して、再利用しやすくする。
  - configコマンドでUSE_YO_CLUSTERがdefineされているかを出力するようにした。
  - makefileでYO_CLUSTER=ONとなっていれば"cluster"コマンドが有効になるようにした。


- YANEURAOU_ENGINE_DEEPが定義されている時、置換表を確保しないようにした。


- HASH_KEY_BITが128,256の時にKPPT/KPP_KKPTのビルドが通らなかった問題を修正。


- position::is_repetition()高速化

	// ここまでに通過した局面のhashkeyを格納する用。
	// hashkeyの下位N bitをindexとして、通過するごとに trajectories[index]++ のようにインクリメントする。
	int8_t trajectories[64 * 1024];

  	std::memset(trajectories, 0, sizeof(trajectories));

    // → これアイデア自体は悪くないのだが、このメモリクリア、position::set()でも
    行わないといけなくて、局面送られてくるごとにこのクリアするの、わりと嫌な意味はあるな…。
    // この実装、見送ろう…。


- やねうら王V7.50リリース
  - WCSC32(第32回世界コンピュータ将棋選手権)出場バージョン。(大会成績 3位)
  - V7.00から+R70以上強くなった
  - (HashKeyが)128-bit Edition誕生
    - mateバグが(天文学的確率でしか)起きない
  - 思考エンジンのcluster化ができるようになった。
    - 現在実験中。V8.00で本格稼働。


- int64_max , int_64_min導入。
- INT_MAX , INT_MINが残っていたので修正。



■ 2022/05/06


- size_max , size_min などを導入。
  constexpr int int_max     = (std::numeric_limits<int>::max)();
  constexpr int int_min     = (std::numeric_limits<int>::min)();
  constexpr size_t size_max = (std::numeric_limits<size_t>::max)();
  constexpr size_t size_min = (std::numeric_limits<size_t>::min)();

- yo_cluster、YO_CLUSTERがdefineされていない時は無効化する。
- yo_cluster、ponderのアルゴリズム変更。


■ 2022/05/05


1T VS cluster-h 1T*2 , node = 100000 (1T)
T1,b1000,425 - 25 - 380(52.8% R19.44[-0.72,39.6]) winrate black , white = 52.67% , 47.33%
// CPU負荷率が20%ぐらいしかない。何かやらかしたのか?

1T VS cluster-h 1T*2 , node = 100000 (4T)
T1,b1000,691 - 60 - 819(45.76% R-29.52[-44.28,-14.77]) winrate black , white = 52.65% , 47.35%

1T VS cluster-h 1T*2 , node = 10000 (1T)
T1,b1000,780 - 56 - 954(44.98% R-34.98[-48.77,-21.19]) winrate black , white = 50.58% , 49.42%

1T VS cluster-h 1T*2 , node = 1000000 (1T)
T1,b1000,91 - 7 - 22(80.53% R246.65[179.19,314.11]) winrate black , white = 51.33% , 48.67%
// おかしい。次の指し手に被っているのか?
// bestmoveを返したあとにgo ponderさせられているのか?


- yo_cluster
  - cluster nodes 10000→100000(2T)で比較。
    // cluster-h

// startup.txt
setoption name BookFile value no_book
setoption name Threads value 2
cluster node 100000
setoption name BookFile value no_book
setoption name Threads value 1

1T VS cluster-h 1T*3


MultiPVで探索する時に、台数増えるとMultiPVの数が増えて、それで
ponder局面の選出の精度が落ちてレーティングが悪化している可能性があるのか…。

あー、clusterのponder選出のnode数を増やすと、thread 1だとその間、思考スレッドが一つ遊ぶから、
CPU負荷が変わってきて、勝率に影響を及ぼすのか…。こりゃ計測が大変だわ。

しかし1T VS 2T で 3T×20でCPU消費30%はおかしいのでは…。なんなんだろこれ。
// わからん。あとで調査しよう。


- yo_cluster
// クラスター部分、もっとモジュール化して、さまざまな編成ができるようにできると理想なのだが。


- yo_cluster
  - ponderhit_countの処理除去
  // ↓に戻す。
			// 偶数局面であるなら、空きエンジンに現在の局面を思考させてみる。
			// → その方がponderが当たった時の利得が高いと考えられる。
			if (same_color)
			{
				for(size_t i = 0 ; i < engines.size() ; ++i)
				{
					// 現在ponderしているか、何もしていないエンジンは空きエンジンとみなす。
					auto& engine = engines[i];

					if (  (engine.is_state_go_ponder() && engines[i].get_searching_sfen() != search_sfen)
						|| engine.is_idle_in_game()
						)
						engine.send(Message(USI_Message::GO_PONDER, string() , search_sfen));
				}
				return ;
			}

- 最小値・最大値、書いてみたものの、うざいので削除。
- int_max , size_maxみたいなのだけtype.hに追加。

// windows.hをincludeしていると minとmaxがマクロ定義されているのでstd::max()と書けなくて、(std::max)()のように書くと回避できる。
// 以下は、そのテクニックを利用したもの。

constexpr size_t u8_max  = (std::numeric_limits<u8 >::max)();
constexpr size_t u8_min  = (std::numeric_limits<u8 >::min)();
constexpr size_t s8_max  = (std::numeric_limits<s8 >::max)();
constexpr size_t s8_min  = (std::numeric_limits<s8 >::min)();
constexpr size_t u16_max = (std::numeric_limits<u16>::max)();
constexpr size_t u16_min = (std::numeric_limits<u16>::min)();
constexpr size_t s16_max = (std::numeric_limits<s16>::max)();
constexpr size_t s16_min = (std::numeric_limits<s16>::min)();
constexpr size_t u32_max = (std::numeric_limits<u32>::max)();
constexpr size_t u32_min = (std::numeric_limits<u32>::min)();
constexpr size_t s32_max = (std::numeric_limits<s32>::max)();
constexpr size_t s32_min = (std::numeric_limits<s32>::min)();
constexpr size_t u64_max = (std::numeric_limits<u64>::max)();
constexpr size_t u64_min = (std::numeric_limits<u64>::min)();
constexpr size_t s64_max = (std::numeric_limits<s64>::max)();
constexpr size_t s64_min = (std::numeric_limits<s64>::min)();


- yo_cluster
  - ponderhit_countの初期化方法、変えた。
  - ponderhit_countのカウントが間違っていたの修正。


- yo_cluster
  - ENGINE_PER_POSITIONの導入。
  // ENGINE_PER_POSITION台ずつに同じ局面を割り当てる

> 台数多いと下位のほうはponderが外れるから、外れたところを調べていたengineが
> 次に参加しても…みたいなところはあるのか…。
  → これ、対策してみた。
    3回思考してからしか予想ponderに参加できないようにした。

    1T VS yo-cluster-e 1T*4
    T1,b1000,79 - 11 - 80(49.69% R-2.19[-47.38,43.01]) winrate black , white = 58.49% , 41.51%

    → あかん。これ、デバッグしきれん。いったんrevertするわ。


- yo_cluster
  - 比較のため、偶数ponderでは現在の局面を思考させてみる。

			// 空きエンジンに現在の局面を思考させてみる。
			if (same_color)
			{
				for(size_t i = 0 ; i < engines.size() ; ++i)
				{
					// 現在ponderしているか、何もしていないエンジンは空きエンジンとみなす。
					auto& engine = engines[i];

					if (   engine.is_state_go_ponder()
						&& engines[i].get_searching_sfen() != search_sfen)

						engine.send(Message(USI_Message::GO_PONDER, string() , search_sfen));
					else if ( engine.is_idle_in_game())
						engine.send(Message(USI_Message::GO_PONDER, string() , search_sfen));
				}
				return ;
			}
    // cluster-f

    → これが効果あるなら、main engineと同じ局面をN回思考したあとに選出されたponder局面を思考する、みたいな
      そういうタイプの探索が必要かも知れん。


台数多いと下位のほうはponderが外れるから、外れたところを調べていたengineが
次に参加しても…みたいなところはあるのか…。


1T VS yo-cluster-e 1T*2
T1,b1000,713 - 69 - 818(46.57% R-23.87[-38.5,-9.23]) winrate black , white = 50.16% , 49.84%

1T VS yo-cluster-e 1T*3
T1,b1000,565 - 48 - 637(47.0% R-20.84[-37.34,-4.33]) winrate black , white = 51.33% , 48.67%

1T VS yo-cluster-e 1T*4
T1,b1000,130 - 13 - 157(45.3% R-32.78[-66.61,1.05]) winrate black , white = 48.08% , 51.92%

// なんか少しつよなった?


- yo_cluster
  - 比較のため、偶数ponderやめてみる。
    // cluster-e

			// 偶数局面のponderをやめてみる。(比較実験のため)
			if (same_color)
				return ;

台数が増えるほど悪くなる。
選出したponder局面が当たる確率は台数が増えるほど上がる。
つまりは、ponder当たった時に、直前に1つ前の局面について思考していないことが
ロスにつながっているのではないかと考えられる。

1T VS yo-cluster-d 1T*2
T1,b1000,403 - 26 - 351(53.45% R24.0[3.15,44.85]) winrate black , white = 53.45% , 46.55%

1T VS yo-cluster-d 1T*3
T1,b1000,307 - 19 - 244(55.72% R39.9[15.41,64.39]) winrate black , white = 53.18% , 46.82%

1T VS yo-cluster-d 1T*4
T1,b1000,189 - 16 - 165(53.39% R23.59[-6.81,54.0]) winrate black , white = 48.87% , 51.13%


■ 2022/05/04


- yo_clusterはUSE_YO_CLUSTERをdefineした時だけ有効にする。


- yo_cluster 2022/05/04
  - ponder中の局面(指し手)は必ずGUIに出力する その2

  例
    [0:P]7g7f(E100)

    [0:P]
      0 は、engine id // 0から 台数N - 1
      そのあと
       G = Go                 : 局面が送られてきたが、すべてのgo ponderしていた局面から外れたので、
                                前回goしていたエンジンのponderの指し手を思考してエンジンに、その局面が送られてきたので"go"を送信した。
       H = ponderHit          : 前回goしていたエンジンのponderの指し手をgo ponderで思考中にその局面が送られてきたので"go"を送信した。
	   P = Ponder             : 前回この局面を思考してたと思われるエンジンに"go ponder"を送信した。
	   C = Continue to ponder : Ponderの継続。いま"go ponder"で思考しているエンジンだったので、そのまま"go ponder"し続けてもらうことにした。
	   N = New ponder         : 新規局面を"go ponder"で思考してもらうことにした。("go ponder"で思考中であったならそれを停止させた上で)
    7g7f   : 指し手
    (E100) :
       E   = goしていたEngineがbestmove XX ponder YYで返してきたponderの指し手YYであるという意味
       100 = 訪問回数
  - MultiPVで2番目以降の指し手のrootMoves[i].valueがおかしい件。
    - おかしくはなかった。
    - previous_scoreを見ないといけないのだった。



- yo_cluster
  - MultiPVで2番目以降の指し手のrootMoves[i].valueがおかしい件。
    - おかしくはなかった。
    - previous_scoreを見ないといけないのだった。


- 更新履歴、ここまで分。
- "startup.txt"に関する説明追加。


- go ponderでbookにhitしてponderhitのパラメーターありが送られてくると落ちるの修正。

setoption name BookFile value user_book1.db
isready
usinewgame

position startpos moves 2g2f 8c8d
go ponder
ponderhit btime 60000 wtime 60000 binc 1000 winc 1000

// V723



- yo_cluster
  - ponder中の局面(指し手)は必ずGUIに出力する その2

  例
    [0:P]7g7f(E100)

    [0:P]
      0 は、engine id // 0から 台数N - 1
      そのあと
       G = Go                 : 局面が送られてきたが、すべてのgo ponderしていた局面から外れたので、
                                前回goしていたエンジンのponderの指し手を思考してエンジンに、その局面が送られてきたので"go"を送信した。
       H = ponderHit          : 前回goしていたエンジンのponderの指し手をgo ponderで思考中にその局面が送られてきたので"go"を送信した。
	   P = Ponder             : 前回この局面を思考してたと思われるエンジンに"go ponder"を送信した。
	   C = Continue to ponder : Ponderの継続。いま"go ponder"で思考しているエンジンだったので、そのまま"go ponder"し続けてもらうことにした。
	   N = New ponder         : 新規局面を"go ponder"で思考してもらうことにした。("go ponder"で思考中であったならそれを停止させた上で)
    7g7f   : 指し手
    (E100) :
       E   = goしていたEngineがbestmove XX ponder YYで返してきたponderの指し手YYであるという意味
       100 = 訪問回数



- yo_cluster
  - エンジン側、2手前からの継続局面であることを前提にaspiration searchを行うので、
    継続局面以外を渡すとそこでロスがでるのかもな…。


- 定跡のprobe()でhitしたときにMultiPV配列がその通りに並んでいない問題があるな…。
  まあいいか…。いまこんなややこしいところいじってエンバグしてはかなわん。


■ 2022/05/03


- 起動時にstartup.txtのコマンドを実行するようにした。


- yo_cluster
  - go_count、マイナスにしない。
  - goコマンド、ゲーム外で受理しないように。
  - ignore_bestmove、readyokの時点でリセットするように。
  - 将棋所の連続対局、一局ごとにquitがきてプロセスが終了するのかと思っていたらそうではないようなので
   gameover時の処理が正常に行われないと以降の対局すべてに影響するようだ。
  // cluster-d
  // この修正バージョンで対局をやりなおしてみる。


  // 1T*2とか勝率悪化したが、これはcluster-cが、エンジンが死ぬことがあって、実質的に単体エンジンに
  // なっていたから互角の勝率になっていただけなのかも…。

1T*1(=ponderあり,cluster-c) VS 1T*2 cluster-d
T1,b1000,1599 - 101 - 1300(55.16% R35.96[25.29,46.63]) winrate black , white = 52.19% , 47.81%

1T*1(=ponderあり,cluster-c) VS 1T*3 cluster-d
T1,b1000,1247 - 78 - 975(56.12% R42.74[30.53,54.96]) winrate black , white = 54.23% , 45.77%

1T*1(=ponderあり,cluster-c) VS 1T*4 cluster-d
T1,b1000,850 - 44 - 666(56.07% R42.38[27.6,57.16]) winrate black , white = 53.76% , 46.24%

定数ロスが生じているってことか。

しかし、台数増えた時にはponder当たる確率は増えるはずだから、
それなのに一定の効果しかないのおかしい気が。

ponder当たる確率が増えるが、そのPCに割り当てる行為がロスである確率は一定であるため、
ロスとしてはほぼ一定になるだとか?

// よくわからん。1手2秒でも計測してみる。

1T*1(=ponderあり,cluster-c) VS 1T*2 cluster-d
T1,b2000,1318 - 101 - 1251(51.3% R9.06[-2.21,20.34]) winrate black , white = 51.58% , 48.42%

1T*1(=ponderあり,cluster-c) VS 1T*3 cluster-d
T1,b2000,1150 - 61 - 859(57.24% R50.68[37.8,63.56]) winrate black , white = 51.82% , 48.18%

1T*1(=ponderあり,cluster-c) VS 1T*4 cluster-d
T1,b2000,701 - 61 - 558(55.68% R39.63[23.43,55.84]) winrate black , white = 53.22% , 46.78%


// 将棋所での対局
1T*4 cluster-c VS 1T
27-19-21
→ 対局回数少なくてわからん…。


// 対局コマンド
c:\python27\python engine_invoker6.py --engine1 cluster-c1/YaneuraOu-nnue-cluster-c.exe --eval1 . --engine2 cluster-d3/YaneuraOu-nnue-cluster-d.exe --eval2 . --hash1 128 --hash2 128 --time b1000 --loop 3000 --PARAMETERS_LOG_FILE_PATH result --cores 30 --cpu 2 --rand_book 1


- yo_cluster ponderのPC割当アルゴリズムの修正。

1)	// ponderの継続をすればいいなら、そうする。
2)	// 前回、この局面を探索していた(現在bestmoveを返したのか停止しているエンジンがあれば、それを用いる)
    → 2)を優先してみると?
    → これをcluster-cとする。

				// これやったほうが良いのか自信がない。比較すべき。
				// → やらないほうが良さそう。ponderのほうが価値がある。[2022/05/03]
#if 0
				// エンジンが指定してきたponderは、そのエンジンに思考させてあげるべき。
				// たとえ、その局面をジャストでponderしているエンジンがあったとしても。
				// (ここ、過去の思考時間等から統計的にこの局面について思考していた分量を算出して、
				// このエンジンのほうが優れているかを比較するとなお良し。)
				if (engine_ponder)
				{
					auto& engine     = engines[engine_ponder_engine_id];
					string engine_id = std::to_string(engine_ponder_engine_id);
					DebugMessageCommon("go engine's ponder [" + engine_id + "] : " + sfen);
					engine.send(Message(USI_Message::GO_PONDER, string() , sfen));

					summery += "[" + engine_id + "P]" + short_sfen2;
					goto Next;
				}
#endif


bestmoveを返して休憩中のエンジンだとしたら1手前の局面だしなぁ…。このケースは何なんだ?

engine1 = nnue/YaneuraOuNNUE_V720_avx2.exe , eval = .
engine2 = cluster-c/YaneuraOu-nnue-cluster-c.exe , eval = .
T1,b1000,116 - 15 - 339(25.49% R-186.3[-216.99,-155.6]) winrate black , white = 49.45% , 50.55%
// →たぶん、まだ単体エンジンを1T*2で超えてない。

engine1 = cluster-c1/YaneuraOu-nnue-cluster-c.exe , eval = .
engine2 = cluster-c2/YaneuraOu-nnue-cluster-c.exe , eval = .
T1,b1000,1514 - 87 - 1399(51.97% R13.72[3.13,24.32]) winrate black , white = 51.7% , 48.3%
// 単体エンジンを超えていない。

// cluster-c 1T VS cluster-c 1T*2

engine1 = cluster/YaneuraOu-nnue-cluster.exe , eval = .
engine2 = cluster-b/YaneuraOu-nnue-cluster-b.exe , eval = .
T1,b1000,683 - 51 - 626(52.18% R15.14[-0.67,30.94]) winrate black , white = 50.57% , 49.43%

engine1 = cluster-c1/YaneuraOu-nnue-cluster-c.exe , eval = .
engine2 = cluster-c3/YaneuraOu-nnue-cluster-c.exe , eval = .
T1,b1000,1442 - 99 - 1459(49.71% R-2.04[-12.64,8.57]) winrate black , white = 51.22% , 48.78%

engine1 = cluster-c1/YaneuraOu-nnue-cluster-c.exe , eval = .
engine2 = cluster-c4/YaneuraOu-nnue-cluster-c.exe , eval = .
T1,b1000,1258 - 74 - 848(59.73% R68.51[55.82,81.21]) winrate black , white = 52.28% , 47.72%

// 1T*4で急激に悪くなる。これは1手先から3手ずつ選出しているから、4つ目のエンジンが別の指し手を引いてきて
その4つ目のエンジンのponderが当たった時にこいつの指し手を割り当てるが、それが良くない(時が多々ある)ことを
示している。

あるエンジンからの読み筋があるので、それ活かすか、もう少し統計情報を出力するように改造してあれば、
ponderしてるエンジンと、元のエンジンと、どちらのほうがその局面についての情報を持っているかが
判断できそうなものなのだが。

  1分+1秒
  yo_cluster-c(1T*4) VS 1T
  34-14-36

  1分+2秒
  yo_cluster-c(1T*4) VS 1T
  11-11-35

  いやー、これはバグあるな…。
  1T*4になった時に固有のバグが…。


- makefile : NNUEのbuildに yo_cluster.cppが抜けていたの修正。
- NNUEのbuildでyo_clusterで警告が出ていたの修正。
- yo_clusterの割当アルゴリズム変更
・bestmove返して待機してるエンジン
・ponderしてたエンジン
この2つがあった時に先に見つけたほうに割当てている。
これ良くないな…。これを割り当てるならponderしてたエンジンのほうが良いはず…。


- yo_cluster : エンジンが指定してきたponderは、そのエンジンに思考させてあげるの良くなかったので変更。


- cluster版との比較

// 1T VS cluster 1T*1(cluster 1T×1engine)
engine1 = nnue/YaneuraOuNNUE_V720_avx2.exe , eval = .
engine2 = cluster/YaneuraOu-nnue-cluster.exe , eval = .
T1,b1000,192 - 24 - 684(21.92% R-220.7[-244.02,-197.38]) winrate black , white = 52.74% , 47.26%

1秒 VS 2秒とほぼ同じレート差。これがponder自体の価値。
ponderには、同型のソフトだとほぼ2倍の価値がある。

// 1T VS cluster 1T*4
T1,b1000,237 - 27 - 616(27.78% R-165.93[-187.76,-144.11]) winrate black , white = 51.23% , 48.77%

// 1T VS cluster 1T*3
T1,b1000,274 - 46 - 700(28.13% R-162.94[-183.29,-142.59]) winrate black , white = 51.13% , 48.87%

// 1T VS cluster 1T*2
T1,b1000,446 - 46 - 1268(26.02% R-181.51[-197.24,-165.79]) winrate black , white = 50.29% , 49.71%


// 1T*4なのに1T*1よりR50ぐらい弱くなってる。
// ponderhitの時の処理(GO)で損しているとしか考えられない。
// ponder候補自体は、bestmoveを返してたエンジンのponderの指し手を含むので。


- エンジンが指定してきたponderは、そのエンジンに思考させてあげるべき。
  →これ cluster-aとする。

// 1T VS cluster-a 1T*2
T1,b1000,368 - 36 - 886(29.35% R-152.63[-170.35,-134.92]) winrate black , white = 51.67% , 48.33%
// cluster-a、やらないほうがよさそう。

↓直接対決。
engine1 = cluster-a/YaneuraOu-nnue-cluster-a.exe , eval = .
engine2 = cluster/YaneuraOu-nnue-cluster.exe , eval = .
T1,b1000,379 - 21 - 420(47.43% R-17.84[-38.08,2.39]) winrate black , white = 52.19% , 47.81%


あー、なんかわかった。
・bestmove返して待機してるエンジン
・ponderしてたエンジン
この2つがあった時に先に見つけたほうに割当てている。
これ良くないな…。これを割り当てるならponderしてたエンジンのほうが良いはず…。
  → これをcluster-bとする。



// 自己対局コマンド
c:\python27\python engine_invoker6.py --engine1 nnue/YaneuraOuNNUE_V720_avx2.exe --eval1 . --engine2 cluster/YaneuraOu-nnue-cluster.exe --eval2 . --hash1 128 --hash2 128 --time b1000 --loop 3000 --PARAMETERS_LOG_FILE_PATH result --cores 40 --cpu 2 --rand_book 1


- yo_cluster ponder局面の選出にNNUEエンジンを利用できるようにした。
  - ponderするエンジンがないときのエラー抑制。
  - ponder局面の選定のコード、上位n/3+2手に対して3つずつ選出。
  - bestmove ponder出力したエンジンにponderの局面を強制で割り当てるのやめる。
  - gameoverのあとのbestmoveを受信した時の処理、ちゃんと書く。
  - ponder局面の選定、ふかうら王エンジンではなく、NNUEを使ってやる改造。


- yo_cluster
  - ponderするエンジンがないときのエラー抑制。

- yo_cluster
  - ponder局面の選定のコード、上位n/3+2手に対して3つずつ選出。

- yo_cluster
  - bestmove ponder出力したエンジンにponderの局面を強制で割り当てるのやめる。
  - gameoverのあとのbestmoveを受信した時の処理、ちゃんと書く。

- yo_cluster
  - ponder局面の選定、ふかうら王エンジンではなく、NNUEを使ってやる改造。



■ 2022/05/02


- position::is_repetition()高速化
  - position::is_repetition()は全体の3%程度か…。高速化する価値はあるかも?
  - Stockfishのほうは、cuckoo + st->rule50だからこれに相当するコードがないのか…。

  // Calculate the repetition info. It is the ply distance from the previous
  // occurrence of the same position, negative in the 3-fold case, or zero
  // if the position was not repeated.
  st->repetition = 0;
  int end = std::min(st->rule50, st->pliesFromNull);
  if (end >= 4)
  {
      StateInfo* stp = st->previous->previous;
      for (int i = 4; i <= end; i += 2)
      {
          stp = stp->previous->previous;
          if (stp->key == st->key)
          {
              st->repetition = stp->repetition ? -i : i;
              break;
          }
      }
  }
  // ここあるな…。


- search()の引き分け局面の判定、search()の先頭で行うようにした。
      // V750c
    → これ、Stockfishのコードと等価じゃない気がしてきた。
あちらは、has_game_cycle()を呼び出していて、千日手局面に到達するかを判定しているだけのような気が…。

			auto draw_type = pos.is_repetition(/*ss->ply*/);
			if (draw_type != REPETITION_NONE)
				return value_from_tt(draw_value(draw_type, pos.side_to_move()), ss->ply);


engine1 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V750c_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1556 - 26 - 1418(52.32% R16.13[5.64,26.62]) winrate black , white = 52.29% , 47.71%
T2,b2000,1332 - 46 - 1202(52.57% R17.84[6.47,29.21]) winrate black , white = 51.66% , 48.34%
// 千日手、すごい減ってる。でもだいぶよわなってる。

なんでこれで千日手減るのかはよくわからない。root nodeでも千日手判定するからか…。



- search()の引き分け局面でのdraw_valueに±1の乱数を加算するようにした。
      // V750b

↓以前のV720 vs V750
T2,b1000,1249 - 123 - 1258(49.82% R-1.25[-12.66,10.16]) winrate black , white = 53.25% , 46.75%

engine1 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V750b_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1466 - 136 - 1398(51.19% R8.25[-2.43,18.93]) winrate black , white = 54.68% , 45.32%

// つよなってない&千日手減ってない。revertする。


- search()の直後に千日手判定のコードを移動させた。

  千日手で枝刈りをするのは、↓この条件に限ることにした。

				if (alpha >= beta)
					return alpha;
      // V750a

      これで勝率が変わらず、千日手が減っていれば良いのだが。

↓以前のV720 vs V750
T2,b1000,1249 - 123 - 1258(49.82% R-1.25[-12.66,10.16]) winrate black , white = 53.25% , 46.75%

↓今回のやつ。
engine1 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V750a_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1447 - 125 - 1428(50.33% R2.3[-8.36,12.95]) winrate black , white = 49.36% , 50.64%

千日手が減ってないのだが…。
また、強くなっているのかどうかはわからない。



- yo_cluster 2022/05/02
  - "go ponder"(パラメーターなし)からの"ponderhit btime XX wtime XX binc YY winc YY"の時に最小時間で指してたの修正。
  - does_ で始まるメソッド名、おかしい気がするのでrename
  - bestmove ponderの指し手は、そのengineに継続させる。
  - すべてのponderが外れて、新規でGOする時に、0を選ぶのではなく前回bestmoveをGUIに返したエンジンでGOする。
  - ponder中の局面(指し手)は必ずGUIに出力する

  例
    [0:P]7g7f(E100)

    [0:P]
      0 は、engine id // 0から 台数N - 1
      そのあと
	   P = 前回思考してたと思われるエンジンでの Go Ponder
	   C = Continue to ponder : Ponderの継続
	   N = New ponder         : 新規のgo ponder
       G = Go                 : 現在の局面を思考中。
    7g7f   : 指し手
    (E100) :
       E   = goしていたEngineがbestmove XX ponder YYで返してきたponderの指し手YYであるという意味
       100 = 訪問回数


- yo_cluster
  - すべてのponderが外れて、新規でGOする時に、0を選ぶのではなく前回bestmoveをGUIに返したエンジンでGOする。


- yo_cluster
  - bestmove ponderの指し手は、そのengineに継続させる。

  1分+2秒
  yo_cluster(1T*7) VS 1T
  6-6-7
  // スーパーテラショック定跡 BookEvalDiff=30 , BookMoves=16 , BookBlackLimit 0 , BookWhiteLimit -100

  1分+2秒
  yo_cluster(1T*7) VS 1T
  // スーパーテラショック定跡 BookEvalDiff=50 , BookMoves=24 , BookBlackLimit -100 , BookWhiteLimit -200
  35-25-60 , -R92.5
  // ダブルスコアぐらいで負けている。GPU使うoverheadにしては負けすぎでは…。

  1分+1秒
  17-19-35
  yo_cluster(1T*4) VS 1T


- bench
  // bench
  search()のPVのdbg_hit_on()
  Total 55798603 Hits 36169 hit rate (%) 0.065
  99.935%はNonPV

  // bench 1024 16
  Total 519605132 Hits 349256 hit rate (%) 0.067

  many threadsでもほぼ同様

  // bench
  Total 33451 Hits 334 hit rate (%) 0.998
  search()のmoves_loopのなか。
	if (nodeType == Root)
		dbg_hit_on(moveCount == 0);
  Total 504724 Hits 4476 hit rate (%) 0.887

  // 開始局面
  info depth 35 seldepth 40 score cp 54 nodes 84600460 nps 4641745 hashfull 1000 time 18226 pv 2g2f 8c8d 7g7f 8d8e 8h7g 3c3d 7i6h 2b7g+ 6h7g 3a2b 3g3f 7a6b 2i3g 2b3c 3i3h 7c7d 6i7h 4a3b 1g1f 1c1d 2f2e 6a5b 5i6h 6c6d 4g4f 9c9d 9g9f 6b6c 2h2i 8a7c 4i4h 4c4d 3h4g
  Total 5371 Hits 235 hit rate (%) 4.375

開始局面、わりと選択肢あるんだな…。



■ 2022/05/01


- yo_cluster
  - ponder中の局面(指し手)は必ずGUIに出力する

  例
    [0:P]7g7f(E100)

    [0:P]
      0 は、engine id // 0から 台数N - 1
      そのあと
	   P = 前回思考してたと思われるエンジンでの Go Ponder
	   C = Continue to ponder : Ponderの継続
	   N = New ponder         : 新規のgo ponder
       G = Go                 : 現在の局面を思考中。
    7g7f   : 指し手
    (E100) :
       E   = goしていたEngineがbestmove XX ponder YYで返してきたponderの指し手YYであるという意味
       100 = 訪問回数



- yo_cluster
  - does_ で始まるメソッド名、おかしい気がするのでrename


Yo 1スレ×4 VS 1スレ(ponderあり) , 3分+2秒加算

30-5-27 , 52.6% = R18.1
// 差がほとんどつかない。これでは強くなっているのかがわからない。
// FV_SCALE = 16のまま計測しとった。😥

engine2 = YaneuraOuNNUE_V750_avx2.exe , eval = suishou6_20220114-fv32

// 計測しなおす。
Yo 1スレ×7 VS 1スレ(ponderあり) , 3分+3秒加算



■ 2022/04/30


- Mizarさんのプルリク以降、定跡生成時に落ちるようになったという報告があったのでその前後で対局させてみる。
engine1 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V750_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1249 - 123 - 1258(49.82% R-1.25[-12.66,10.16]) winrate black , white = 53.25% , 46.75%
T2,b2000,1420 - 180 - 1400(50.35% R2.46[-8.3,13.22]) winrate black , white = 50.5% , 49.5%
// 落ちない?


- remove duplicate Debug-Deep-TensorRT #232
  //  Mizarさんのプルリク 


- build MacOS & WebAssembly, install CUDA-11.6 + TensorRT8.2.4 (#231)
  //  Mizarさんのプルリク 
  * - nproc

  * - YANEURAOU_ENGINE_MATERIAL* ビルドテストの一部省略

  * - release build material lv1,lv9

  * - pacboy -Syuu

  * - remove base-devel: from actions

  * - remove base-devel:

  * - pacman update

  * - POPCNT, BSF, BSR の実装パターン追加

  * - MacOS

  * - NuGet packages bump up

  * - CUDA 11.6 Update 2, TensorRT 8.2 GA Update 3, cuda-nvrtc, remove copy cuda dlls
  - CUDA gpg-key change
    cf. https://github.com/NVIDIA/cuda-repo-management/issues/4

  * - clang-15

  * - DNN_Batch_Size max 1024

  * - fp16

  * - .gitignore

  * - badge MacOS, WebAssembly

  * - WASM port
    cf. https://github.com/arashigaoka/YaneuraOu.wasm
    cf. https://github.com/niklasf/stockfish.wasm
    cf. https://github.com/hi-ogawa/Stockfish

  * - wasm_build

  * - github workflows: wasm



- yo_cluster
  - SlowMover調整
    - PCたくさんあると、ponderかなり当たるので時間余るからSlowMover増やしたほうがいいかも。


- yo_cluster
  - "stop"をhandleするコードを追加。


- yo_cluster 20220430a
  - GO_PONDER → stop → GO で GO_PONDERの最後のログがGUIに出力されてしまう。
    GOでignore_bestmoveをインクリメントしないからか…。ここignoreではないのだが…。

  1分 + 1手4秒
  1スレッド(ponderなし) VS 1スレッド×4エンジン(Cluster)
    1-3-3
    // 対局回数少ないが改善したかも?

  1分 + 1手4秒
  1スレッド(ponderあり) VS 1スレッド×4エンジン(Cluster)
    13-2-9
    // 単体のエンジンにクラスターで4台も使って勝てないだと…。

    私のWCSC32は本日を持ちまして終了したようです。
    本当にありがとうございました。


- "go ponder"(パラメーターなし)からの"ponderhit btime XX wtime XX binc YY winc YY"の時に最小時間で指してたの修正。


- yo_cluster 20220430
  - デバッグメッセージをファイルに出力できるようにする。
  - id authorに対しては、clusterエンジンのエンジン名、作者名が反映するようにした。
    - engine_name.txt で変更可能。
  - Illegal Inputになるエンジンがあるの修正。
  - 詰み間際でエンジン落ちるの修正。
    - 詰んでて、ponderの指し手が無いからか…。
  - isreadyコマンドが来てから、DL部のisready()呼び出すことに。
  - usiに対してengine 0からのメッセージがGUIに返ってなかったの修正。
  - gameover後にinfoを受け取って警告が出ていたの修正。
  - ponderするengineの選出アルゴリズム、変更。

  1分 + 1手5秒
  1スレッド(ponderなし) VS 1スレッド×4エンジン(Cluster)
  4-9-16
  // ダブルスコア以上で負けとる…。俺のWCSC32、終わったな…。


■ 2022/04/29


- yo_cluster 20220429
  - goで思考局面になかった時のponderの局面がおかしいの修正。
  - goしているエンジンからのbestmoveに対して、偶数局面を選出してponderする。
  - 対局中に遊んでいるEngineがないか監視するコード追加。
  - ProcessNegotiatorとEngineNegotiator、copyとmove禁止にした。
  - goコマンドかなり実装した。
  - fixed_size_vector導入。


- sln: vs2022 (PR #230)
  - Mizarさんからのプルリク。slnファイル、新しいVisual Studioのslnにする件。

  
- yo_cluster
  - positionコマンド実装。
  - goコマンド途中まで実装。
    - 局面が当たった時に"ponderhit"を送信する。
    - あとは、当たらなかった時の処理と、残りのエンジンの処遇を決める処理と…。
  - エラー出力は、error_to_gui()にまとめる。
  - エンジンからのメッセージハンドラ、整理する。
  - エンジン側からのlogをbufferingしておき、"ponderhit"に対して出力するようにした。


- 同じやねうら王同士で思考時間2倍でどれくらいの差なのか?のデータ。

engine1 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000.b2000,607 - 144 - 2249(21.25% R-227.52[-240.59,-214.45]) winrate black , white = 51.26% , 48.74%
T2,b2000.b4000,663 - 185 - 2152(23.55% R-204.53[-217.22,-191.84]) winrate black , white = 52.18% , 47.82%
T2,b4000.b8000,308 - 89 - 833(26.99% R-172.84[-191.88,-153.79]) winrate black , white = 52.23% , 47.77%
T2,b4000.b8000,258 - 109 - 863(23.02% R-209.76[-230.02,-189.49]) winrate black , white = 50.49% , 49.51%
T2,b4000.b8000,284 - 98 - 848(25.09% R-190.03[-209.61,-170.45]) winrate black , white = 51.06% , 48.94%
T2,b8000.b16000,318 - 135 - 787(28.78% R-157.42[-176.4,-138.44]) winrate black , white = 52.94% , 47.06%
// 1 vs  2秒で R230ぐらいの差。
// 2 vs  4秒で R205ぐらいの差。
// 4 vs  8秒で R190ぐらいの差。
// 8 vs 16秒で R160ぐらいの差。
// 持時間が長くなると差が縮まっていく傾向はある。


■ 2022/04/28


- yo_cluster
  - クラスター本体が終了しているのにエンジン停止しないの修正。
    - 対応が簡単ではないようなのでやめる。quitコマンドで終了するようにはできた。
  - start_pondering()で各エンジンに"go ponder"でその局面を思考させるコードを追加。
  - 先行して go ponderするコードを書く。
    - their_search_sfen と our_search_sfenが必要。
    - 与えられた局面に対して遷移確率の高い上位の偶数局面と奇数局面を拾ってくるルーチンが必要。(少し書いた)
  - EngineNegotiatorState → EngineStateにrename


■ 2022/04/27


- USE_TIME_MANAGEMENTがdefineされていない時にコンパイル通らなくなっていたのを修正。


- makebook2021、ビルド通らなくなっていたの修正。

- yo_cluster
  - StandardInputを用いるように変更。
  - usinewgameのあとは、局面が来るまで適当な局面でgo ponderしておくように。
  - ある局面に対して、遷移可能性の高い上位N個の局面を列挙するルーチンを書く。
    - dlshogi::GetTopVisitedNodes()実装
    - dlshogi::GetSearchResult()、引数で返し値を用意することに変更。(vectorをreturnするの、コピーのコストちょっと嫌な気がした)
    - n-thまでは返るようになった。あとで精査する。
    - position_cmd()の宣言をusi.hに移動させる。
  - usinewgame , gameoverの実装。


- StandardInputクラス追加。
  - f 1コマンドでこれがclusterコマンドに対してもqueueが積まれてくれないと使いづらい。


■ 2022/04/26


- ponderhitコマンドの拡張の件、USI拡張コマンド.txtに記載する。


- ponderhitコマンド時に、goコマンド同様に残り時間等を指定できるように拡張。
  - btime,wtime,winc,binc,byoyomiを指定できる。
  - これによりgo ponder (残りパラメーターなし)でponderさせといて、ponderhitで残り時間を渡すような方法が採れる。

背景)
・pre-ponder時のgo ponderに関して

いまpre-ponderみたいなのを考える。

サーバーからpositionコマンドが送られてくる前に各worker engineに対して
go ponder
で思考させておく。サーバーからのpositionコマンドがponderingしている局面であった時にそのworker engineに対して
ponderhit
を送信する。こうすれば、思考時間制御が不要になって、worker engine側の思考時間制御に頼ることができる。

ところが、
ponderhit の時には残り持ち時間を送らない仕様になっているので、これができないのである。
そこで、
ponderhit btime XX wtime XX binc XX winc XX
みたいな形で現時点での残り時間をgoコマンドと同様に渡せるように拡張する必要がある。



- yo_cluster 作り直し
  - 気に入らないので作りなおす。
  - エンジンとして.batファイル対応。
  - エンジンとして"ssh ..."の形式に対応。
  - waitallオプションを指定すればエンジンの起動に失敗していたら起動したエンジンの数を出力して、プログラムは終了するようにした。
  - usi, isready, setoptionまで書けた。
  - info stringのError、guiに戻すようにした。
  - 起動したエンジンの数をreadyokのあとに出力するようにした。
  - debug,nodebugコマンドの追加。
- StringExtension::Contains()追加。


- usiコマンドで解釈できなくてErrorを出す時に、先頭にinfo stringをつけて出力するようにした。

- Ubuntu20.04でmakeコマンド手前までを 解説.txtに追記。


■ 2022/04/25


- V7.20

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V720_avx2.exe , eval = suishou6_20220114-fv32 // HASH_KEY_BITS = 128, TT_CLUSTER_SIZE = 4
T2,b1000,995 - 94 - 1171(45.94% R-28.29[-40.61,-15.98]) winrate black , white = 50.37% , 49.63%
T2,b2000,1330 - 172 - 1498(47.03% R-20.66[-31.43,-9.9]) winrate black , white = 53.71% , 46.29%
T2,b3000,1251 - 184 - 1565(44.42% R-38.9[-49.74,-28.07]) winrate black , white = 52.34% , 47.66%
T2,b4000,1265 - 217 - 1518(45.45% R-31.67[-42.55,-20.8]) winrate black , white = 52.43% , 47.57%
T2,b8000,1222 - 253 - 1525(44.48% R-38.48[-49.45,-27.51]) winrate black , white = 53.77% , 46.23%
T2,b16000,642 - 177 - 781(45.12% R-34.05[-49.26,-18.83]) winrate black , white = 52.99% , 47.01%
T2,b16000,741 - 191 - 958(43.61% R-44.62[-58.59,-30.64]) winrate black , white = 52.15% , 47.85%
T2,b16000,716 - 193 - 1011(41.46% R-59.94[-73.89,-45.98]) winrate black , white = 55.3% , 44.7%

// 持時間が倍になると+R10ずつぐらい強くなってる?


- threatened 歩だけに変更してみる。
  // V7.01ss

engine1 = YaneuraOuNNUE_V701pp_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701ss_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1428 - 139 - 1433(49.91% R-0.61[-11.29,10.08]) winrate black , white = 53.58% , 46.42%
T2,b2000,1289 - 181 - 1310(49.6% R-2.81[-14.02,8.4]) winrate black , white = 52.14% , 47.86%
T2,b3000,859 - 143 - 788(52.16% R14.99[0.9,29.08]) winrate black , white = 51.73% , 48.27%
T2,b4000,621 - 99 - 600(50.86% R5.98[-10.37,22.33]) winrate black , white = 51.43% , 48.57%
T2,b5000,204 - 49 - 227(47.33% R-18.56[-46.1,8.98]) winrate black , white = 52.9% , 47.1%

→ 誤差程度しか違わないがトータルで得していないので採用しないことにする。


- yo_cluster engine_list.txt batファイル、ssh対応


■ 2022/04/24


- makebook2021.cppがコンパイル通らなくなっていたのを修正。
  - Position::long_key → hash_key の影響。


- Position::long_key → hash_keyのようにrename
- Key128,Key256に暗黙のKeyへの変換を無くす。


- benchコマンドで結果に無駄な改行が出力されていたの修正。


- prefetchのコード、HASH_KEYが128bitになった時に間違えていたの修正。
  - 間違ってたと思ったら、アドレス計算自体はこれで合ってた…。
  // V7.01rr

after)
Total time (ms) : 60011
Nodes searched  : 74182734
Nodes_searched/second    : 1236152

before)
Total time (ms) : 60010
Nodes searched  : 73637043
Nodes_searched/second    : 1227079

after) bench 8192 16
Total time (ms) : 60018
Nodes searched  : 624959693
Nodes_searched/second    : 10412871
Nodes searched       (main thread) : 39646369
Nodes searched/second(main thread) : 660574

before) bench 8192 16
Total time (ms) : 60015
Nodes searched  : 610430866
Nodes_searched/second    : 10171304
Nodes searched       (main thread) : 38267842
Nodes searched/second(main thread) : 637637


- threatend bonusのコード、見直し。
  - 歩以外の小駒による脅威を計算するようにした。
  // V7.01qq

engine1 = YaneuraOuNNUE_V701pp_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701qq_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,705 - 87 - 628(52.89% R20.09[4.42,35.77]) winrate black , white = 49.74% , 50.26%
T2,b2000,520 - 70 - 500(50.98% R6.81[-11.08,24.7]) winrate black , white = 52.25% , 47.75%
T2,b3000,1235 - 177 - 1238(49.94% R-0.42[-11.91,11.07]) winrate black , white = 53.13% , 46.87%
T2,b4000,1006 - 167 - 977(50.73% R5.08[-7.75,17.91]) winrate black , white = 51.99% , 48.01%
T2,b4000,877 - 161 - 912(49.02% R-6.8[-20.31,6.71]) winrate black , white = 50.87% , 49.13%
T2,b5000,502 - 78 - 430(53.86% R26.89[8.13,45.66]) winrate black , white = 52.68% , 47.32%

// これたぶん悪いな…。


  // 実験中のコード

	if constexpr (Type == QUIETS)
	{
#if 0
		Color us = pos.side_to_move();
		// squares threatened by pawns
		threatenedByPawn  = pos.attacks_by<PAWN>(~us);
		// squares threatened by minors or pawns
		threatenedByMinor = pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
		// squares threatened by rooks, minors or pawns
		threatenedByRook  = pos.attacks_by<ROOK>(~us) | threatenedByMinor;

		// pieces threatened by pieces of lesser material value
		threatened =  (pos.pieces(us, QUEEN) & threatenedByRook)
					| (pos.pieces(us, ROOK)  & threatenedByMinor)
					| (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
#endif
		// → Stockfishのコードを忠実に実装すると将棋ではたくさんの利きを計算しなくてはならないので
		//     非常に計算コストが高くなる。
		// ここでは歩による当たりになっている駒だけ考える。

		const Color us = pos.side_to_move();

#if 0 // 歩による脅威だけ。
		// squares threatened by pawns
		threatenedByPawn = (~us == BLACK) ? pos.attacks_by<BLACK, PAWN>() : pos.attacks_by<WHITE, PAWN>();
#endif

#if 0
		// squares threatened by pawns
		threatenedByPawn = (~us == BLACK) ? pos.attacks_by<BLACK, PAWN>() : pos.attacks_by<WHITE, PAWN>();

		// squares threatened by minors or pawns
		threatenedByMinor = ((~us == BLACK) ? (pos.attacks_by<BLACK, LANCE>() | pos.attacks_by<BLACK, KNIGHT>() | pos.attacks_by<BLACK, SILVER>() | pos.attacks_by<BLACK, GOLDS>())
										    : (pos.attacks_by<WHITE, LANCE>() | pos.attacks_by<WHITE, KNIGHT>() | pos.attacks_by<WHITE, SILVER>() | pos.attacks_by<WHITE, GOLDS>()))
			| threatenedByPawn;

		// 歩以外の自駒で、相手の歩の利きにある駒 + 角馬飛龍の自駒に相手の小駒の利きがある
		threatened =  (pos.pieces(us,PAWN).andnot(pos.pieces(us))                 & threatenedByPawn ) |
					 ((pos.pieces(us,BISHOP_HORSE) | pos.pieces(us, ROOK_DRAGON)) & threatenedByMinor) ;
#endif
	}
	else
	{
		// Silence unused variable warnings
		//(void)threatened;
		//(void)threatenedByPawn;
		//(void)threatenedByMinor;
		//(void)threatenedByRook;
	}

	for (auto& m : *this)
	{
		if constexpr (Type == CAPTURES)
		{
			// Position::see()を用いると遅い。単に取る駒の価値順に調べたほうがパフォーマンス的にもいい。
			// 歩が成る指し手もあるのでこれはある程度優先されないといけない。
			// CAPTURE系である以上、打つ指し手は除外されている。
			// CAPTURES_PRO_PLUSで生成しているので歩の成る指し手が混じる。
			
			// MVV-LVAだが、将棋ではLVAあんまり関係なさげだが(複数の駒である1つの駒が取れるケースがチェスより少ない)、
			// Stockfish 9に倣いMVV + captureHistoryで処理する。

			// 歩の成りは別途考慮してもいいような気はするのだが…。
			// ここに来るCAPTURESに歩の成りを含めているので、捕獲する駒(pos.piece_on(to_sq(m)))がNO_PIECEで
			// ある可能性については考慮しておく必要がある。

			m.value = 6 * int(Eval::CapturePieceValue[pos.piece_on(to_sq(m))])
					 +    (*captureHistory)[to_sq(m)][pos.moved_piece_after(m)][type_of(pos.piece_on(to_sq(m)))];
		}
		else if constexpr (Type == QUIETS)
		{
			// 駒を取らない指し手をオーダリングする。
			// ここ、歩以外の成りも含まれているのだが…。
			// → 指し手オーダリングは、quietな指し手の間での優劣を付けたいわけで、
			//    駒を成るような指し手はどうせevaluate()で大きな値がつくからそっちを先に探索することになる。

			Piece movedPiece = pos.moved_piece_after(m);
			Square movedSq = to_sq(m);
			PieceType moved_piece = type_of(pos.moved_piece_before(m));

			// threatedned bonus(やねうら王独自拡張)
			//int bonus = 0;

#if 0 // 歩以外の駒に対する歩の脅威だけ
			if (threatened.test(from_sq(m)))
			{
				if (threatenedByPawn.test(to_sq(m)))
					if (moved_piece == BISHOP || moved_piece == ROOK)
						bonus = 50000;
					else if (moved_piece != PAWN)
						bonus = 15000;
			}
#endif

#if 0 // 大駒に対する歩の脅威だけ
					+     (threatened & from_sq(m) ?
							((moved_piece == ROOK || moved_piece == BISHOP) && !threatenedByPawn.test(to_sq(m))) ? 50000
						:                                                                                            0
						:                                                                                            0)
#endif

#if 0 // 歩以外の駒に対する歩とminor駒の脅威
					+     (threatened & from_sq(m) ?
							((moved_piece == ROOK || moved_piece == BISHOP) && !threatenedByMinor.test(to_sq(m)) ? 50000
						:    (moved_piece != ROOK && moved_piece != BISHOP) && !threatenedByPawn .test(to_sq(m)) ? 15000
						:                                                                                            0)
						:                                                                                            0)
#endif

			m.value =     (*mainHistory)[from_to(m)][pos.side_to_move()]
					+ 2 * (*continuationHistory[0])[movedSq][movedPiece]
					+     (*continuationHistory[1])[movedSq][movedPiece]
					+     (*continuationHistory[3])[movedSq][movedPiece]
					+     (*continuationHistory[5])[movedSq][movedPiece]
				//	移動元の駒が安い駒で当たりになっている場合、移動させることでそれを回避できるなら価値を上げておく。
#if 0
					+     (threatened & from_sq(m) ?
							 (type_of(pos.moved_piece_before(m)) == QUEEN && !(to_sq(m) & threatenedByRook ) ? 50000
							: type_of(pos.moved_piece_before(m)) == ROOK  && !(to_sq(m) & threatenedByMinor) ? 25000
							:                                                !(to_sq(m) & threatenedByPawn ) ? 15000
							:																					0)
																											    0);
				// → Stockfishのコードそのままは書けない。
#endif
					//+ bonus;
					;

		}




- reformat
  - ソースコード、改行が崩れているところなど修正。

- SlowMoverの説明を修正。


■ 2022/04/23


- TT_ClusterSizeとして、2,3以外に4,6,8,16,32などを選べるようにした。

TT_ClusterSize cl = 4
===========================
Total time (ms) : 60012
Nodes searched  : 74991984
Nodes_searched/second    : 1249616
===========================

TT_ClusterSize cl = 2
===========================
Total time (ms) : 60009
Nodes searched  : 77259881
Nodes_searched/second    : 1287471
===========================

3%違いか。どれくらい探索に影響出るかだな…。

  // V7.10pp
engine1 = YaneuraOuNNUE_V701oo_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701pp_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1451 - 137 - 1412(50.68% R4.73[-5.95,15.41]) winrate black , white = 49.67% , 50.33%
T2,b2000,1241 - 172 - 1227(50.28% R1.97[-9.53,13.47]) winrate black , white = 53.4% , 46.6%
T2,b4000,432 - 81 - 457(48.59% R-9.77[-28.94,9.39]) winrate black , white = 53.77% , 46.23%
T2,b4000,583 - 104 - 573(50.43% R3.01[-13.8,19.81]) winrate black , white = 55.19% , 44.81%

// 長い時間で悪くない可能性が…ある…な?
// 大会では、これ使うか。


- 王手延長は開き王手と駒損しない王手に限定する。

				else if (givesCheck
					&& depth > 9
					&& abs(ss->staticEval) > 71)
					// この条件、やねうら王で独自追加。
					// → 王手延長は、開き王手と駒損しない王手に限定する。
					&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
					extension = 1;
  // V701oo

engine1 = YaneuraOuNNUE_V701nn_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701oo_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1226 - 124 - 1300(48.54% R-10.18[-21.55,1.19]) winrate black , white = 52.22% , 47.78%
T2,b2000,1421 - 161 - 1418(50.05% R0.37[-10.36,11.09]) winrate black , white = 53.12% , 46.88%
T2,b4000,1162 - 192 - 1196(49.28% R-5.01[-16.78,6.76]) winrate black , white = 52.46% , 47.54%
T2,b4000,1143 - 193 - 1214(48.49% R-10.47[-22.24,1.31]) winrate black , white = 55.45% , 44.55%

→ これやったほうが良さそう。


- V701nnを やねうら王 128-bit Editionとしてリリース。
→ YaneuraOuNNUE_V710-128.zip
https://github.com/yaneurao/YaneuraOu/releases/tag/v7.10


- bestMoveCountという変数の除去
  - Simplify away best move count logic : https://github.com/official-stockfish/Stockfish/commit/e41f727f0f7041b43997f04c031353be5087856b

- 置換表上のスコア(value)がalpha,valueより小さいものは負の延長を行う。
  - Negative extension for ttMove that is less than alpha and value : https://github.com/official-stockfish/Stockfish/commit/e1f12aa4e61a8bbb772918c405137acdd85e3eec
  // V701nn

engine1 = YaneuraOuNNUE_V701kk_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701nn_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1430 - 150 - 1420(50.18% R1.22[-9.48,11.92]) winrate black , white = 51.89% , 48.11%
T2,b2000,1426 - 189 - 1385(50.73% R5.07[-5.71,15.85]) winrate black , white = 53.18% , 46.82%
T2,b4000,791 - 188 - 811(49.38% R-4.34[-18.61,9.94]) winrate black , white = 55.49% , 44.51%
T2,b4000,489 - 77 - 494(49.75% R-1.77[-19.99,16.45]) winrate black , white = 54.83% , 45.17%

// ほぼ互角だが、4秒で悪くないし、元のコードがよりシンプルになるので導入する。


- LMRのcapture history based pruningのコード、復活させる。

  // Stockfishでは削除された枝刈り。これはあったほうが良いらしい。
  // Capture history based pruning when the move doesn't give check
  if (  !givesCheck
	  && lmrDepth < 1
	  && captureHistory[to_sq(move)][movedPiece][type_of(pos.piece_on(to_sq(move)))] < 0)
	  continue;
  // V701mm

engine1 = YaneuraOuNNUE_V701ll_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701mm_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1395 - 110 - 1495(48.27% R-12.03[-22.66,-1.39]) winrate black , white = 53.53% , 46.47%
T2,b2000,1424 - 169 - 1407(50.3% R2.09[-8.65,12.83]) winrate black , white = 51.11% , 48.89%
T2,b4000,947 - 151 - 932(50.4% R2.77[-10.41,15.95]) winrate black , white = 54.07% , 45.93%
T2,b4000,580 - 87 - 543(51.65% R11.45[-5.6,28.51]) winrate black , white = 52.98% , 47.02%

→ ほぼ誤差だったのでこのコードは(ソースコード上に残すものの)コメントアウト



■ 2022/04/22


- 王手延長のコード、ちょっと考えなおす。


- probCutのassert、修正。


- qsearch内での詰みの条件、考えなおして、8ヶ月前のコードに戻した。

		// チェスでは王手がかかっていて、合法手がない時に詰みだが、
		// 将棋では、合法手がなければ詰みなので ss->inCheckの条件は不要
		// かと思ったら、qsearch()で王手がかかっていない時は、
		//  captureとcheckの指し手しか生成していないから、moveCount==0だから詰みとは限らない。
		// 王手されている局面なら、evasion(王手回避手)を生成するから、moveCount==0なら詰みと確定する。
		// ただし、その場合、bestValue == -VALUE_INFINITEだし、仮にmoveCount !=0 でもその回避手で詰みなら
		// bestValue == -VALUE_INFINITEのまま(だと思う)ので、moveCountよりbestValue == -VALUE_INFINITEで
		// 比較するほうが優れている。

		if (ss->inCheck && bestValue == -VALUE_INFINITE)
		{
			// 合法手は存在しないはずだから指し手生成しても速攻終わるはず。
			ASSERT_LV5(!MoveList<LEGAL>(pos).size());

			return mated_in(ss->ply); // Plies to mate from the root
									  // rootから詰みまでの手数。
		}
    // V701ll
engine1 = YaneuraOuNNUE_V701jj_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701ll_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1457 - 138 - 1405(50.91% R6.31[-4.37,17.0]) winrate black , white = 51.89% , 48.11%
T2,b2000,1380 - 185 - 1435(49.02% R-6.79[-17.56,3.98]) winrate black , white = 52.11% , 47.89%
T2,b4000,568 - 89 - 573(49.78% R-1.52[-18.43,15.39]) winrate black , white = 50.22% , 49.78%


- qsearch内での詰みの条件間違ってた。
  - benchでmate1って出るの調べる。
    - 王手がかかっていない時、captureとcheckの指し手しか生成していないの忘れていた。
    // V701kk
    if (ss->inCheck && moveCount == 0)
    に変更。

    Stockfishも12年前は↓ではなく↑この書き方だったようだ。moveCountが除去された時に変更されてしまったようだ。
		if (ss->inCheck && bestValue == -VALUE_INFINITE)

      cf. https://github.com/official-stockfish/Stockfish/commit/452f0d16966e0ec48385442362c94a810feaacd9

    moveCountが再度導入されたからには、Stockfishもここは、↑の書き方に戻したほうが良いと思う。

engine1 = YaneuraOuNNUE_V701jj_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701kk_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1384 - 138 - 1478(48.36% R-11.42[-22.1,-0.73]) winrate black , white = 52.03% , 47.97%
T2,b2000,1365 - 158 - 1277(51.67% R11.58[0.45,22.7]) winrate black , white = 51.36% , 48.64%
T2,b4000,612 - 90 - 638(48.96% R-7.23[-23.39,8.93]) winrate black , white = 50.88% , 49.12%



- SSSE3でコンパイルが通らなかったの修正。


- 王手延長のコード、独自コードに変更。

	// やねうら王独自コード
	// → 王手延長は、開き王手と駒得しながらの王手に限定する。
	else if (givesCheck
		&& depth > 9
		&& abs(ss->staticEval) > 71
		&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
		extension = 1;
  // V701jj
engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701jj_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1470 - 149 - 1381(51.56% R10.85[0.14,21.56]) winrate black , white = 51.53% , 48.47%



- Key128、Key256、AVX2以外の環境で動くようにするの忘れていたの修正。


- tt.hで一部の環境でコンパイルエラーになっていたの修正。
  // V701ii

engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701ii_avx2.exe , eval = suishou6_20220420-fv32
T2,b2000,1374 - 178 - 1448(48.69% R-9.11[-19.87,1.65]) winrate black , white = 53.26% , 46.74%


engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701hh128-cl2_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1052 - 102 - 1036(50.38% R2.66[-9.84,15.17]) winrate black , white = 52.25% , 47.75%



- tt.h 整形


- TT_CLUSTER_SIZEをmakefileで指定できるようにした。
- USI拡張コマンド "config" 追加。
- Key128,256、高速化。


■ 2022/04/21

- KEY_TYPEでコンパイルエラーになっていたの修正。

- Hash key 128bit化対応

・メモリ大容量時代の置換表について

TTEntryにhash keyを64bit格納したところで、TTClusterのindexの計算にhash keyの上位bitを用いているので、
例えば、TTClusterを2^32個(4G個)確保する時には、hash keyの下位32bitしかチェックしていないも同じである。
TTClusterは32[byte]なので4G×32B = 128GBである。いまどきAWSのc5,c6インスタンスを借りることを思えば、
128GBぐらいは確保するだろう。

そうなると結局32bitのhash keyを用いているのと同じことになってしまう。4Gと言うと多いようだが、
大会では0.1G nps近く出ているので、40秒に1回ぐらい違う局面のTTEntryを持ってきていることになる。
それが詰み絡みの局面でないことを祈るばかりである。

もう少し極論をすれば、TTClusterを2^64個確保した場合には、いまの実装の場合、TTEntryに格納されている
keyは毎回TT.probe()に用いたkeyと合致してしまう。hash衝突率100%である。そう考えるとhash key自体は128bitで
保持するのが正しく、TTEntryに格納するのはその下位64bit、TTClusterの計算に用いるのはその上位64bit、のようにせねばなるまい。


   // YaneuraOuNNUE_V701hh64_avx2.exe : hash key 64bitのほう



engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701hh64_avx2.exe , eval = suishou6_20220420-fv32
T2,r100,929 - 39 - 942(49.65% R-2.41[-15.62,10.79]) winrate black , white = 50.45% , 49.55%

engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701hh64-cl3_avx2.exe , eval = suishou6_20220420-fv32



hh128 - TTCluster = 2
===========================
Total time (ms) : 60009
Nodes searched  : 79764609
Nodes_searched/second    : 1329210
Nodes_searched/second    : 1298939
===========================


hh64 - TTCluster = 2
===========================
Total time (ms) : 60009
Nodes searched  : 78675063
Nodes_searched/second    : 1311054
===========================

ほぼ変わらん…?



- make_promoted_piece() , is_promoted_piece()追加
  - Positionクラス、↑を使って少し整理。
    // V7.01hh

- 改造したので壊していないかのチェック

engine1 = YaneuraOuNNUE_V701gg_avx2.exe , eval = suishou6_20220420-fv32
engine2 = YaneuraOuNNUE_V701hh_avx2.exe , eval = suishou6_20220420-fv32
T2,r100,1491 - 52 - 1457(50.58% R4.01[-6.52,14.53]) winrate black , white = 50.88% , 49.12%

壊してはなさそう。


- 水匠 20220114 vs 20220420
engine1 = YaneuraOuNNUE_V701ff_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701ff_avx2.exe , eval = suishou6_20220420-fv32
T2,b1000,1464 - 140 - 1396(51.19% R8.26[-2.43,18.95]) winrate black , white = 51.36% , 48.64%
T2,b2000,1112 - 128 - 1100(50.27% R1.88[-10.26,14.03]) winrate black , white = 51.9% , 48.1%
T2,b2000,511 - 53 - 476(51.77% R12.33[-5.87,30.52]) winrate black , white = 50.05% , 49.95%
T2,b4000,752 - 112 - 766(49.54% R-3.2[-17.87,11.46]) winrate black , white = 52.77% , 47.23%

// 強くなってない?


■ 2022/04/20


- docs: go perft #229
  - perftの説明古いままだった。
  - Mizarさんのプルリク


・hash key の bit数を16→64に。

いつぞやのStockfishのcommitで TTEntryのhash keyの格納bit数が16bit(byte)になってしまった。そもそもで言うと、
TTEntryは10byte、これを3つ束ねて30byte、そこに2byte paddingして32byteにしてある。
素直にTTEntryを16byteにして2つ束ねて32byteにして何か問題があろうか。6byte増えれば格納できるhash keyは64bitになる。
つまりは、いま探索部で使っているhash keyをそのまま格納できるわけである。TTEntryが3個から2個になるデメリット(置換表効率ダウン)は
USI_Hashが大きければ無視できるはずで、格納keyが16bitであるためhash衝突していたのが回避できる分だけ強くなるはずである。
またmateバグが置換表由来のバグなのであるなら、これでmateバグは起きないようになるはずである。

・USI_Hashは2のべき乗のほうが良いのか?

  USI_Hashのサイズ、いつぞやの改良で2のべき乗でなくても良くなった。
  原理としては、TTClusterのアドレスを求める時に
  index = hash_key(64bit) × clusterCount(TTClusterの数) / (2*64)
  として
  tt_entry = cluster[index]
  とする。

  こうすることによって、indexは 0 から (clusterCount - 1) の範囲の整数となる。それは良いのだが、そのあと、
  probeの時にTTEntryに格納されているhash key(16bit)と比較する。このhash keyは元のhash keyの下位16bitを用いている。

  ということは、上のindexの計算の時には元のhash keyの上位bit(できれば64-16=48bit)が用いられるのが望ましい。

  そのためには、clusterCountは2のべき乗であるほうが上位bitからきっちり使われるので、都合がいいのである。

  そんなわけで、USI_Hashは2のべき乗のほうがhash衝突の確率は下がるということになる。


- TTClusterSize 2に設定できるようにした。
  - config.hで TTClusterSize を変更できる。
  // V7.01ff

engine1 = YaneuraOuNNUE_V701ee_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701ff_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1460 - 130 - 1410(50.87% R6.05[-4.61,16.72]) winrate black , white = 52.86% , 47.14%

// USI_Hash 128MB vs 256MB
engine1 = YaneuraOuNNUE_V701ee_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701ff_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1462 - 143 - 1395(51.17% R8.15[-2.54,18.84]) winrate black , white = 50.09% , 49.91%
T2,b2000,1438 - 155 - 1407(50.54% R3.79[-6.93,14.5]) winrate black , white = 51.56% , 48.44%
T2,b4000,1218 - 190 - 1222(49.92% R-0.57[-12.14,11.0]) winrate black , white = 55.12% , 44.88%
T2,b8000,723 - 181 - 726(49.9% R-0.72[-15.73,14.29]) winrate black , white = 53.21% , 46.79%

// USI_Hashを倍にして比較した場合、強さにほぼ差がない。


■ 2022/04/19


- Position::to_move()で簡単な合法手判定を行うようにした。
  - 速度が少し低下するが、置換表でhash衝突した時に変な指し手で枝刈りするよりマシ。
- 探索部でPosition::to_move()を呼び出したあとにMOVE_NONEが返ってきたら置換表にhitしなかったことにするように変更した。
  - 速度が少し低下するが、置換表でhash衝突した時に変な指し手で枝刈りするよりマシ。
- Position::to_move()で駒打ちの時に上位に駒のbit持ってこれていなかったの修正。
  // V7.01ee

engine1 = YaneuraOuNNUE_V701aa_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701ee_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1186 - 105 - 1169(50.36% R2.51[-9.27,14.28]) winrate black , white = 52.7% , 47.3%
T2,b2000,553 - 78 - 549(50.18% R1.26[-15.95,18.47]) winrate black , white = 51.45% , 48.55%
T2,b4000,597 - 97 - 656(47.65% R-16.37[-32.53,-0.22]) winrate black , white = 52.43% , 47.57%
T2,b8000,1073 - 217 - 1060(50.3% R2.12[-10.25,14.49]) winrate black , white = 54.99% , 45.01%

// ほぼ誤差


- Position::super_legal → Position::legal_promote に rename


- Stockfish 15
  - https://github.com/official-stockfish/Stockfish/commit/e6e324eb28fd49c1fc44b3b65784f85a773ec61c

  // Stockfish 15相当までは完全に追いついた。


- V7.01aaに対して
  Decrease LMR at PV nodes with low depth. : https://github.com/official-stockfish/Stockfish/commit/df2f7e75276cc93a8cb8c70057903ab0edbd92bd
  // V7.01dd
  → どうも導入前より悪いのでコメントアウト

engine1 = YaneuraOuNNUE_V701aa_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701dd_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1462 - 135 - 1403(51.03% R7.16[-3.52,17.83]) winrate black , white = 51.59% , 48.41%
T2,b2000,1156 - 157 - 1117(50.86% R5.96[-6.02,17.95]) winrate black , white = 50.68% , 49.32%
T2,b4000,518 - 93 - 499(50.93% R6.49[-11.42,24.41]) winrate black , white = 52.31% , 47.69%
T2,b8000,681 - 159 - 630(51.95% R13.52[-2.27,29.31]) winrate black , white = 52.71% , 47.29%


■ 2022/04/16

- V7.01aaに対してsuper_sortを使う条件をさらに調整。
  // V7.01cc
			// depth大きくて指し手の数も多い時だけsuper sortを使うとどう?
			if ((depth >= 15 && endMoves - cur >= 32) || (depth >= 10 && endMoves - cur >= 64) || (depth >= 5 && endMoves - cur >= 96) )
				super_sort(cur, endMoves);
			else
				partial_insertion_sort(cur, endMoves, -3000 * depth);

engine1 = YaneuraOuNNUE_V701aa_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701cc_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1421 - 125 - 1454(49.43% R-3.99[-14.65,6.67]) winrate black , white = 52.49% , 47.51%
T2,b2000,999 - 135 - 986(50.33% R2.28[-10.55,15.1]) winrate black , white = 51.44% , 48.56%
T2,b4000,813 - 140 - 857(48.68% R-9.16[-23.14,4.83]) winrate black , white = 52.04% , 47.96%
T2,b8000,620 - 116 - 624(49.84% R-1.12[-17.31,15.08]) winrate black , white = 52.97% , 47.03%
// どう条件を調整してもよくならん感じ…。



- V7.01aaに対してsuper_sortを使う条件をさらに調整。
  // V7.01bb
			// depth大きくて指し手の数も多い時だけsuper sortを使うとどう?
			if (depth >= 15 && endMoves - cur >= 64)
				super_sort(cur, endMoves , -3000 * depth);
			else
				partial_insertion_sort(cur, endMoves, -3000 * depth);

engine1 = YaneuraOuNNUE_V701aa_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701bb_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1425 - 144 - 1431(49.89% R-0.73[-11.42,9.96]) winrate black , white = 52.8% , 47.2%
T2,b2000,1000 - 140 - 1000(50.0% R-0.0[-12.78,12.78]) winrate black , white = 52.65% , 47.35%
T2,b4000,657 - 117 - 636(50.81% R5.64[-10.25,21.53]) winrate black , white = 50.5% , 49.5%


- benchコマンドで sync_endl一つ多かったの修正。


- V7.01wに対して
  - capture_or_promotionだけ元(capture)に戻して比較。
  // V7.01aa

engine1 = YaneuraOuNNUE_V701w_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701aa_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1406 - 133 - 1461(49.04% R-6.67[-17.34,4.01]) winrate black , white = 49.42% , 50.58%
T2,b2000,1445 - 184 - 1371(51.31% R9.13[-1.64,19.9]) winrate black , white = 51.31% , 48.69%
T2,b4000,1385 - 226 - 1389(49.93% R-0.5[-11.35,10.35]) winrate black , white = 52.02% , 47.98%
T2,b8000,909 - 208 - 943(49.08% R-6.38[-19.66,6.9]) winrate black , white = 52.43% , 47.57%
  // aaのほうが良さげに見えるが誤差かも。


engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701aa_avx2.exe , eval = Suisho5_211028
T2,b1000,1346 - 143 - 1511(47.11% R-20.09[-30.8,-9.38]) winrate black , white = 52.19% , 47.81%
T2,b8000,650 - 140 - 820(44.22% R-40.36[-55.36,-25.36]) winrate black , white = 53.33% , 46.67%


- V7.01wに対して
 - super sort、条件が良さげな時だけ使う。
  // V7.01z

			// depth大きくて指し手の数も多い時だけsuper sortを使うとどう?
			if (depth >= 10 && endMoves - cur >= 64)
				partial_super_sort(cur, endMoves , -3000 * depth);
			else
				partial_insertion_sort(cur, endMoves, -3000 * depth);

engine1 = YaneuraOuNNUE_V701w_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701z_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1457 - 145 - 1398(51.03% R7.18[-3.52,17.88]) winrate black , white = 52.78% , 47.22%
T2,b2000,817 - 124 - 879(48.17% R-12.71[-26.59,1.18]) winrate black , white = 52.06% , 47.94%
T2,b4000,1392 - 217 - 1391(50.02% R0.12[-10.71,10.96]) winrate black , white = 53.47% , 46.53%
T2,b8000,1333 - 290 - 1367(49.37% R-4.38[-15.37,6.62]) winrate black , white = 54.63% , 45.37%

// super sortの使う条件、やはりこれでもおかしいのか…。
// depth条件が悪いのか…。うーむ...


- V7.01wに対してmovepicker、歩以外の駒に対する歩の脅威を実装。
- supersortやめる
  // V7.01y
engine1 = YaneuraOuNNUE_V701w_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701y_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,617 - 57 - 596(50.87% R6.02[-10.39,22.42]) winrate black , white = 54.49% , 45.51%
// 良いとは言い難いので、脅威の実装やめる。


- supersort使ってみる。
- V7.01wに対して。
  // V7.01x
engine1 = YaneuraOuNNUE_V701w_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701x_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1406 - 128 - 1466(48.96% R-7.26[-17.92,3.4]) winrate black , white = 51.53% , 48.47%
T2,b8000,460 - 99 - 421(52.21% R15.39[-3.87,34.65]) winrate black , white = 56.41% , 43.59%

// 短い時間では効果があるようなのだが、長い時間で効果がない。なんで?


- movepickerのthreatenやめてみる。
- 探索部のcapture → 全部capture_or_pawn_promotionに変更してみる。
  // V7.01w

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701w_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,656 - 66 - 748(46.72% R-22.8[-38.08,-7.52]) winrate black , white = 50.36% , 49.64%
T2,b4000,708 - 118 - 824(46.21% R-26.36[-41.0,-11.72]) winrate black , white = 51.57% , 48.43%
T2,b8000,666 - 138 - 936(41.57% R-59.12[-73.6,-44.64]) winrate black , white = 53.0% , 47.0%
// 長い時間でわりと強い。

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701w_avx2.exe , eval = Suisho5_211028
T2,b1000,1322 - 145 - 1533(46.3% R-25.72[-36.45,-15.0]) winrate black , white = 51.45% , 48.55%
T2,b8000,807 - 212 - 1001(44.63% R-37.42[-50.94,-23.91]) winrate black , white = 51.44% , 48.56%


- movepickerでPRO_PLUS使うのやめてみる。
- movepickerのthreatenやめてみる。
  // V7.01v

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701v_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,649 - 33 - 438(59.71% R68.31[50.65,85.97]) winrate black , white = 52.53% , 47.47%
T2,b8000,111 - 15 - 74(60.0% R70.44[27.66,113.21]) winrate black , white = 46.49% , 53.51%

// これはよくないな…。


- movepickerにthreatenedByMinor追加。

- Piece::QUEEN廃止。
- Bitboard::attacks_bb()追加。
- Bitboard::pawn_attacks_bb()追加
- Position::attacks_by() template引数のColorとPieceを逆順に。

- B_QUEEN , W_QUEEN削除。
  - B_GOLDS , W_GOLDSとして使いたいので。
    // V7.01u

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701u_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1350 - 120 - 1430(48.56% R-10.0[-20.84,0.84]) winrate black , white = 51.69% , 48.31%
T2,b2000,599 - 68 - 773(43.66% R-44.3[-59.85,-28.75]) winrate black , white = 51.82% , 48.18%
T2,b8000,632 - 117 - 731(46.37% R-25.28[-40.8,-9.76]) winrate black , white = 51.58% , 48.42%

// 短い時間では改善しているが、長い時間で改善しているか怪しい。



■ 2022/04/14


- attacks_bb()などのUnitTest追加。


- やねうら王V7.10
  - Stockfish最新[2022/04/14]に追いついたが、ほとんど強くなってない😇


- In movepicker increase priority for moves that evade a capture
  - https://github.com/official-stockfish/Stockfish/commit/08e0f52b77edb929989c68c49e954b9bc5d7d67e
- MovePickerのQUIETのscoringにthreatened導入。
- Bitboard::attacks_bb()実装
- Position::attacks_by()実装
  // V701t

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701t_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1120 - 94 - 1136(49.65% R-2.46[-14.49,9.57]) winrate black , white = 52.53% , 47.47%
T2,b2000,1069 - 142 - 1159(47.98% R-14.04[-26.16,-1.93]) winrate black , white = 52.42% , 47.58%
T2,b4000,1054 - 176 - 1180(47.18% R-19.62[-31.72,-7.51]) winrate black , white = 52.24% , 47.76%
T2,b8000,377 - 83 - 480(43.99% R-41.96[-61.61,-22.31]) winrate black , white = 54.03% , 45.97%
// 長い時間ではそこまで悪くはなさげ?


- bestThreadの選出、よく見直す。
→ 問題なさそう。
- MovePickerのCAPTURE、pro_plus除外するか。
→ 問題なさそう。


		const Color us = pos.side_to_move();
		// squares threatened by pawns
		threatenedByPawn = ~us == BLACK ? pos.attacks_by<PAWN,BLACK>() : pos.attacks_by<PAWN,WHITE>();

		// squares threatened by minors or pawns
		//threatenedByMinor = pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
		// → 将棋では小駒を入れていいと思う。
		threatenedByMinor = ~us == BLACK ?
				pos.attacks_by<LANCE, BLACK>() | pos.attacks_by<KNIGHT, BLACK>() | pos.attacks_by<SILVER, BLACK>() | pos.attacks_by<GOLD, BLACK>() | threatenedByPawn
			:   pos.attacks_by<LANCE, WHITE>() | pos.attacks_by<KNIGHT, WHITE>() | pos.attacks_by<SILVER, WHITE>() | pos.attacks_by<GOLD, WHITE>() | threatenedByPawn;

		// squares threatened by rooks, minors or pawns
		threatenedByRook = ~us == BLACK ?
			  pos.attacks_by<ROOK, BLACK>() | threatenedByMinor
			: pos.attacks_by<ROOK, WHITE>() | threatenedByMinor;

		// pieces threatened by pieces of lesser material value
		threatened = (pos.pieces(us, QUEEN) & threatenedByRook)
			| (pos.pieces(us, ROOK) & threatenedByMinor)
			| (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);


- Adjust singular extension depth restriction
  - https://github.com/official-stockfish/Stockfish/commit/8e8234593190804babd36b8a8862e2bb1fc65bb7
  // V701s

// r→sでなんか弱なっとる。

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701s_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1379 - 111 - 1510(47.73% R-15.77[-26.41,-5.12]) winrate black , white = 52.41% , 47.59%



- Tweak history initialization : https://github.com/official-stockfish/Stockfish/commit/7d44b43b3ceb2eebc756709432a0e291f885a1d2
  - continuation historyを少し負の値(-71)で初期化する。

  // ほとんどの履歴エントリがいずれにせよ後で負になるため、
  // 開始値を「正しい」方向に少しシフトさせるため、-71で埋めている。
  // この効果は、深度が深くなるほど薄れるので、長時間思考させる時には
  // あまり意味がないが、無駄ではないらしい。
  // Tweak history initialization : https://github.com/official-stockfish/Stockfish/commit/7d44b43b3ceb2eebc756709432a0e291f885a1d2

  // V701r
engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701r_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1319 - 124 - 1557(45.86% R-28.82[-39.51,-18.13]) winrate black , white = 52.16% , 47.84%
T2,b2000,744 - 103 - 913(44.9% R-35.56[-49.67,-21.45]) winrate black , white = 51.84% , 48.16%
T2,b4000,248 - 44 - 288(46.27% R-25.98[-50.71,-1.24]) winrate black , white = 52.05% , 47.95%
// 長い時間で言うほどつよない


- Reintroduce check extension
  // V701q

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701q_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1327 - 138 - 1535(46.37% R-25.29[-36.0,-14.59]) winrate black , white = 52.48% , 47.52%


- Reintroduce futility pruning for captures : https://github.com/official-stockfish/Stockfish/commit/fb7d3ab32ebd7a6514bded459b4aa442276f6cda
  - CapturePieceValueEg()追加。
- Correctly reset bestMoveChanges : https://github.com/official-stockfish/Stockfish/commit/c1f9a359e8e319d832ee5a55277dab996dd29d25
- Tweak time management : https://github.com/official-stockfish/Stockfish/commit/18f2b12cd019212b9c7103cc63e3bf64a5be7c3c
  // V701p

  engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
  engine2 = YaneuraOuNNUE_V701p_avx2.exe , eval = suishou6_20220114-fv32
  T2,b1000,455 - 41 - 514(46.96% R-21.18[-39.56,-2.8]) winrate black , white = 49.54% , 50.46%


- Introduce movecount pruning for quiet check evasions in qsearch
  - https://github.com/official-stockfish/Stockfish/commit/95d7369e54f20715345cf5408040f3c7d1ec8415

- Introduce Optimism : https://github.com/official-stockfish/Stockfish/commit/a5a89b27c8e3225fb453d603bc4515d32bb351c3
  → これ、trendとかと絡むので導入せず。

  このパッチでは、実際にスケーリングを行う前に、Stockfishの評価に小さな「楽観」値を追加することで、この2つの戦略の間の転換点をわずかに相殺します。
  その効果は、SFがもう少しリスキーなプレイをし、防衛しているときはもう少し緊張を保とうとし、優位にあるときはボード上にさらに多くの材料を維持することである。

  このパッチは、昔あった「軽蔑」の考えと精神的に似ていることに注目します。
  しかし、この実装は次の2つの点で異なっている。

    a) マスターに対するEloゲイナーとしてテストされている。
    b) 検索によって出力される値は、この実装によって平均的に変化しない。(つまり、楽観値によってテンション・交換戦略は変わるが 1.0ポーンという表示値は、パッチの前後で同じ意味を持つ)。

→ 興味深いのは、nnueのevaluate()のスコアをスケーリングする時に、その係数は固定ではなく、序中盤と終盤とでは、この係数を変化させているということ。
// もし序盤の優劣で大きなスコアがつかないから 0 付近の解像度をあげようとするとき、たとえば nnueの出力の絶対値が 300未満なら 係数を大きくする、みたいなことは意味がありそう。

- Simplify limiting extensions. : https://github.com/official-stockfish/Stockfish/commit/9083050be692b2d9a4f281e78b967755e00cfc39
  // V701o

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701o_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,346 - 39 - 395(46.69% R-23.01[-44.04,-1.98]) winrate black , white = 49.93% , 50.07%


■ 2022/04/13


- Scale child node futility pruning with previous move history. : https://github.com/official-stockfish/Stockfish/commit/8b4afcf8f7a38ee3060f39d563aad5956fe723d7
- Less futility pruning. : https://github.com/official-stockfish/Stockfish/commit/092b27a6d0174f619fff9a53099ac9fdc5c2cb4e
  // V701n

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701n_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,574 - 60 - 616(48.24% R-12.27[-28.84,4.3]) winrate black , white = 53.03% , 46.97%


- Reintroduce razoring
  - Reintroduce razoring : https://github.com/official-stockfish/Stockfish/commit/4d3950c6eb80c932af00f6495668d5c5adf3701b
  - Tune search at very long time control : https://github.com/official-stockfish/Stockfish/commit/84b1940fcae95bb0a641dda9e85cb96f8c21cd22

  Razoringは何年か前に簡略化されましたが、このパッチでは少し違った形で再導入されています。
  現在では、eval が alpha よりもずっと下にある場合、qsearch が alpha よりも上に押し上げることができるかどうかをチェックし、もしできなければ fail low を返します。

- Don't direct prune a move if it's a retake : https://github.com/official-stockfish/Stockfish/commit/93b14a17d168e87e7f05fc09e3ba93e737b0757e
  // V701m

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701m_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,633 - 53 - 654(49.18% R-5.67[-21.6,10.26]) winrate black , white = 52.06% , 47.94%


- Introduce post-lmr extensions :
  - https://github.com/official-stockfish/Stockfish/commit/c228f3196ae9965250f317c8784012c2485228c4
  // V701l

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701l_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,535 - 41 - 534(50.05% R0.33[-17.15,17.8]) winrate black , white = 54.35% , 45.65%


- lmr調整
  - Tune search at very long time control : https://github.com/official-stockfish/Stockfish/commit/84b1940fcae95bb0a641dda9e85cb96f8c21cd22

- Use complexity in search : https://github.com/official-stockfish/Stockfish/commit/7678d63cf2323e51c01e60cdff4ac3d685313790
  → これ、psq_scoreが必要だが、その計算してないから導入できない。

  // V701k

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701k_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,274 - 22 - 274(50.0% R-0.0[-24.39,24.39]) winrate black , white = 51.46% , 48.54%


- tuning LMR
  // V701j

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701j_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,337 - 23 - 290(53.75% R26.09[3.22,48.96]) winrate black , white = 50.08% , 49.92%


- tuning pruning parameters
  // V701i

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701i_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,359 - 30 - 301(54.39% R30.61[8.3,52.93]) winrate black , white = 54.24% , 45.76%


- tuning reduction parameters
  // V701h

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701h_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,805 - 89 - 806(49.97% R-0.22[-14.45,14.02]) winrate black , white = 53.69% , 46.31%


- remove singularQuietLMR
  - https://github.com/official-stockfish/Stockfish/commit/0889210262ab5a14bc6fcd261125b919120637a0
- remove Range reductions
- remove ss->ttPv = ss->ttPv && (ss + 1)->ttPv;
- clean up double extension
  // V701g
- tuning reduction parameters
  // V701h


				// Range reductions (~3 Elo)
				//
				// staticEvalとchildのeval(value)の差が一貫して低い時にreduction量を増やす。
				if (ss->staticEval - value < 30 && depth > 7)
					rangeReduction++;

		// Otherwise, a counter move has been found and if the position is the last leaf
		// in the search tree, remove the position from the search tree.

		// それ以外の場合は、カウンターの手が見つかり、その局面が探索木のleafであれば、
		// その局面を探索木から削除する。
		// (ttPvをfalseに変更してTTEntryに保存する)

		else if (depth > 3)
			ss->ttPv = ss->ttPv && (ss + 1)->ttPv;


engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701g_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,733 - 83 - 794(48.0% R-13.89[-28.52,0.75]) winrate black , white = 51.93% , 48.07%


- Improve transposition table remplacement strategy
  - https://github.com/official-stockfish/Stockfish/commit/94514199123874c0029afb6e00634f26741d90db
  // V701f


engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701f_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,165 - 13 - 142(53.75% R26.08[-6.58,58.74]) winrate black , white = 47.56% , 52.44%
  // 間違えてupdateしたほう

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701f2_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,820 - 83 - 807(50.4% R2.78[-11.39,16.94]) winrate black , white = 53.35% , 46.65%


- suisho5 embedded_nnue resource #228
  - Mizarさん、たややんさんからのプルリク。


- update comments
  - 探索部のコメントを更新。
  - 指し手に影響はない。


- ExplosionState削除
- doubleExtensionAverage削除
  // V701e

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701e_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,557 - 61 - 602(48.06% R-13.5[-30.29,3.3]) winrate black , white = 52.29% , 47.71%

- capture_or_pawn_promotion() → すべて capture()に変更 // V701d
  - 変数名、前のままだったところ修正。


engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701d_avx2.exe , eval = suishou6_20220114-fv32
T2,b2000,485 - 61 - 454(51.65% R11.47[-7.18,30.13]) winrate black , white = 52.29% , 47.71%

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701d_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1456 - 142 - 1402(50.94% R6.57[-4.12,17.26]) winrate black , white = 50.03% , 49.97%

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V701c_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,1451 - 141 - 1408(50.75% R5.23[-5.46,15.91]) winrate black , white = 49.63% , 50.37%


- capture_or_pawn_promotion() → すべて capture()に変更 // V701c
  - 計測誤差程度にしか変わらないので、Stockfishに倣い、capture()で統一する。
  - 変数名、前のままだったところ修正。

  探索で、capture(駒を捕獲する指し手)を別扱いする時に、capture() , capture_or_promotion() ,
  capture_or_pawn_promotion()の3択で、将棋ではcapture_or_pawn_promotion()の方が良いのではと
  長らく言われていたのだが(Aperyなど他のソフトがそういう工夫がなされていた)、どうやら
  最新のStockfishではcapture()で統一されたようで、計測してみたら将棋でもcapture()で良さそう
  (capture_or_pawn_promotionとは誤差程度にしか変わらない)。これは事件である。🤯 

engine1 = YaneuraOuNNUE_V701b_avx2.exe , eval = suishou6_20220114-fv32
engine2 = YaneuraOuNNUE_V701c_avx2.exe , eval = suishou6_20220114-fv32
T2,b1000,564 - 61 - 505(52.76% R19.2[1.7,36.69]) winrate black , white = 50.8% , 49.2%



■ 2022/04/12


- lowPlyHistory削除 // V701b
  - これ削除しても強さほぼ変わらなかった。

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028          , FV_SCALE = 24
engine2 = YaneuraOuNNUE_V701b_avx2.exe , eval = suishou6_20220114-fv32 , FV_SCALE = 32
T2,b1000,652 - 46 - 602(51.99% R13.86[-2.28,30.01]) winrate black , white = 52.47% , 47.53%

engine1 = YaneuraOuNNUE_V701a_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 24
engine2 = YaneuraOuNNUE_V701b_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 24
T2,b1000,457 - 54 - 449(50.44% R3.07[-15.91,22.05]) winrate black , white = 49.34% , 50.66%

engine1 = YaneuraOuNNUE_V701a_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 32
engine2 = YaneuraOuNNUE_V701b_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 32 lowPlyHistory削除
T2,b1000,1443 - 171 - 1386(51.01% R7.0[-3.74,17.75]) winrate black , white = 52.6% , 47.4%

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028     , FV_SCALE = 24
engine2 = YaneuraOuNNUE_V701a_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 32
T2,b1000,1487 - 146 - 1367(52.1% R14.62[3.91,25.32]) winrate black , white = 51.33% , 48.67%

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028     , FV_SCALE = 24
engine2 = YaneuraOuNNUE_V701a_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 24
T2,b1000,547 - 47 - 446(55.09% R35.46[17.24,53.68]) winrate black , white = 52.67% , 47.33%
// 水匠6では、FV_SCALE = 32のほうが強いっぽいな…。

engine1 = YaneuraOuNNUE_V700beta4.exe , eval = Suisho5_211028     , FV_SCALE = 24
engine2 = YaneuraOuNNUE_V701a_avx2.exe , eval = suishou6_20220114 , FV_SCALE = 16

T2,b1000,212 - 13 - 105(66.88% R122.06[88.01,156.1]) winrate black , white = 46.06% , 53.94%
// FV_SCALE=16、マジでクソ。



■ 2022/04/11


- remove -lcublas #227
	- Mizarさんからのプルリク。

- virturlenv: windows-2022 (#226)
	- Mizarさんからのプルリク。


- Visual Studio 2022の最新版に対応
	- 使用するPlatformToolset が v142 → v143 に
- Visual Studioのプロジェクトウィンドウで、bench.pyがscriptフォルダに入っていなかったの修正。


- Bitboard256::byte_reverse()、AVX2がない時の実装、AVX2用と互換性がなかった。
	- dlshogiの山岡さんからの指摘
	// 利きは正しく求まっているので気づかなかった。
- Bitboard256::byte_reverse()をUnitTestに追加。

2021年

■ 2021/12/23 V7.00


- やねうら王V7.00
	- 探索部、最新のStockfishに追随し、かつ探索パラメーターを調整した。(V6.00から+R40程度up)
	- 水匠5(NNUE)の評価関数内蔵型の実行ファイル追加。
	- 定跡ファイル2GB以上のものも取り扱えるようにした。
	- Qugiyのアルゴリズムを用いた飛び利きの高速化。(nps+5%程度up)
	- リンク時最適化。(nps+2%程度up)
	- FV_SCALE調整できるようにした。(これと合わせ、水匠5では前バージョンから+R100程度up)
	- スーパーテラショック定跡生成コマンド追加。
	- fコマンド追加。
	- Graviton2をARM NEON SIMD対応
	- ベンチマークの実行時間を一定にする改良
	- 学習時のテストロスの計算のスレッド並列処理をApery方式に変更し、高速化した
	- エンジンオプションのEvalDirで指定されたフォルタにある"eval_options.txt"でエンジン設定を読み込めるように。
	- eval_options.txtはdlshogiの設定ファイルと同じ形式で書けるようにした。
	- 定跡DB上に非合法手があると、その手を選択した場合、定跡にhitしなかった扱いになっていたのを修正。


■ 2021/12/18


- 32bit などの時に ftello64(), fseeko64() を使わない。 #221
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/221


- スーパーテラショック定跡化コマンド、循環をうまく取り扱うように修正。
- Position::is_reptitionに何手目前からの循環であるかを返す引数を用意。
- ftell64(),fseek64()追加。
	- 定跡ファイル、on the flyの時に32bit環境で2GB以上のファイルが扱えないのは仕様ということで。



■ 2021/12/16


- make clean $extra #220 (Mizarさんのプルリク)

EVAL_EMBEDDING=ON のような、ソースファイルの構成が変化する追加オプションを指定した場合、ビルド用スクリプトファイルから make clean を呼び出す時にその指定が欠けていたため、前のビルドで使われたオブジェクトファイルが掃除し切れていないケースがありました。(自動ビルド以外のケースにおいて)
例えば、EVAL_EMBEDDING=ON 付きでコンパイラ g++ , clang++ の両方でビルドする際、前のビルドで作られた embedded_nnue.o が残っていたためにリンカエラーを起こす事がありました。(ソースファイルのコンパイル時、オブジェクトファイルに付与されるLTOのヒント情報が g++, clang++ の間で互換性がないため。)


■  2021/12/11 Bitboard大改造計画その2 V7.00beta4


- V7.00beta4
	- nps+7%ぐらい速くなった
	- 方向利きを実装した
	- 利きのコード整理した
	- 使ってないテーブル、コメントアウトした
	- 離し角・飛車の1手詰めはコメントアウトした
	- cuckooのコード削除
	- リンク時最適化のオプションを指定するようにした
	- Bitboard(ZERO)廃止 Bitboard(0)を用いるように。
	- ALL_BB廃止。Bitboard(1)で代用。


- NNUEでLONG_EFFECT_LIBRARYをdefineした時に、コンパイルが通らなくなっていたのを修正。
- Bitboardのtable、関数経由でアクセスして欲しいものは、tableの方をnamespaceに入れた。
- Bitboard(ZERO)廃止 Bitboard(0)を用いるように。
- ALL_BB廃止。Bitboard(1)で代用。


- directEffectのコード、整理。
- rayEffectのtable、使っていないところを詰めてworking memoryを減らす。
- ZERO_BB廃止。
- mate1plyのコード、Bitboard::andnotが使えるところは用いる。
- around24_bbコメントアウト


- Bitboard::decrement() SSE4.1用のコード追加。
	- wainさん、Mizarさんのアドバイスによる。
- Bitboardの0クリアのコード、修正。
- 1手詰めルーチン、離し角・飛車での詰みを調べるのをやめる。
	- やめたほうが強い。離し角・飛車での詰み、そんなに出てこないので調べるコストに見合っていない。


- 方向利き(大駒の部分利き)実装

- ZERO_BBテーブル初期化以外では廃止。
- do_move()で王手している駒の更新に方向利きを使うように。nps+1%
- SEEでも次の候補の駒の更新に方向利きを使うように。nps+3%

- more_than_one() → Bitboard classに移動。
- Bitboard::pop_from_p0,p1を削除
	// pop()をp[0],p[1]に分けて片側ずつする用
	Square pop_from_p0() { u64 q0 = extract64<0>(); ASSERT_LV3(q0 != 0);  Square sq = Square(pop_lsb(q0)); insert64<0>(q0); return sq; }
	Square pop_from_p1() { u64 q1 = extract64<1>(); ASSERT_LV3(q1 != 0);  Square sq = Square(pop_lsb(q1) + 63); insert64<1>(q1); return sq; }


■  2021/12/10 Bitboard大改造計画


- do_move()の時に王手してる駒を更新するコード、少し高速化


- cuckoo algorithmのコード削除。

#if defined(CUCKOO)
// Marcel van Kervinck's cuckoo algorithm for fast detection of "upcoming repetition"
// situations. Description of the algorithm in the following paper:
// https://marcelk.net/2013-04-06/paper/upcoming-rep-v2.pdf

// Stockfishの2倍の配列を確保

// First and second hash functions for indexing the cuckoo tables
inline int H1(Key h) { return h & 0x3fff; }
inline int H2(Key h) { return (h >> 16) & 0x3fff; }

// Cuckoo tables with Zobrist hashes of valid reversible moves, and the moves themselves
Key cuckoo[8192*2];
Move cuckooMove[8192*2];

//  → cuckooアルゴリズムとやらで、千日手局面に到達する指し手の検出が高速化できるらしい。
// (数手前の局面と現在の局面の差が、ある駒の移動(+捕獲)だけであることが高速に判定できれば、
//  早期枝刈りとしてdraw_valueを返すことができる。)
#endif

#if defined(CUCKOO)
	// Prepare the cuckoo tables
	std::memset(cuckoo, 0, sizeof(cuckoo));
	std::memset(cuckooMove, 0, sizeof(cuckooMove));
	int count = 0;
	// 重複カウント用
	int count2 = 0;
	for (auto pc : Piece())
	{
		auto pt = type_of(pc);
		if (!(pt == PAWN || pt == LANCE || pt == KNIGHT || pt == SILVER || pt == GOLD || pt == BISHOP || pt == ROOK || pt == KING
			|| pt == PRO_PAWN || pt == PRO_LANCE || pt == PRO_KNIGHT || pt == PRO_SILVER || pt == HORSE || pt == DRAGON))
			continue;

		// 将棋だとチェスと異なり、from → toに動かせるからと言ってto→fromに動かせるとは限らないので
		// ここのコード、ずいぶん違ってくる。
		for (auto s1 : SQ)
			for (Square s2 : SQ)
				if (effects_from(pc, s1, ZERO_BB) & s2)
				{
					Move move = (Move)(make_move(s1, s2) + (pc << 16));
					// 手番のところ使わない。無視するために潰す。
					Key key = (Zobrist::psq[s2][pc] - Zobrist::psq[s1][pc]) >> 1/* Zobrist::side*/;
					int i = H1(key);
					while (true)
					{
						std::swap(cuckoo[i], key);
						std::swap(cuckooMove[i], move);
						if (move == MOVE_NONE) // Arrived at empty slot?
							break;

						//i = (i == H1(key)) ? H2(key) : H1(key); // Push victim to alternative slot
						// → これ、テーブル小さいので衝突しつづける…(´ω`) H1になかったらH2でええで..

						i = H2(key);
						std::swap(cuckoo[i], key);
						std::swap(cuckooMove[i], move);

						if (move != MOVE_NONE)
							count2++;

						break;
					}
					count++;
				}
	}
	//assert(count == 3668); // chessの場合

	// cout << "count = " << count << " , count2 = " << count2 << endl;
	// chessの2倍の配列時 : count = 16456 , count2 = 4499 
	// chessの4倍の配列時 : count = 16456 , count2 = 1623
	ASSERT_LV3(count == 16456);
#endif

#if defined(CUCKOO)
// この局面から以前の局面に到達する指し手があるか。
// ply : 遡る手数
bool Position::has_game_cycle(int plies_from_root, int rep_ply /*= 16*/) const
{
	int j;

	int end = std::min(/* st->rule50*/ rep_ply , st->pliesFromNull);

	if (end < 3)
		return false;

	Key originalKey = st->key();
	StateInfo* stp = st->previous;

	for (int i = 3; i <= end; i += 2)
	{
		stp = stp->previous->previous;

		// やねうら王ではZobrist Hashに足し算を使っているので、差を取る必要がある。
		// bit 0はside(手番)なので、ここは削る。
		Key moveKey = (stp->key() - originalKey) >> 1;
		if ((j = H1(moveKey), cuckoo[j] == moveKey)
			|| (j = H2(moveKey), cuckoo[j] == moveKey))
		{
			Move move = cuckooMove[j];
			Square s1 = from_sq(move);
			Square s2 = to_sq(move);
			Piece pc = (Piece)(move >> 16);
			if (piece_on(s1) != pc)
				continue;

			// 間に駒がないのでたぶんいける。開き王手とか知らん。
			// ざっくりした枝刈りにしか使わないのでこのへんの判定甘くても問題ない。

			// あと、連続王手による千日手到達に関してはdraw_value返すのはやめたほうが…。
			// これは、rating下がりうる。王手の指し手ではないことを条件に含めないと。

			if (!(between_bb(s1, s2) & pieces()))
			{
				if (plies_from_root > i)
					return true;

				// For repetitions before or at the root, require one more
				// rootまでに指し手が見つかった場合、もう一度同じ局面に遭遇する必要がある。

				// Stockfish10のコード
				//if (stp->repetition)
				//	return true;

				// Stockfish9の時のコード。(StateInfo->repetitionを持っていないのでこんなコードになる)
				StateInfo* next_stp = stp;
				for (int k = i + 2; k <= end; k += 2)
				{
					next_stp = next_stp->previous->previous;
					if (next_stp->key() == stp->key())
						return true;
				}

			}
		}
	}
	return false;
}
#endif

#if defined(CUCKOO)
	// この局面から以前と同一局面に到達する指し手があるか。
	// plies_from_root : rootからの手数。ss->plyを渡すこと。
	// rep_ply         : 遡る手数。デフォルトでは16手。あまり大きくすると速度低下を招く。
	bool has_game_cycle(int plies_from_root , int rep_ply = 16) const;
#endif


		// 【計測資料 34.】cuckooコード Stockfishの2倍のサイズのcuckoo配列で実験

#if defined(CUCKOO)
		// この局面から数手前の局面に到達させる指し手があるなら、それによって千日手になるので
		// このnodeで千日手スコアを即座に返すことで早期枝刈りを実施することができるらしい。

		// Check if we have an upcoming move which draws by repetition, or
		// if the opponent had an alternative move earlier to this position.

		Value ValueDraw = draw_value(REPETITION_DRAW, pos.side_to_move());
	    if (   !rootNode
	        && pos.rule50_count() >= 3
	        && alpha < VALUE_DRAW
			&& pos.has_game_cycle(ss->ply))
		{
			alpha = value_draw(pos.this_thread());
			if (alpha >= beta)
				return alpha;

			/*
				将棋では、1手あれば現局面よりプラスになる指し手がほぼ確実に存在するであろうから、
				4+2n手前の局面に戻る指し手があるからと言って、draw_valueを返すのは、もったいない意味が。
				
				手番の価値(Eval::Turn)を返すのはありかな?

				あと、連続王手による千日手到達に関してはdraw_value返すのはやめたほうが…。
				これは、rating下がりうる。戻る指し手が王手ではないことを条件に含めないと。
			*/

		}
#endif


- Bitboard(ZERO)でZERO_BBを作れるようにする。(こっちの方が少し速い)


- SSE2用でコンパイルエラーになっていた件を修正。
	- _mm_extract_epi64()命令がSSE4.1用らしい。
	- しかし、SSE2以上であるなら、Bitboardはu64 p[2];ではなく、 __m128i m; のように メンバを持っている。
		このmの上位64bit / 下位64bitにアクセスする手段がSSE2だと_mm_extract_epi64()が使えなくて困るのだ。
	// これやっぱりunionで持ってないといけないのか…。困る。


■  2021/12/06 V7.00beta3


- Bitboard、SSE2環境以降で unionで __m128iを持つのをやめる。(これのせいで最適化が阻害されている気がする)
	- ベンチ上、わずかに改善されている気もするが、計測誤差かも。
  → V700beta3cとする

beta3c

===========================
Total time (ms) : 60028
Nodes searched  : 166955526
Nodes/second    : 2781294
Nodes searched(main thread) : 20889671
Nodes/second  (main thread) : 347998

Total time (ms) : 60050
Nodes searched  : 165558516
Nodes/second    : 2757011
Nodes searched(main thread) : 20946295
Nodes/second  (main thread) : 348814

Total time (ms) : 60047
Nodes searched  : 163629255
Nodes/second    : 2725019
Nodes searched(main thread) : 20027319
Nodes/second  (main thread) : 333527


beta3b

8スレ
===========================
Total time (ms) : 60037
Nodes searched  : 162200384
Nodes/second    : 2701673
Nodes searched(main thread) : 20458054
Nodes/second  (main thread) : 340757

Total time (ms) : 60048
Nodes searched  : 161191551
Nodes/second    : 2684378
Nodes searched(main thread) : 19914801
Nodes/second  (main thread) : 331648

===========================
Total time (ms) : 60040
Nodes searched  : 161141475
Nodes/second    : 2683901
Nodes searched(main thread) : 20146055
Nodes/second  (main thread) : 335543

Total time (ms) : 60029
Nodes searched  : 163597833
Nodes/second    : 2725313
Nodes searched(main thread) : 20255088
Nodes/second  (main thread) : 337421


beta3
8スレ
===========================
Total time (ms) : 60053
Nodes searched  : 160888802
Nodes/second    : 2679113
Nodes searched(main thread) : 20083341
Nodes/second  (main thread) : 334426

===========================
Total time (ms) : 60027
Nodes searched  : 165840400
Nodes/second    : 2762763
Nodes searched(main thread) : 21276742
Nodes/second  (main thread) : 354452

===========================
Total time (ms) : 60039
Nodes searched  : 154349589
Nodes/second    : 2570822
Nodes searched(main thread) : 19438701
Nodes/second  (main thread) : 323767



- リンク時最適化 #218
	- https://github.com/yaneurao/YaneuraOu/pull/218 (Mizarさんのプルリク)
	- 2%ぐらいnpsアップ。
 →  V7.00beta3bとする

- V7.00beta3

	- NUMAでうまくスレッドが使えていなかった環境でうまく動いていることが確認された。(Komafontさんから)
		- Revert and fix earlier windows NUMA patch のcommitで。

		OS Name: Microsoft Windows 10 Pro
		Version: 10.0.19041 Build 19041
		Processor: AMD Ryzen Threadripper 2950X 16-Core Processor, 3500 Mhz, 16 Core(s), 32 Logical Processor(s)

	- BookOnTheFlyで定跡hitしなかったの修正されてる。(たぶん)

	- Qugiyの利きを導入してmagic bitboardのコードを完全除去
		- Core i7 , Surface Pro6 8スレッドで+1%程度nps上がった。
		- ZEN2 , 128スレッドで+2%程度nps上がった
		- ZEN3 , 16スレッドで -2%程度nps下がった
		- ZEN3 , 128スレッド → 未計測
		- まとめ :
			- 1手詰めルーチン高速化、attackers_toなどのtemplate化で+1%ぐらいnpsアップ。
			- 香の利きと歩の打てる場所の高速化で1%ぐらいnpsアップ(Qugiyのアルゴリズム)
			- 角の利きはZEN3やIntel系では1%ぐらいnpsダウン。(Qugiyのアルゴリズム)
			- 飛車の利きもZEN3やIntel系では0.5%ぐらいnpsダウン。(Qugiyのアルゴリズム)
			- トータルとしては、悪化していないし、
				magic bitboardとPEXT bitboardのコードが完全に除去できているし、
				利きのテーブルサイズが大幅に縮んだことにより128スレッドのような
				many threadsでメモリ帯域が問題となる環境の場合、高速化が期待できるのでこれで良しとする。



■  2021/12/05


- BookOnTheFlyでtellg()を使わずにファイルポジションを時前で算出するように修正。


- BookOnTheFlyで二分探索が正しく行われないバグを修正した #217
	- https://github.com/yaneurao/YaneuraOu/pull/217 (たぬきさんのプルリク)

nodchip@tanuki- — 今日 20:54
軽く printf デバッグをした のですが、 current_pos() が、ストリームから最後に読み取った位置より、少し先を指しているように見えます。

info string s=21290C7 m=2129511 e=212995B
next_sfen(): seek_from=2129511
line= 0 1
line=9c9d 7g7f 0 0 1
line=sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B3S1R1/LNSGKG1NL w - 2
info string lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B3S1R1/LNSGKG1NL w - 2
current_pos(): fs.tellg()=61C7E640 file_start=61C7E630
info string Go to right. current_pos()=21295D0
current_pos(): fs.tellg()=61C7E640 file_start=61C7E630

printf デバッグの出力の一部をコピペしたものです。定跡ファイルの [0x21290C7 バイト目, 0x212995B バイト目) を調べています。その中点は 0x2129511 バイト目です。 next_sfen() に 0x2129511 を渡し、「sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B3S1R1/LNSGKG1NL w - 2」という行が得られました。このタイミングで current_pos() を呼んだところ、  0x21295D0 が返ってきました。ところがこの場所は、「sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B3S1R1/LNSGKG1NL w - 2」の次の行の先頭より、だいぶ先を指しています。参考までに「sfen lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B3S1R1/LNSGKG1NL w - 2」の次の行の先頭は、0x212956E でした。
tellg() が返す値が、 VS2019 と MSYS2 + g++ とで異なっているということなのだと思います。



- Revert and fix earlier windows NUMA patch
	- https://github.com/official-stockfish/Stockfish/commit/7218ec4df9fef1146a451b71f0ed3bfd8123c9f9

	> Revert and fix earlier windows NUMA patch
	> revert 9048ac0 due to core spread problem and fix new OS compatibility with another method.

	以前のWindows NUMAパッチを元に戻して修正
	9048ac0のコア分散問題を元に戻し、新しいOSとの互換性を別の方法で修正しました。

- Do more aggressive pruning for some node types
	- https://github.com/official-stockfish/Stockfish/commit/e4b7403f127a36a35bbace9f833ab43babd98a6c

	Enable compilation on older Windows systems
	Improve compatibility of the last NUMA patch when running under older versions of Windows,
	for instance Windows Server 2003. 

	古いWindowsシステムでのコンパイルを可能にする
	旧バージョンのWindows上で動作するNUMAパッチの互換性を向上させました。
	最後のNUMAパッチの互換性を向上させます(Windows Server 2003など)。


■ 2021/12/03


- Bitboard::decrement()で使っている命令、SSE4.1以降の命令であったのでifdef修正。
	USE_SSE41 for _mm_add_epi64 #216
	- https://github.com/yaneurao/YaneuraOu/pull/216 (Mizarさんのプルリク)



- WriteDebugLogオプションで以前の(チェックボックスの)ままFalseを代入してくるGUIに対して、
	Falseが指定されている時にファイルは書き出さないように。Trueが指定されていれば"io_log.txt"に
	書き出すようにした。
- StringExtension::ToUpper()追加。


- Bitboard512::byte_reverse()がifdef無効にしたままだったの修正。
	- 以前のコードと同等ぐらいにはなった。

===========================
Total time (ms) : 60040
Nodes searched  : 162063034
Nodes/second    : 2699251
Nodes searched(main thread) : 20570836
Nodes/second  (main thread) : 342618



- Bitboardの利きの初期化コード、整理した
- magic bitboardのtableが残っていたので掃除した。


- 角・飛車の利きにQugiyのアルゴリズムを導入し、magic bitboardを使わないようにした。
- magic tableの初期化が不要になって、起動が少し速くなった。
- 香の利きのコード、足し算でなく引き算を使うように変更。
- BitboardのUnitTestに、利きのテストを追加。
- bswap64のコード、Mizarさんに書いたのもらった。
- Bitboard::unpack(),Bitboard::decrement()追加
- エンジンオプションの"WriteDebugLog"の説明を USI拡張コマンド.txt に追記。
- 角の利きのコード、Qugiyの利きアルゴリズムを導入。
- Bitboard256::unpack(),Bitboard256::decrement,Bitboard256::merge()を追加。

///////////////////////////////////////////////
  大駒の利きの実装に関して、
  Qugiyの作者の森さん、CGPのwainさん、Mizarさんに
  大変お世話になりました。ありがとうございます。
///////////////////////////////////////////////

以下、
bench 1024 1
bench 1024 8
の結果。Surface Pro6で計測。

// 角の利き、1スレだとむしろ遅くなっているが、この環境、AVX256が遅いのだと思う。

・Qugiyの飛車・角の利きコード導入

// 1スレ
===========================
Total time (ms) : 60040
Nodes searched  : 42965064
Nodes/second    : 715607

===========================
Total time (ms) : 60031
Nodes searched  : 43189598
Nodes/second    : 719454

// 8スレ

===========================
Total time (ms) : 60038
Nodes searched  : 158268802
Nodes/second    : 2636143
Nodes searched(main thread) : 19002682
Nodes/second  (main thread) : 316510

===========================
Total time (ms) : 60039
Nodes searched  : 161386424
Nodes/second    : 2688026
Nodes searched(main thread) : 20355963
Nodes/second  (main thread) : 339045


・Qugiyの飛車の利きコード導入(角は前のまま)

// 1スレ
===========================
Total time (ms) : 60043
Nodes searched  : 43571370
Nodes/second    : 725669

===========================
Total time (ms) : 60032
Nodes searched  : 43542455
Nodes/second    : 725320

===========================
Total time (ms) : 60025
Nodes searched  : 43388836
Nodes/second    : 722846

// 8スレ
===========================
Total time (ms) : 60037
Nodes searched  : 161223118
Nodes/second    : 2685395
Nodes searched(main thread) : 20611811
Nodes/second  (main thread) : 343318

===========================
Total time (ms) : 60036
Nodes searched  : 162226247
Nodes/second    : 2702149
Nodes searched(main thread) : 20152300
Nodes/second  (main thread) : 335670


・以前のコード
===========================
Total time (ms) : 60029
Nodes searched  : 41541531
Nodes/second    : 692024

===========================
Total time (ms) : 60022
Nodes searched  : 42866963
Nodes/second    : 714187

// 8スレ
===========================
Total time (ms) : 60040
Nodes searched  : 167172767
Nodes/second    : 2784356
Nodes searched(main thread) : 21334570
Nodes/second  (main thread) : 355339

===========================
Total time (ms) : 60046
Nodes searched  : 163801397
Nodes/second    : 2727931
Nodes searched(main thread) : 19962799
Nodes/second  (main thread) : 332458


■ 2021/12/02


- 香の利きのコード、足し算でなく引き算を使うように変更。
- BitboardのUnitTestに、利きのテストを追加。
- bswap64のコード、Mizarさんに書いたのもらった。


- start_logger()の引数がboolから`std::string`に変更されたが、WriteDebugLogオプションのデフォルト値が`false`のままだったため、デフォルトではデバッグログがファイル名`false`に常に書き出されていた。
	- https://github.com/yaneurao/YaneuraOu/pull/215 (Mizarさんのプルリク)

https://github.com/yaneurao/YaneuraOu/commit/fa10bc3ad096c265041fbfe82f7259bcfc5aa680#diff-56d0745227250f49421f61a56de172b8b68624734977a6ff2c8f4a5fd67d0ba2L120-R131


■ 2021/12/01


- 飛車の縦利きを求めるコード、表引きをやめる。
	- 速くはなってないかも知れないが、余計な表引きが減るのでまあいいや。


- unittestの指し手生成祭りのperftの値が間違っていたの修正。
- 香の利き、1~7筋と8~9筋とで処理を分けた。


- 評価関数埋め込み対応、HalfKPvmビルド対応など #214(Mizarさんのプルリク
	- https://github.com/yaneurao/YaneuraOu/pull/214

	TensorRTのバージョン取得、ヘッダ埋め込み定数ではなく getInferLibVersion() を参照
	ビルド時に参照したTensorRTのバージョンではなく、実行時に読み込まれたTensorRTのダイナミックリンクライブラリのバージョンを参照してシリアライズ化ファイルのファイル名を決定するため。
	VisualC++でのソースコード読み込みにて、UTF-8の文字セットを既定に
	CUDA/TensorRT関連のビルド時に、インクルードファイルを別の文字セットとして読み込んで警告が出ていたため。
	Make CI (DeepLearning for Ubuntu Linux) ビルドにてビルド環境にインストールするパッケージを削減
	Deep-TensorRT ビルドにて使用する TensorRT のバージョンを 8.2.1 GA に変更
	dllの環境変数等による読み込み順の影響を低減するため、ビルド時に関連するdllを極力実行ファイルと同じフォルダに配置するよう設定。
	ONNX Runtime NuGetパッケージの更新、ORT-CUDA 廃止、ORT-TRT 対応。
	ORT-TRTはORT無しのTensorRTビルドより若干遅く、挙動も若干特殊ですが、自動ビルド対応が容易となります。
	USIオプションを16GPUまで対応
	NNUE評価関数の実行バイナリ埋め込みに対応、水匠5評価関数実行バイナリ埋め込み版のリリースビルド対応
	HalfKPvmのビルド対応
	Android NDK を最新のLTS版に変更
	明示的にストリームを作成しないで、Per-thread default stream(cudaStreamPerThread)を使う
	TadaoYamaoka/DeepLearningShogi@3d408cc の取り込み


■ 2021/11/30 V700beta2


- V700beta2

engine1 = YaneuraOuNNUE_V700beta2.exe , eval = Suisho5_211028
engine2 = YaneuraOuNNUE_V700beta1.exe , eval = Suisho5_211028
T2,b1000,1450 - 170 - 1380(51.24% R8.6[-2.15,19.34]) winrate black , white = 53.22% , 46.78%
T2,b2000,920 - 155 - 925(49.86% R-0.94[-14.24,12.36]) winrate black , white = 52.41% , 47.59%
T2,b4000,452 - 99 - 439(50.73% R5.07[-14.07,24.21]) winrate black , white = 54.43% , 45.57%
Quiet ttMove extensionsの修正と高速化で、弱くはなってなさそう。



■ 2021/11/29


- Mate1plyのコードまわり、templateをかなり導入した。


- _mm_shuffle_epi8はSSE3の命令らしくSSE2用のビルドが失敗していたの修正。


- Qugiyの香の利きを実装した時に差し替えた歩の利きの初期化コード、バグっていたの修正。
	- これで落ちなくなった。よかった。
- MoveGenに対してassert増した。
- attackers_toなどtemplate版の利きを使うようにした。


- 起動時に startup_info.txt があれば、それを出力する。
	- 開発時にfコマンドによるマクロの説明などを書いておくのに便利。
- bitboard.cpp、SSE2なし環境でコンパイル通ってなかったの修正。


- attackers_to(Square sq, const Bitboard& occ)、利きをtemplate版の方を呼ぶようにした。
	- 少しだけ高速化。
- byte_reverse()、g++だとコンパイル通ってなかった。
	- MOVBE自体、対応してないCPUわりとあるようで、使わないほうが無難。
	- https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
	- byte_reverse()削除。

// ----------------------------
//    byte reverse
// ----------------------------

// 書いてみたものの、この速度なら使う価値がないと思う。

// 32bitの値をbyte単位で逆順にして返す。
// byte_reverse()から64bit環境でない時に呼び出される。
inline u32 byte_reverse32(u32 u)
{
//#if defined(__GNUC__) && !defined(IS_64BIT)
	// GCCはこのマクロが定義されているはず。
	//return _loadbe_i32(&u);
	//
	// 	→ MOVBE命令が実装されている環境(SSE3以降?)でないと使えないようだ。
	// 
//#else
	// それ以外なのでどうしようもない。
	// これ遅いから使わないほうがいいと思う。
	return ((u&0xff000000)>>24) | (((u&0x00ff0000)<<8)>>16) | (((u&0x0000ff00)>>8)<<16) | ((u & 0x000000ff) << 24);
//#endif
}

// 64bitの値をbyte単位で逆順にして返す。
inline u64 byte_reverse(u64 u)
{
//#if (defined(_WIN64) && defined(_MSC_VER)) || (defined(__GNUC__) && defined(IS_64BIT))
#if defined(_WIN64)

#if !defined( __clang__ ) 
	return _load_be_u64(&u); // MSVCとg++はこのマクロが定義されているはず?Clangで存在しない模様。
#else
	return _loadbe_i64(&u);  // こう書けばMSVCとClangでコンパイル通る模様。でもg++でコンパイルが通らない。
#endif

#else 
	// 下位4バイトを逆順にして上位へ。上位4バイトを逆順にして下位へ。
	return ((u64)byte_reverse32((u32)u) << 32) | (u64)byte_reverse32((u32)(u >> 32));
#endif
}



- Quiet ttMove extensions修正。

			else if (   PvNode
				&& move == ttMove
				&& move == ss->killers[0]
				&& (*contHist[0])[to_sq(move)][movedPiece] >= 10000)
				extension = 1;

	このcontHist[0]の[]内、1つ目と2つ目が入れ替わっていた。(Stockfishからやねうら王に持ってくる時、ここ入れ替えないといけないので注意)


- engine_options.txt、TextReaderを用いて読み込むように変更。
	- 以前のコードだとutf-8のBOMがついていると読み込めていなかった。


- Bitboard256、AVX2命令使ってあるのにUSE_SSE2になっていたの修正。
	- SSE2用のビルドに失敗していた。


- Clangでビルドエラーになっていたの修正。
	- ひとつ前のcommitの_load_be_u64()、Clangだと_loadbe_i64と書かないといけないようだった。


- 角と飛車の飛び利きをmagic bitboardを用いないで実現する作業、途中でgive upしたので作業途中まで反映。
	- Qugiyのコードに似た考えかた。
		- Qugiyの作者に色々教えていただきました。ありがとうございます。
	- Bitboard256みたいなclassを作って、そのclassの演算子だけで実装する。
		- Bitboard256のclassの実装に関して、wain_CGPさんに色々教えていただきました。ありがとうございます。
	- Bitboard512があれば、角の4方向の利きは並列的に求められる。
	- 飛車の利きは、上方向がshuffleでbyte単位で逆順にした時に、升が逆順に並ばないから求まらない。
		- Qugiyもここは先手の香の利きを合成している。

	- 角の利きをBitboard256 classで

	Bitboard256という、Bitboardを2つ連結させたclassを用意した。
	また、Bitboard::byte_reverse()というbyteで逆順にしたBitboardを返すメソッドを追加した。
	あとwainさんに教えていただいたSIMDでymmレジスタに対して128bit×2のaddを行うテクニックを用いて、Bitboard256::add128()を実装する。(まだしていない)

	これらを用いて、角の利きを計算することは出来るはず。(私の理解が間違っていなければ)
	ところが、byte_reverse()するのにMOVBEすらない環境だとbyteを入れ替えるだけでも大変なので、magic bitboardを用いるより遅くなる。(計測していない。あくまで予想)

	そのため、AVX2が使える環境に限定した方がいいような気はしている。問題は、ZEN2のようなPEXTが激遅である環境以外で高速になるのかどうかである。
	せめてmagic bitboardと同じぐらいの速度(1%程度の速度低下は可)であるなら、これを使うことにしてmagic bitboardの実装を削除できる。
	しかしその場合でもMOVBEが使えない環境のためにmagic bitboardの実装を残しておかないといけないかもしれない。

	正直、magic bitboard(PEXTありとなし)の実装と、Bitboard256の実装(AVX2ありとなし)と、byte_reverse(MOVBEありとなし)とこの3つを同時に保守していくのは避けたいところである。

	WCSC32では、AWSのc6i.32xlarge(128 vCPU)を使うとしてこれ、
		最大 3.5 GHz の第 3 世代インテル Xeon スケーラブルプロセッサー
	と書いてあるのでPEXT、遅くない。

	そんなわけで、飛び利きのコード、刷新してもこの環境で速くなるかどうか怪しいので、ここで一旦作業を保留しておく。


■ 2021/11/28


- Androidのclangなどでビルドが通らなくなっていたの修正。
	- attackers_toをtemplate化した時に、.cppから.hに移動させてなかったから、
		C++ templateの扱いがinclusion modelだとコンパイル通らないのだった。


- SSEなし環境でビルドが通らなくなっていたの修正。
	- andnot()実装した時に、SSEなしの時の関数名をand_notとしてしまっていた。
	- 古い利きのコードと間違えて掃除してしまっていた。
- 古い利きのコード、掃除。



■ 2021/11/26 V7.00beta


- Handに対するoperator<<の出力先が正しくない問題を修正 #213(komori-nさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/213


- Position::UnitTestに指し手生成祭りのperft追加。
- 一つ前のcommitでまだコンパイルエラーになっていたの修正。


- yo_cluster.cppが非Windows環境用にビルドした時にコンパイルエラーになっていたの修正。


- Qugiyの飛び利きのコードを移植その2。
	- 二歩になる升のBitboardをbit演算で得るコードを実装。

- Position::set_check_infoをtemplate化。
	template <bool doNullMove , Color Us>
	void Position::set_check_info(StateInfo* si) const;

- Position::attackers_to()をtemplate化して先後分けた。
- 駒の利き関連のコード、先後をtemplate化して分けた。


- Qugiyの飛び利きのコードを移植その1。香の飛び利き、先後。
	- cf.WCSC31 Qugiy アピール文書 : https://www.apply.computer-shogi.org/wcsc31/appeal/Qugiy/appeal.pdf
	- 最終的に全部盛りで、ZEN2で4%ぐらい速くなるらしい。
- PositionにperftのUnitTest追加。
- pawnEffect,lanceEffectなどtemplate化。
- Bitboardにandnotなど追加。
- PawnEffect(Bitboard)紛らわしいのでPawnBbEffectと改名。


		//Square sq = SQ_21;
		//Bitboard occ(SQ_27);
		Square sq = SQ_11;
		Bitboard occ(SQ_17);
		cout << lanceEffect<WHITE>(sq, occ);


// やねうら王の従来の遠方駒の利きを求めるコードを用いる。
// これをundefするとApery型の利きのコードを用いる。(そっちのほうがPEXTが使えない環境だと速い)
// 互換性維持および、55将棋のように盤面を変形させるときに、magic tableで用いるmagic numberを求めたくないときに用いる。

// #define USE_OLD_YANEURAOU_EFFECT
→ 削除


- やねうら王 V7.00beta


- HASH_KEY_BITS、Makefileの方から変更できるようにした。
	- スーパーテラショック定跡を生成するとき128を指定してコンパイルした実行ファイルを使いたい。


- やねうら王TheClusterその1(まだ書きかけ)


- "test evalsave"コマンド復活。これがないと空の評価関数ファイルを作る時に困るのだった。
	- たまさんからの指摘。


- ふかうら王のエンジンオプションに以下の6パラメーターを追加。(dlshogiにあるのと同じ意味)
	C_fpu_reduction , C_fpu_reduction_root , C_init , C_base, C_init_root , C_base_root

- dlshogiのモデルの設定ファイルと互換性をもたせる。

第2回世界将棋AI電竜戦エキシビジョンバージョン
https://github.com/TadaoYamaoka/DeepLearningShogi/releases/tag/dr2_exhi

// 以下のパラメーターをふかうら王に追加し、dlshogiと同じ設定ファイルが使えるようにする。

	C_init=127
	C_base=27126
	C_fpu_reduction=31
	C_init_root=112
	C_base_root=33311
	Softmax_Temperature=140

dlshogiは、モデルファイル名が model-dr2_exhi.onnx の時、model-dr2_exhi.onnx.ini にオプション設定を書けるようになっている。
やねうら王は、EvalDirで指定したフォルダのなかにある eval_options.txt にオプション設定を書けるようになっている。
// よって、dlshogiの model-dr2_exhi.onnx.ini を、やねうら王の eval/eval_options.txt にコピーすればそのまま動く。

- engine_options.txt , eval_options.txt は、
1. option name UCT_Threads1 type spin default 2 min 0 max 256 のような形式("usi"コマンドに対してエンジンが返してくる形式)
2. オプション 値
3. オプション名=値
の3通りの書き方ができるようにした。(以前は、1.と2.だけサポートしていた。今回dlshogiの.iniを読み込むために3.の形式をサポートすることにした)


- NNUEのエンジンオプションにFV_SCALE追加。
	- 水匠5ではFV_SCALE = 24にしたほうが強いらしいので。


■ 2021/11/25


- やねうら王探索パラメーター刷新。(+R15)


- やねうら王探索、capturesSearchedに追加する条件、調整。(+R10)


- 王手延長の条件を調整する。
	- たややんさんからの報告。

	// 将棋では王手はわりと続くのでStockfishのコードは明らかにやりすぎ。
	else if (   givesCheck
				&& depth > 6
				&& abs(ss->staticEval) > 100)
		extension = 1;

	以下のようにする。

	// 王手延長は、開き王手と駒得しながらの王手に限定する。
	else if (givesCheck
		&& depth > 6
		&& abs(ss->staticEval) > 100)
		&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
		extension = 1;


- TensorRT: 転送・推論を非同期に行う #211 (Mizarさんのプルリク)

	cudaStream_t stream はこのPRではGPUごとに持っていますが、推論自体を並列に行いたい時は context, stream, inputDims1, inputDims2, x1_dev, x2_dev, y1_dev, y2_dev などは探索スレッドごとに持つように変更した方が良いかもしれません。(推測であり未確認)

	参考:
	ふかうら王 アピール文章
	https://drive.google.com/open?id=1aO0gLSYvhph1uL_gaaohLYWTMpe1BdA8



- NNUEにHalfKP_vmの評価巻数を追加 #212
	- https://github.com/yaneurao/YaneuraOu/pull/212 (tanuki-さんのプルリク)
	- @nodchip : 第 2 回世界将棋 AI 電竜戦本戦で「タヌキの為に鐘は鳴る」が採用した、HalfKP_vm の PR です。よろしくお願いいたします。


	* HalfKP_vmを追加した

	# Conflicts:
	#	source/YaneuraOu.vcxproj.filters

	* halfkp_vm_256x2-32-32.hを追加した

	# Conflicts:
	#	source/YaneuraOu.vcxproj
	#	source/eval/nnue/nnue_architecture.h

	* HalfKP_vmの駒インデックスの誤りを修正した

	* Makefileでhalfkp_vm_256x2-32-32を指定できるようにした

	# Conflicts:
	#	source/Makefile

	# Conflicts:
	#	source/Makefile
	#	source/eval/nnue/nnue_architecture.h



■ 2021/11/17


- 王手延長の条件を調整する。
	- たややんさんからの報告。

	// 将棋では王手はわりと続くのでStockfishのコードは明らかにやりすぎ。
	else if (   givesCheck
				&& depth > 6
				&& abs(ss->staticEval) > 100)
		extension = 1;

	以下のようにする。

	// 王手延長は、開き王手と駒得しながらの王手に限定する。
	else if (givesCheck
		&& depth > 6
		&& abs(ss->staticEval) > 100)
		&& (pos.is_discovery_check_on_king(~us, move) || pos.see_ge(move)))
		extension = 1;



V650k

- Simplify Pv nodes related logic in LMR : https://github.com/official-stockfish/Stockfish/commit/f5df517145890ecee3d855e98470241b68645b87
- Simplify LMR multiThread condition : https://github.com/official-stockfish/Stockfish/commit/1163d972a9a1e480d9130c5fabbf869cdb7f7ecb


V650j

- Time-management fix in MultiPV mode. : https://github.com/official-stockfish/Stockfish/commit/371b522e9ed9cab91274ff111c0bf4b0f6ec3340
	- MultiPVでtime managementがおかしかった原因。
- More futility pruning : https://github.com/official-stockfish/Stockfish/commit/11c6cf720d4cdd882bc0f2c36e25910cf77fb57b
- Simplify multi-cut condition : https://github.com/official-stockfish/Stockfish/commit/673841301b0cc6ed78c4db3e6ec2a0b9a010c8cb


V650i

- Increase TTdepth acceptance some Threads : https://github.com/official-stockfish/Stockfish/commit/927a84d310fb41222518ea80d398933a0ba3e5b7

- Extend quiet tt moves at PvNodes : https://github.com/official-stockfish/Stockfish/commit/21ad356c0900c9eba9b7b1f7453f934eab80f303
	- PV nodeで quietなttは良い指し手のはずだから延長するというもの。

- ソースから取り除く
	// Last captures extension

	// 最後に捕獲した駒による延長
	// 捕獲した駒の終盤での価値がPawnより大きく、詰みに直結しそうなら延長する。
	// 将棋では駒は終盤で増えていくので関係なさげ。

	//else if (PieceValue[EG][pos.captured_piece()] > PawnValueEg
	//	&& pos.non_pawn_material() <= 2 * RookValueMg)
	//	extension = 1;


V650h

- Simplify probCutCount away : https://github.com/official-stockfish/Stockfish/commit/67d06164833857d3497010e952fd0d2c5f00c095
	- probCutCount要らなかったらしい…。

- Compute ttCapture earlier : https://github.com/official-stockfish/Stockfish/commit/580698e5e57f40dcba52b92a7f0c7a0e9ab09437
	- ttCaptureの値を早めに計算してこれで枝刈りするようにした。
	- 枝刈り条件がcaptureOrPawnPromotionに変わった影響が出るかも。

- Do more deeper LMR searches. : https://github.com/official-stockfish/Stockfish/commit/a8330d5c3bfeb4c9d5c55083223792e0989bb9c6


V650g

- do not store qsearch positions in TT as exact. : https://github.com/official-stockfish/Stockfish/commit/45e5e65a28ce7e304c279fabf5f8a83cced73013
	- oldAlpha変数が除去された。
	- qsearchした局面を置換表にexactとして保存しなくなった。
	- Mateが出て詰まし損なうことがあったの、これが原因か?


V650f

- Smooth improving : https://github.com/official-stockfish/Stockfish/commit/4231d99ab408674115623f42f7ff89f3f189ca23
	- PARAM_NULL_MOVE_MARGIN3の意味が変わったので注意。


V650e

- Remove noLMRExtension flag : https://github.com/official-stockfish/Stockfish/commit/8a74c089286913f24a641aa37532006088d0f438

- Simplify Skill implementation : https://github.com/official-stockfish/Stockfish/commit/ef4822aa8d5945d490acca674eb1db8c3c38e9d5
	- SkillLevelというハンデ用のオプションの実装を単純化するだけなので通常対局の棋力には影響しないはず。


V650d

- Capping stat bonus at 2000 : https://github.com/official-stockfish/Stockfish/commit/54a989930ebed200c3278c725151e26a2c0da37a
	- stat bonusは2000でcapする。(最大値を2000にする)

- Range reductions : https://github.com/official-stockfish/Stockfish/commit/00e34a758f2ca170986550a1f8f25dfe691ca511
	- adding reductions for when the delta between the static eval and the child's eval is consistently low.

- このコード削除
#if 1
		// 【計測資料 37.】 update_quiet_stats()で、歩以外に対してreverse_moveにペナルティ。

		if (type_of(pos.moved_piece_after(move)) != PAWN && !is_drop(move))
			thisThread->mainHistory[from_to(reverse_move(move))][us] << -bonus;
#endif

V650c
- Tweak initial aspiration window. : https://github.com/official-stockfish/Stockfish/commit/a0259d8ab9661b7f625474d2cbe18481ef69bbf2


■ 2021/11/16


- スーパーテラショック定跡、探索部のソースコード整理。


Fix processor group binding under Windows. :  https://github.com/official-stockfish/Stockfish/commit/9048ac00db12a9ac48bff9b9eb145b30ff88d984
	- Windows Build 20348からNUMA APIの挙動が変更になるらしく、その対策。


V650b
- Reduce more if multiple moves exceed alpha : https://github.com/official-stockfish/Stockfish/commit/c8459b18ba2d6ddc76d6db90d6eab346ed682e69
	- あるnodeでalphaが更新された回数を記録して枝刈りに利用する。
- Do more reductions at Pv nodes with low delta : https://github.com/official-stockfish/Stockfish/commit/c2b9134c6e7637ea375b4755a6f96dc772c6bb17
- Simplify Pv nodes related logic in LMR : https://github.com/official-stockfish/Stockfish/commit/f5df517145890ecee3d855e98470241b68645b87
- Reduce use of lazyEval : https://github.com/official-stockfish/Stockfish/commit/7b278aab9f61620b9dba31896b38aeea1eb911e2
	- これ、evaluateの評価を遅延させていないので、やねうら王では影響受けない。
	- 単にThreadクラスにbestevalが移動しただけ。

V650a
- Simplify ttHitAverage away : https://github.com/official-stockfish/Stockfish/commit/0bddd942b4d096ff31132a4c3e7aef016d0f2d41
- Adjust ButterflyHistory decay parameter : https://github.com/official-stockfish/Stockfish/commit/2c86ae196df8b2a1197e0de1853a6458e404a976


■ 2021/11/09

- スーパーテラショック定跡、banned_nodesの取り扱いが間違っていたの修正。
- テラショック化コマンド、循環を許すようにした。(変換が組み合わせ爆発を起こして終わらないので…)
- Concurrent::ConcurrentSet追加。


■ 2021/11/08


- スーパーテラショック定跡のテラショック化コマンド("makebook stera_convert")で、leaf nodeまでのdepthをdepthとして出力するようにした。
	- 千日手手順は長くなるほうを選択したいのだが、leaf nodeまでのdepthが深いほうに加点して、alpha-beta探索を行う場合、
	先後協力して(飛車を無駄に動かし合うなど)、depth伸ばしたほうが得となってしまう。
	// 定跡掘ってる時に、組み上げた局面で手待ちのためにそういう手順が可能な局面がある。
	- 仕方ないので、テラショック化の時はvalueが同じ時にdepthを優先しないようにする。色々難しいんだな…ほえほえ。
	- 自分(root)が先手だとして、先手は最長、後手は最短を目指すべきではある。(以前作ったテラショック化コマンドはそうしてあるが、
	 あれ実装が複雑になる&遅いんだよな…)
	- どのみち、自分が最長、相手が最短にしようとする場合でも、飛車だけそれとなく動かし続けて手待ちできる場合、すごく長手順の千日手に
	  なる可能性はあって、そういう時に長手数で千日手になるほうを定跡として目指すのが正しいかというとそうではないから…。
	  単純に手数が最長になるところを目指すのは無理がある。



■ 2021/11/07


- スーパーテラショック定跡、千日手局面を自動的にbanする仕組みを導入。
	- banされている局面数を定期的に出力する
	- ranged_alpha_beta_loopをインクリメントするのやめる。


- スーパーテラショック定跡、千日手局面に到達して思考対象局面がなくなってしまう時のリカバー処理追加。


- 定跡の書き出しをTextWriterクラスを用いて高速化。


■ 2021/11/04


- "makebook extract_sfen_from_db"コマンド追加。
- "makebook extract_sfen_from_sfen"コマンド追加。

- SystemIO::TextWriter追加。わりと速い。

- スーパーテラショック定跡生成部、gccで警告でてたの修正。

- 定跡ファイルBOMついてても、二分探索する時に先頭行はヘッダ行だから関係なくて、うまくprobeできるような気がしてきた。


■ 2021/11/03


- TensorRT8以降に対応
	https://github.com/yaneurao/YaneuraOu/pull/210 (Mizarさんのプルリク)

	* - TensorRT8 : `deserializeCudaEngine()` を2引数に変更
	  3引数のものはTensorRT8以降、非推奨。
	  https://docs.nvidia.com/deeplearning/tensorrt/api/c_api/deprecated.html
	  TensorRT 7.2.3 API : https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-723/api/c_api/classnvinfer1_1_1_i_runtime.html#a8821d6dbbc7bcec2da4ae8ebd927eb89
	  TensorRT 8.2.0 API : https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-820-ea/api/c_api/classnvinfer1_1_1_i_runtime.html#aa0fa4ae510ad803ac2f0caf5a6abe320

	* - TensorRT8 : `buildEngineWithConfig()` -> `buildSerializedNetwork()`
	https://docs.nvidia.com/deeplearning/tensorrt/api/c_api/deprecated.html

	* - TensorRT8 : Deprecated `destroy()`
	https://docs.nvidia.com/deeplearning/tensorrt/api/c_api/deprecated.html


- fコマンド追加。
	- f 1 とやると1.txtからUSIコマンドを読み込みそれを丸ごと実行する。
	- USI拡張コマンド.txtにその説明を追加。

- SystemIO::ReadAllLines()でutf-8のBOMは読み飛ばすように。
- SystemIO::TextReader()でもutf-8のBOMは読み飛ばすように。
	- あとGetLineNumber()追加。
- 定跡ファイルの読み込みはTextReader()を使っているが、on the flyで読み込む時はそうではないので
	定跡ファイルはon the flyで読み込むときはutf-8のBOMついてると駄目。
	なので、結論的には、現時点では定跡ファイルにはBOMつけないで。

- スーパーテラショックコマンドの説明を解説.txtに追加。


■ 2021/11/01


- msys2: pactoys-git -> pactoys #209 (Mizarさんのプルリク)


- makebook steraコマンド、search_delta_on_kifが反映していなかったのを修正。
- misc.cppがコンパイルエラーになっていたの修正。


- makebook stera_convertコマンド、パラメータが指定できていなかったのを修正。
- ProgressBar、"readyok"などにタイミングが被るとGUIが誤動作しかねないので
	makebookコマンドの時だけ有効にするように変更。
	learnコマンドもやったほうがいい?


■ 2021/10/30


- スーパーテラショック定跡コマンドでPVが千日手になった時に無限再帰でstack overflowになる問題修正。
- 定跡の読み込み時にProgressBarを使うようにした。(これUSI違反になるか…?)
- BinaryReader、method名が小文字から始まっていたのでTextReaderに倣い、大文字から始めるようにした。


- スーパーテラショック定跡コマンド、高速化その3
	- 次に思考するleaf nodeの選出、100倍ぐらい速くなった。
	- テラショック化コマンドも速くなった?


- スーパーテラショック定跡のテラショック化コマンド"makebook stera_convert"追加。(テスト中)
- BookTools追加。
- ProgressBar追加。

- misc.hで include <condition_variable> がなくてコンパイルエラーになっていたのを修正
	- Mizarさんからの指摘


- スーパーテラショック定跡、高速化その2。
	- 別スレッドで思考すべきスレッドを探索する。
		- GPU利用率ほぼ100%になった。
	- 定跡DB上に全合法手が存在しないnodeは作り直す。
	- root_sfens.txtに"startpos moves XX"と書くと指し手が弾かれていたの修正。
	- root_sfens.txtを指定しない場合、以下の先手の初期局面、後手の初期局面(初期局面から先手が1手指したすべての局面)が用いられるようにした。

// book/root_sfens.txt
startpos moves 2g2f
startpos moves 7g7f
startpos moves 1g1f
startpos moves 9g9f
startpos moves 6i7h
startpos moves 3i3h
startpos moves 3i4h
startpos moves 3g3f
startpos moves 5i6h
startpos moves 4i5h
startpos moves 7i6h
startpos moves 5i5h
startpos moves 6g6f
startpos moves 5g5f
startpos moves 4g4f
startpos moves 6i6h
startpos moves 4i4h
startpos moves 7i7h
startpos moves 5i4h
startpos moves 4i3h
startpos moves 2h3h
startpos moves 2h6h
startpos moves 2h5h
startpos moves 2h4h
startpos moves 1i1h
startpos moves 2h1h
startpos moves 2h7h
startpos moves 6i5h
startpos moves 9i9h
startpos moves 8g8f
startpos

- Producer Consumer Queueの実装をした。
	- Concurrent::ConcurrentQueue


■ 2021/10/29


- deep-ubuntu: cuda-toolkit-11-5 #207
	https://github.com/yaneurao/YaneuraOu/pull/207 (Mizarさんのプルリク)


- スーパーテラショック定跡、高速化。
- 定跡読み込み時に読み込んだ局面数を出力するようにした。
- hash<Key64>の定義不要だったので削除。

/*
template <>
struct std::hash<Key64> {
	size_t operator()(const Key64& k) const {
		// 下位bit返すだけで良いのでは?
		return (size_t)(k);
	}
};
*/
// → これは 最初からC++のheader上で定義されているはず。


- スーパーテラショック定跡生成ルーチン 作り直した
	- ranged alpha beta探索、無理があった。


■ 2021/10/26


- スーパーテラショック定跡、deltaを調整
	- beta cutの時の処理、間違っていたの修正。
	- デフォルト値を調整。
	- ranged alpha-beta searchの時もPV出力。



■ 2021/10/25


- スーパーテラショック定跡手法による定跡生成コマンド追加。
	makebook steraコマンド
	- 簡単な動作は確認した。
	- 使い方の説明はあとで書く。


- ふかうら王、デフォルトで2スレッドに変更。(最近15bを使うことが多くなってきたので)
- dlshogi::GetSearchResult()追加。これで探索結果を学習部や定跡部に返すことができる。
- ArgumentParserのソースコメント追加。
- StringExtension::to_string_with_zero()追加。


- HASH_KEY_BITSを128,256にした時にコンパイルエラーになっていたの修正。
- std::unordered_set/mapにHASH_KEYが、HASH_KEY_BITSが128,256の時に使えなかった問題を修正。
- eval_coefのコメント、紛らわしかったので修正。


- ふかうら王のTensorRT版のビルド、CUDA 11.4→CUDA 11.5を参照するように変更。


■ 2021/10/22


- msys2 toolchain llvm-13, gcc-11.2 (add arch AVXVNNI, ZEN3) #205
	- https://github.com/yaneurao/YaneuraOu/pull/205 (Mizarさんのプルリク)

	https://twitter.com/msys2org/status/1451060685044129795
	Toolchain updates: clang/llvm 12.0.1 → 13.0.0 and gcc 10.3 → 11.2
	msys2 toolchain の更新に伴い、 ZEN3, AVXVNNI を msys2 でのビルドテストおよびリリースビルドの対象に加えるよう変更します。


- cuda-11.4 の明示 #204
	- https://github.com/yaneurao/YaneuraOu/pull/204 (Mizarさんのプルリク)

	CUDA Toolkit 11.5 Downloads : https://developer.nvidia.com/cuda-downloads
	NVIDIA CUDA Toolkit Release Notes : https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
	CUDA Toolkit 11.5 のリリースに伴ってなのか、TensorRT版のビルドテストにおいてincludeファイルが見つからなくなるエラーが発生しているため、当面は /usr/local/cuda/ ではなく、明示的に /usr/local/cuda-11.4/ 以下を見るよう変更します。


■ 2021/10/20


- ふかうら王 Eval_Coefオプション追加。
	- dlshogiで追加されたやつ
		- https://tadaoyamaoka.hatenablog.com/entry/2021/10/19/230601
		- https://github.com/TadaoYamaoka/DeepLearningShogi/commit/b7f0a8773bb38e30bd4fa347d0ccd1c260868e35


- graviton2 build test #202
	- https://github.com/yaneurao/YaneuraOu/pull/202 (Mizarさんのプルリク)

	Graviton2 向けビルドテストを Ubuntu Linux 20.04 (amd64) 環境、 aarch64-linux-gnu-g++-9 コンパイラにて行います。(normal, tournament target のみ)
	Graviton2 向けビルドオプションを -mfpu=neon から -march=armv8.2-a+fp16+rcpc+dotprod+crypto に変更します。(-mfpu=neon のままではビルドテストに失敗するため)
	変更元: Graviton2をARM NEON SIMD対応 #201
	参考: https://github.com/aws/aws-graviton-getting-started/blob/main/c-c++.md
	参考: https://d1.awsstatic.com/webinars/jp/pdf/services/20200707_BlackBelt_Graviton2.pdf
	Ubuntu Linux 20.04 (amd64) 環境でのビルドテストに使うコンパイラの一部を変更します。 clang++-13 → clang++-14
	最新のclangで発生するwarning, error等を確認できるように。
	その他、ビルドマトリクスの整理など。


- bitop.hからmm_alloc.hのinclude文を削除
	- mm_alloc、以下のcommitで使わないようにしたのだった。
		https://github.com/yaneurao/YaneuraOu/commit/f726457d03ccd3c51332b8cee8254a7d2a80dc69
	- -mfpu=neonをつけてコンパイルした時にコンパイルエラーになっていた。

- Makefile、CPU種別の整理


■ 2021/10/19

- Graviton2をARM NEON SIMD対応 #201
  - https://github.com/yaneurao/YaneuraOu/pull/201 (quiverさんのプルリク)


■ 2021/10/17


- g++ & arm64 でビルドできない問題を修正 #200
	- https://github.com/yaneurao/YaneuraOu/pull/200 (quiverさんのプルリク)


- ベンチマークの実行時間を一定にする改良
	- ベンチマーク、探索部の改良により、実行時間が変動するのはあまり良くない性質
	- 固定時間で計測してnpsで比較すべき。
	- 現状、デフォルトでは固定depthになっているが、これを固定timeに変更する。
	- cf. https://github.com/yaneurao/YaneuraOu/issues/195
	- ベンチマーク局面、一つ追加。4局面×15秒 = 60秒。

- learnerでコンパイル時にwarning出てたの修正。


- extra/bitop.h内のマクロ定義でARM向け向け分岐が足りていない問題を修正 #199
	- https://github.com/yaneurao/YaneuraOu/pull/199 (quiverさんのプルリク)

	extra/bitop.h内のマクロ定義でARM向け向け分岐が足りていない問題を修正
	AWSにはGraviton2というARM Neoverse N1系のプロセッサが存在します。

	https://www.arm.com/why-arm/partner-ecosystem/aws


■ 2021/10/12

- 学習データをまとめて読み込むようにした #196 (nodchip)
	- https://github.com/yaneurao/YaneuraOu/pull/196

- テストロスの計算のスレッド並列処理をApery方式に変更し、高速化した #197 (nodchip)
	- https://github.com/yaneurao/YaneuraOu/pull/197

- TensorRT 8.2 EarlyAccess #198
	- https://github.com/yaneurao/YaneuraOu/pull/198 (mizar)

	* - EVAL_TYPE_NAME に TensorRT のバージョンを含める
	* - ビルド時にTensorRTのdllを出力先にコピー
	* - TensorRT8.2.0.6, CUDA 11.4
	* - Ubuntu2004-README.md
	* - make-deep-ububtu : expand single-line list
	* - cuda-toolkit-11-4
	* - g++-11, clang++-12, clang++-13, clang++-14
	* - reorder compiler
	* - remove libomp5-*
	* - remove libomp5-*, and others
	* - install CUDA, TensorRT later


■ 2021/09/28


- Learner::search,qsearchのコード、整理
	- コードを少し整理した。
	- 初期化コード少し足した。
	- th->selDepthの初期化は不要だったので削除。
  - reformat


- gensfenコマンド正常に生成できていなかったの修正。
	- Learner::search()でsearch<Root>にしていなかった。


■ 2021/09/27 V6.50

- V6.50

- やねうら王探索部、V6.05から短い時間で+R50程度強くなった。

engine1 = YaneuraOu2018NNUE_V605.exe , eval = suishou_wcso1
engine2 = YaneuraOu2018NNUE_V650.exe , eval = suishou_wcso1
T2,b1000,1233 - 86 - 1681(42.31% R-53.84[-64.55,-43.13]) winrate black , white = 51.48% , 48.52%
T2,b2000,1329 - 137 - 1534(46.42% R-24.92[-35.63,-14.21]) winrate black , white = 50.96% , 49.04%
T2,b4000,734 - 73 - 853(46.25% R-26.1[-40.48,-11.72]) winrate black , white = 52.61% , 47.39%

V6.50で水匠4を超えているらしい。

https://twitter.com/tayayan_ts/status/1442104187601375233

最近本家やねうら王の開発が進んでいるのはご存じでしょうか!(やる気なしツイートは何だったのか…笑)
既に水匠4改同梱の探索部を超えた強さになっているようなので、導入できる方はご検討ください!
参考(4T1手200万ノード):
YO6.03kai2(水匠4改同梱) vs YO6.05最新
1256-299-1332(勝率48.53%)

- "engine_options.txt"、オプション名と設定値をそのまま書けるようにした。
- "eval_options.txt"の読み込み対応。(docs/解説.txt に説明がある)
- GenerateAllLegalMovesオフの時に定跡で不成の指し手にhitすると定跡にhitしない扱いにしてたの修正。
- 定跡DBに非合法手がある時、それをエラーとして出力するようにした。
- etc..


■ 2021/09/26


- エンジンオプションのEvalDirで指定されたフォルタにある"eval_options.txt"でエンジン設定を読み込めるように。
- "engine_options.txt"で↓の例2の形式でも設定できるように。

// ↓説明を解説.txtに追加。

 ■ エンジンオプションのデフォルト値の変更

"usi"に対して返すオプションリストのオプションのデフォルト値を変更する機能
カレントフォルダに"engine_options.txt"というファイルを配置して、
ここにOptionを構築するための文字列を書きます。(この"option"で始まる文字列は、
"usi"に対して応答として返している文字列なので、コマンドプロンプト上でエンジンを
実行して、"usi"とタイプして、返ってきた文字列一覧をコピペして編集すると良い)

例1)
option name EvalDir type string default ../eval/YaneuraOu_2018
option name EvalShare type check default true
option name BookDir type string default ../book

また、エンジンオプション名 のあとにデフォルト値だけ書くこともできます。

例2)
EvalDir ../eval/YaneuraOu_2018
BookMoves 16

// この場合、BookMovesの最小値 = 最大値 = default値 = 16となります。
// minとmaxが同じ値なのでGUI側から値の変更はできません。


 ■ 評価関数ファイルに応じたエンジンオプション

評価関数ファイルに応じて、エンジンオプションを調整しないといけないことがあり、
どの評価関数ファイルがどの設定値であるかわからなくなることがあります。

そこで、EvalDirオプションで指定されているフォルダのなかにある
"eval_options.txt"というファイルを"isready"コマンドが送られてきた時(評価関数を読み込む直前)に
読み込みに行くようになっています。


■ 2021/09/25


- LMRの条件中のmove countの計算式修正。

- PARAM_REDUCTION_ALPHAの値、Stockfishの値にいったん戻す。

- 探索部のコメント、Stockfishのものもコピペして貼り付けておく。
	// 元のコードとの対応がわかりやすくなる。

- 探索部、コメントの誤りをいくつか修正。


- 静的評価に基づく王手延長
	- Check Extension with Static Evaluation : https://github.com/official-stockfish/Stockfish/commit/e8418bb1b92800550264b9a4993f51208f8fe681

- doubleExtensionsの値を更新してなかったの修正。

- continuation_historiesのupdate、詰みの時は、PvNodeかcutNodeならボーナスを2倍する。
	- Further improve history updates : https://github.com/official-stockfish/Stockfish/commit/b7b6b4ba18bc9d291c2c2fd300c22a3e008dcbb2

- captureと成りを延長する
	Extend captures and promotions : https://github.com/official-stockfish/Stockfish/commit/e404a7d97c94890dda18ca3a16cfd15b5a7ef235

- PARAM_FUTILITY_AT_PARENT_NODE_DEPTHを7から8に変更。

- root nodeでsingular延長していたの修正。

- Pruning at shallow depthのreorder
	- Reorder conditions in LMR and pruning : https://github.com/official-stockfish/Stockfish/commit/2c1be0be8ec51005befcd4fc422e88b6e32cef45
	- 並び替えただけなので棋力に影響はないはず。

- SEEの単純化
	- SEE simplification : https://github.com/official-stockfish/Stockfish/commit/a1a83f38691ae3f39c827a46e59ae9875605aa3b

- 探索部のコメントに書いてあるEloの上昇値を修正
	- Update Elo estimates for terms in search : https://github.com/official-stockfish/Stockfish/commit/114ddb789bed2d74d6a786f5da6c9ce63d44de27

- TTでないときのCutNodeのdepthを減らす。
	- Decrease depth for cutnodes with no tt move : https://github.com/official-stockfish/Stockfish/commit/30fdbf43283eb0d2f8e5ca325877d3e514758804

- ProbCutでmoveがTTの指し手である場合の枝刈り削除

-  王手がかかっているときのprobcut導入
	- Introduce ProbCut for check evasions : https://github.com/official-stockfish/Stockfish/commit/7c30091a92abddb8265e53768b32751c49642040



- rootでのbestmoveが不安定であるときに思考時間を増やす。
	- Make extra time for bestMoveInstability dependent on rootdepth. : https://github.com/official-stockfish/Stockfish/commit/9353e72103d4dc4880506c2f54b6426cbd182450

- null moveのmargin調整。
	- Tuning Search : https://github.com/official-stockfish/Stockfish/commit/ff4c22238a199625cf7f02be1816b07fc49f5d45

- ProbCutの定数調整。
	- Search Parameters Tuning : https://github.com/official-stockfish/Stockfish/commit/29ed22de8cd347cacb0ba826ee43fa587985a98d

- likelyFailLow導入
	- Cleanup of likelyFailLow logic : https://github.com/official-stockfish/Stockfish/commit/d777ea79fff0f651bd948c881946cd06bebd9381
	- Simplify LMR rules for statScore : https://github.com/official-stockfish/Stockfish/commit/c82f6f56a65759461f417602059ad7c97b9451aa

- formerPv削除
	- Remove formerPV variable. : https://github.com/official-stockfish/Stockfish/commit/95f73ff393e5b87b2a3b4195d698b6620fd4a123

- LMRのnonPVのbestmoveが不安定なときのreduction条件変更。
	- Small cleanups (march 2021) : https://github.com/official-stockfish/Stockfish/commit/83eac08e7562d93787f75eccd4b7781c4bd45dd3


- excludedMoveがある時は、置換表にsaveしない。
	- Add / remove leaves from search tree ttPv : https://github.com/official-stockfish/Stockfish/commit/c02b3a4c7a339d212d5c6f75b3b89c926d33a800

- PARAM_EVAL_TEMPO、削除。

	// 評価関数での手番の価値
	// 元の値 = 20 , step = 2
	// [PARAM] min:10,max:50,step:1,interval:1,time_rate:1,fixed
	PARAM_DEFINE PARAM_EVAL_TEMPO = 20;

	- Remove Tempo : https://github.com/official-stockfish/Stockfish/commit/754fc8a8b5ca7466926d54465eeb1df4d4a481ac
	- 評価関数(NNUE)は手番込みの評価関数だから、相手番から見た評価値は単に符号を変更せよとのこと。

- update_all_stats()の時のbonus2を変更。
	- Search Parameters Tuning : https://github.com/official-stockfish/Stockfish/commit/29ed22de8cd347cacb0ba826ee43fa587985a98d

engine1 = YaneuraOu2018NNUE_V605.exe , eval = suishou_wcso1
engine2 = YaneuraOu2018NNUE_V605f.exe , eval = suishou_wcso1
T2,b1000,1196 - 104 - 1530(43.87% R-42.78[-53.81,-31.76]) winrate black , white = 50.07% , 49.93%
// ここまででV6.05から+R43ほどあがった模様。(短時間計測なので長時間だともっと?)



■ 2021/09/24


- Reduction配列の初期値変更。
	- Simplify Reductions Initialization : https://github.com/official-stockfish/Stockfish/commit/e47b74457ef12ff28ced317fef942cfad18b18a0
	- スレッド数によってreductionの係数を変更するの、やる必要なかったようだ。
	- スレッド数が変更になった時にvoid Search::init()を呼び出すのやめる。

- Singluarの二重延長防止
	- Detect search explosions : https://github.com/official-stockfish/Stockfish/commit/73018a03375b4b72ee482eb5a4a2152d7e4f0aac
	- Tweak doubly singular condition (Topo's patch) : https://github.com/official-stockfish/Stockfish/commit/ff3fa0c664a5799e5531b0908018c59633d761bf

- LMRの旧コード削除


- やねうら王探索部にNodeTypeとしてRootを追加。
	- Rootの時の条件分岐が不要になるのでわずかだがspeed upする。
	- Introducing NodeType Root : https://github.com/official-stockfish/Stockfish/commit/0b7cc8bd2f5a51de9f911fcdfb253b1c9f513897

- RunningAverage導入。
	- Detect search explosions : https://github.com/official-stockfish/Stockfish/commit/73018a03375b4b72ee482eb5a4a2152d7e4f0aac

- LMRにThreadベースのreduction導入。
	- Thread based reduction tweak. : https://github.com/official-stockfish/Stockfish/commit/c0ff241464338f7e5bb815b4f72c2a95d12244a0

- PV nodeではLMR reductionしない
	- Reduce in LMR reduction on PvNode : https://github.com/official-stockfish/Stockfish/commit/999e142c548f61852ace7b8f025d71bc8a805e3c

- stat_bonus調整
	- Tuning Search : https://github.com/official-stockfish/Stockfish/commit/ff4c22238a199625cf7f02be1816b07fc49f5d45

- Breadcrumb,ThreadHoldingのコード除去
	- Remove coordination between searching threads : https://github.com/official-stockfish/Stockfish/commit/a0e2debe3f1d14f84984a9a2c1482dc41f695548

- Learner::searchでlowPlyHistoryの初期化コード等が足りてなかったの修正。


- aligned_large_pages_alloc() , WIN32用とAndroid用でビルドエラーになっていたの修正。


- NNUEで使っているAlignedDeleter、LargeMemoryDeleterとrename。
- NNUE LEARNがコンパイルエラーになっていたの修正。


- MovePickerでのordering調整。
	- QUIETSのscoring、continuationHistory[1],[3]に関しては2倍しないほうがいいらしい。
		- Tune ordering of moves at internal nodes : https://github.com/official-stockfish/Stockfish/commit/6617ad6e033fc636e82453e121469f10e4f31a1a


- Misc::LargeMemory、リファクタリング。
	- NNUEのメモリ確保の方もコード整頓した。

- Misc::start_logger()の引数をboolからconst string&に変更。
	- Improve handling of the debug log file. : https://github.com/official-stockfish/Stockfish/commit/ccf0239bc468c1fb599785e0dea178e84279674d

- TTのコード、定数値がmagic numberになっているのをconstexprでわかりやすくした。
	- Better code for hash table generation : https://github.com/official-stockfish/Stockfish/commit/573f0e364ff4c1e5928be2ca947f65c5d4e177d5


- goコマンドで思考するときに、定跡DBのその局面の非合法手に関してはエラー出力を行うようにした。


■ 2021/09/19 V6.05


- 定跡DB上に非合法手があると、その手を選択した場合、定跡にhitしなかった扱いになっていたが、非合法手は事前に除外してからbestmoveを選ぶように修正した。
- 定跡DB上の非合法手、probe()した時にそれをエラーメッセージとして出力するようにした。

- やはり、定跡上の歩の不成の指し手、GenerateAllLegalMovesがfalseならhitしないように変更。
	- probeの時にそれを除外する処理を追加。

- Position::legal()を用いて合法手判定をする時、これが連続王手の千日手を弾かないが、
	定跡で連続王手の千日手の指し手があると指してしまう。
	これは回避が難しいので、仕様であるものとする。
	"position"コマンドでも千日手局面は弾かないし、この仕様は仕方ない意味はある。


- V6.05
	- 現在の局面に至るまでに歩の不成が含まれているとそれを非合法手扱いしていたのを修正。(最近のcommitでのエンバグ)
	- 定跡の指し手の歩の不成は、GenerateAllLegalMovesがtrueであっても選択できるように変更。
	- EvalDirなどフォルダ指定の時に絶対Pathでの指定を可能にした。
	- 駒落ちの入玉宣言に対応。
	- UnitTest導入。
		- "test unit"コマンド。


- 現在の局面に至るまでに歩の不成が含まれているとそれを非合法手扱いしていたのを修正。(最近のcommitでのエンバグ)

  - cf : https://github.com/yaneurao/YaneuraOu/issues/190
  - yssayaさん、iwkjosecさん、tttakさん、バグレポ誠にありがとうございました。

- 読み筋に歩の不成が表示されないことがあったの修正。

- 定跡の指し手の歩の不成は、GenerateAllLegalMovesがtrueであっても選択できるように変更。

- USIの"position"コマンドで入力文字列に非合法手があった場合、その旨を出力することにした。
	"Error! : Illegal Input Move : "
	みたいなの。

- UnitTest用のパラメーター設定ができるように拡張
	- 指し手生成のテストコード、少し書いたが、今回のバグそこではなかったのでコメントアウトしておく。
- UnitTestにUSI::UnitTest()追加

- MUST_CAPTURE_SHOGIのコード、掃除。(また再実装する時に追加する)

#if defined(MUST_CAPTURE_SHOGI_ENGINE)
	// 取る一手将棋は合法手かどうかをGUI側でチェックしてくれないから、
	// 合法手かどうかのチェックを入れる。
	if (!MoveList<LEGAL>(pos).contains(move))
		sync_cout << "info string Error!! Illegal Input Move = " << move << sync_endl;
#endif


■ 2021/09/15


- EvalDirなどフォルダ指定の時に絶対Pathでの指定を可能にした。
	例)
		C:/YaneuraOu/Eval  ← Windowsのドライブレター付きの絶対Path
		\\MyNet\MyPC\Eval  ← WindowsのUNC
		~myeval            ← Linuxのhome
		/YaneuraOu/Eval    ← Windows、Linuxのroot

- Path.IsAbsolute()追加。

- namespace MiscにUnitTest追加。


- Android.mk: add source/testcmd/unit_test.cpp #191 (Mizarさんのプルリク)
	- UnitTestのためにunit_test.cppを追加したことに対する、Android用のmakefileの修正。


- 駒落ちの入玉宣言、AobaZeroに合わせる。
	- AobaZeroは、上手を後手とみなし27点以上(二枚落ちなら17点以上)で入玉宣言できる模様。
		- https://github.com/yssaya/komaochi/blob/73258b38a52da395456ed180ea07edea8c491225/src/usi-engine/bona/ysszero.cpp#L1952

- 学習部でのエラーメッセージ、illegalの綴りtypoしてたの修正。


■ 2021/09/14


- 駒落ちの入玉宣言に対応。

	以下のCSARule24HとCSARule27Hが新規に追加されたもの。

	EnteringKingRule: 入玉ルール
		NoEnteringKing  : 入玉ルールなし
		CSARule24       : 24点法。31点で宣言勝ちなので31点にならないと宣言勝ちはしない。
		CSARule24H      : 24点法 , 駒落ち対応
		CSARule27       : 27点法(CSAルール。先手は28点、後手は27点で宣言勝ちできる)
		CSARule27H      : 27点法 , 駒落ち対応
		TryRule         : トライルール(敵の玉が最初にいた升に自玉が移動できたら入玉とみなす)

		駒落ち対応と書いてあるものは、例えば二枚落ちならば、上手(うわて)は5点×2枚=10点だけ事前に点数を持っているとみなして宣言勝ちの条件を満たすかを
		チェックします。駒落ちでは上手が先手なので、上手は 28 - 10 = 18点の駒点で入玉できます。(敵陣に10枚の駒がないといけない等の条件は元のまま)
		注意 : 盤上で足りない駒は、上手の駒を落としているとみなします。

		将棋所、ShogiGUIなどではトライルール、駒落ちの宣言法に対応していないので注意。




- UnitTest Position classの分を少し書いた。
	- "test unit"コマンドやめて、"unittest"というコマンドを作った。
	- うまく動いていて、いい感じの出力をしてくれる。


- UnitTest導入。
	- "test unit"コマンド。


- AMD Optimized BLISを使用するための変数を追加した #189 (tanuki-さんのプルリク)
 	tanuki- 2021-09-03 AMD Optimizing CPU Libraries
	実験結果 - Google ドキュメント https://docs.google.com/document/d/1c-5VxR_TWH3okgTN28mZznPjdB06wxV13JfWNx7pCkU/edit
	AMD Ryzen Threadripper 3990X を用いた場合、 OpenBLAS に比べ、 4% 程度学習が高速になりました。

	- https://github.com/yaneurao/YaneuraOu/pull/189




■ 2021/08/31


- libomp-12-dev #188 (Mizarさんのプルリク)
	Ubuntuでのビルドテスト環境において、以下の修正を行います。

	clang++-11でのビルドテストを削除。
	clang++-12のインストール時に、libomp-12-devを明示的にインストールするように変更。(明示的に指定しないとインストールされなくなったopenmpが必要なビルドテストに失敗していたため。)
	clang++-13でのビルドテストを追加。


- 一つ前のcommitでNO_PIECE_TYPEと書くべきところがNO_PIECEになっていたの修正。
  - gccで警告が出てた。


V6.04
- V6.03からの変更点
	- Counter Moveに非合法手が混入するバグ修正。(tanuki-さんのプルリク)
	- pseudo-leaglまわりのソースコード整理。
	- benchコマンドでGenerateAllLegalMovesオプションが反映されていなかったの、反映するように修正。


- is_ok(m)==falseの時、Position::pseudo_leagl(m)がfalseを返すことを保証するように変更。


- pseudo-leaglまわりのソースコード整理。
	- USE_GENERATE_ALL_LEGAL_MOVES削除。常に指し手生成のtemplateは、歩の不成を生成するバージョンとそうでないバージョンを実体化する。

	// 全合法手を生成する機能を追加するか。
	// これをdefineすると、"GenerateAllLegalMoves"というオプションが自動追加される。
	// ※ Search::Limits.generate_all_legal_moves に↑のオプションの値が反映されるので、
	//     それを見て、trueならば、指し手生成の時に歩の不成も含めて生成すれば良い。
	// #define USE_GENERATE_ALL_LEGAL_MOVES

	- 定跡で歩の不成が指せなかったの修正。
		- GenerateAllLegalMovesがtrueの時は、それを指す。
	- 一つ前のプルリクのコメントをブログに移動。コメント追加。

- benchコマンドでGenerateAllLegalMovesオプションが反映されていなかったの、反映するように修正。



- Counter Moveに非合法手が混入するバグ修正。(tanuki-さんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/185
	- cf : https://yaneuraou.yaneu.com/2021/08/17/about-the-yaneuraou-bug-that-appeared-in-the-long-match/


■ 2021/05/25


- Ubuntu20.04 TensorRT ビルドテスト環境 #183(Mizarさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/183
	- Ubuntu20.04 + CUDA11.3 + TensorRT8.0.0EA 環境でTensorRT版のビルドテストを行えるようにしました。


- update DML 1.5.1, ORT 1.7.0/1.7.1, add ORT_CUDA (for NVIDIA CUDA) #182(Mizarさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/182

	Microsoft.AI.DirectML 1.4.0 -> 1.5.1
	Microsoft.ML.OnnxRuntime 1.6.0 -> 1.7.0
	Microsoft.ML.OnnxRuntime.DirectML 1.6.0 -> 1.7.0
	Microsoft.ML.OnnxRuntime.Gpu 1.7.1 (新規導入)
	NuGetパッケージの更新を行い、 Microsoft.ML.OnnxRuntime.Gpu を利用してTensorRT無しでCUDAを利用するビルドターゲットを追加しました。自分の環境では、ORT_DML (DirectML) より ORT_CUDA は早く、 TensorRT よりは遅く動作するようです。


- dangling-else #181
	- https://github.com/yaneurao/YaneuraOu/pull/181

- モデル読み込み時の情報表示追加 #179(Mizarさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/179
	- 8個modelファイルを読み込む部分を並列化したほうがいいような気も…。😥

- switch main clang to clang-11 #178 (Mizarさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/178



■ 2021/05/23


- df-pnのsecond_pn,second_dnの計算が正しくない問題を修正 #176
	https://github.com/yaneurao/YaneuraOu/pull/176/files

	sfen 3+R1gknl/4+B1s2/6pp1/5p3/8p/9/9/9/9 b RSNPb3g2s2n3l13p 1
	が解けなかったの修正されている。

	- https://github.com/yaneurao/YaneuraOu/issues/174


■ 2021/5/20


- Clangで警告でてたの修正。
	- thanks > Mizarさん



【新しい定跡生成部について】

いまMCTS + UCB1で定跡生成するルーチンが8割ぐらい書けたのだが、単純なUCB1だと角交換された時など(取り返す指し手以外が絶望的な局面)、1手以外がすべて非常に悪い指し手なので、ランダムに次の一手を選ぶと悪い手ばかり拾ってきてしまい、その先を探索しなくなってしまう。:sob: 

Policy使ってAlphaZero式に選んだほうが良いのか、それとも取り返す指し手を優先して選んだほうが良いのか…。(後者の場合、未訪問の枝のUCB1が∞になってしまうのでやはりその局面のすべての指し手を探索されることにはなるはずで…)

そう考えると、もともと(定跡生成に限らず)MCTS + UCB1で将棋はちょっと厳しいのか?

そして、Policy使う場合、ふかうら王でないとこの定跡生成ルーチン、使えないことになるな…。



■ 2021/5/18


- makebook mctsコマンド。4/5ぐらい書けた。


- Parser::ArgumentParser追加。PythonのArgumentParserっぽく使える。

		Parser::ArgumentParser parser;
		int min = 0, max = 100;
		parser.add_argument("min", min);
		parser.add_argument("max", max);
		parser.parse_args(is);
		cout << "min = " << min << endl;
		cout << "max = " << max << endl;

- LineScanner → namespace Parserに移動。

- dlshogi_searcher.cppでfloat変数に代入するところで警告が出ていたの修正。


- makebook mctsコマンド。3/4ぐらい書けた。


- BinaryReader,BinaryWriter実装。
- ReadFileToMemoryで読み込みエラーの時のResultきちんと返すようにした。


- TensorRTのserializeされたファイル読み込みの時にメモリ解放してなかったのを修正。
- struct FileOperator → namespace SystemIOに変更
- TextFileReader → SystemIO::TextReaderに変更
- BinaryReader,BinaryWriter追加。(実装中)



■ 2021/5/16


- PackedSfenにメソッド追加したらclangで警告でるようになっていたの修正。(takotakotさんのプルリク)
	https://github.com/yaneurao/YaneuraOu/pull/172


- NDK のバージョンを r21e にする #171(takotakotさんのプルリク)
	https://github.com/yaneurao/YaneuraOu/pull/171



■ 2021/5/15


- makebook mctsコマンド。半分ぐらい書けた。


- move_pick.hでUbuntuでコンパイルエラーになるようになっていたの修正。
	#include <limits>
	↑これがないとコンパイルエラーになるようになった(突然)

//	C++は、コンパイラの実装者ごとに標準includeファイルのなかでincludeしているファイルが異なっていて、
//	ある環境ではincludeせずに済んでいたものが他の環境ではincludeを明示的に書いていないとエラーになるのでは、
//	portablityも何もあったものではないですな…。



■ 2021/5/14


- makebook mctsコマンド。1/3ぐらい書けた。


- benchコマンドで引数の名前でも値を指定できるようにした。
	例)
		benchmark type nodes limit 3000
		// 3000 nodesで探索


■ 2021/5/13


- benchコマンドで開始時にbench条件を出力すようにした
- benchコマンド、ふかうら王では探索時のdepth limitの指定には対応していないので
	ふかうら王の時は、defaultで LimitType = nodes (node limit)に変更。


■ 2021/5/12


- Makefileで常にdev,abeが有効にコンパイルされていたの修正。
	- nosseで動かなかったの、これが原因らしい。Mizarさん、調査ありがとう。
	- 関連 : https://github.com/yaneurao/YaneuraOu/pull/170

- MateMovePickerで変数未初期化の警告が出ていたの修正。



■ 2021/5/9


- V6.03
	- Stochastic_Ponder追加
	- ふかうら王
		- 持ち時間制御改善
	- wait,sleepコマンド追加
	- LeafDfpnNodesLimitを50→40に変更
	- エンジンオプションにSoftmax_Temperature追加。(dlshogiと違い、千分率)
	- df-pnで落ちることがあったの修正。


- ふかうら王の大会用の設定について説明追加。


- wait,sleepコマンド追加
- Tools::sleep()の引数をint→u64に変更。


- CIビルド、エラーが出ていたのを修正。
	- https://github.com/yaneurao/YaneuraOu/pull/169
	Add development packages

	libstdc++-10-dev for
	#include <chrono>

	libomp-10-dev for
	openmp



■ 2021/5/4


- 探索打ち切り条件のチューニング。
	- パラメーターの調整が、長時間の対局×optimizerのようなものを使わないと無理。
	- 以前の持ち時間制御よりマシやろ、程度。
	- 勝負どころ(1番目の指し手と2番目の指し手の評価値が近いほど)で多くの時間を使うようにしてあるので
	強い相手と対局すると時間たくさん使うし、弱い相手とだと時間かなり余るかも。
	- WCSC31の持ち時間(15分+1手5秒加算)においてSlowMover 100でだいたいいい感じだと思う。

- positionコマンドを送らずにgoコマンドを2回送るとresignが返っていたの修正。
// 実際の対局ではpositionコマンドを送らずにgoは来ないはずだが…。


- ふかうら王 LeafDfpnNodesLimitを50→40に変更
	A100/GeForce GTX 3090 5スレでGPUを使い切りたいために調整。



■ 2021/5/3


- やねうら王/ふかうら王にStochastic Ponder実装する。
	- dlshogiにあるやつ。実装方法は全く異なるが。
	- エンジンオプションに "Stochastic_Ponder"追加。
	// → go ponder二度呼び出されると困るのかw これはまずい。
	// → うまく動くようにした。色々難しいなw

	デフォルト、オフにしとこう…。
	これデフォルトでオンだと相手番で思考するので将棋所で読み筋の指し手のところがおかしくなって、初心者が大恐慌に陥るわ:rofl:


- 新しい定跡生成ルーチン、WCSC31終わってから作るのでいったんrevert。


- ふかうら王、訪問回数の多いnodeでSelectMaxUcbChild()の結果をしばらくcacheしておくようにした。
	A100×8のような高スペックなGPU環境においてroot付近のnodeのlockで待たさせることが減るはず。
	// 弱くなっていないかはそんな環境で棋力計測ができないのでわからない…。


- leaf nodeで使っているdf-pn、ノード数が指定されている時に、残り探索ノード数が証明数より少ないと証明不可なわけで、即座に不詰と判定するように変更。
	// → 不詰が証明できるかもしれないが、不詰を証明する価値に乏しいので…。
	// → 途中で切り上げる分、だいぶ軽くなった。
	RTX3090で10ブロック、3スレッド設定で降るに回せそう。

	検証用) RTX3090にて

	evaldir taya-model052
	DNN_Batch_Size1 256
	UCT_Threads1 3
	isready
	position startpos moves 7g7f 8c8d 2g2f 8d8e 2f2e 4a3b 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a2b 4g4f 2b3c 3i3h 5a4b 6i7h 7a7b 3g3f 7c7d 3h4g 1c1d 2i3g 6c6d 1g1f 8a7c 5i6h 7b6c 4i4h 6a6b 9g9f 9c9d 4g5f 8b8a 6g6f 6c5d 2h2i 5d6c 6h7i 4b5b 7i8h 5b4b 5f6g 6c5d 3g4e 3c4d 2e2d 2c2d 2i2d B*1c 2d2i P*2h 2i4i 8e8f 8g8f 1c4f P*2b 4d4e 2b2a+ 8a2a 4h4g 4f1c 1f1e N*5e 1e1d 1c2d P*2e 5e6g+ 2e2d 6g7h 8h7h P*1e 4i4h 2a2d 7f7e 2d2g+ 7e7d 7c6e 6f6e S*3i
	go btime 10000 wtime 10000 inc 100000

	↓dfpn50 枝刈りなし
	info nps 55773 time 1619 nodes 90298 hashfull 9 depth 29 score cp 114 pv N*2d 2g2d 4h6h 2d2g B*8d G*7b N*3g N*5e 3g4e 5e4g+ N*2d 2g2d S*7c G*5b 7c6b 7b6b 7d7c+ 6b7c 8d7c+ N*7e 7g7f 4g5g 6h6i S*6g 7h7g 5d4e 7f7e 2d2g 6i3i

	↓dfpn50 枝刈りあり
	info nps 57540 time 1617 nodes 93043 hashfull 9 depth 28 score cp 105 pv N*2d 2g2d 4h6h 2d2g B*8d G*7b N*3g N*5e 3g4e 5e4g+ N*2d 2g2d S*7c G*5b 7c6b 7b6b 7d7c+ 6b7c 8d7c+ N*7e 7g7f 4g5g 6h6f 5d4e 7f7e 5g5f 6f7f 2d2g

	// 3%ほどnps上がったか。



- ふかうら王、leaf nodeでの詰将棋をオーダリング付きdf-pnに変更。default 50 node。
	- root nodeでのdf-pnをオーダリング付きdf-pnに変更。
	- エンジンオプション : "MateSearchPly"廃止。
	- エンジンオプション : "LeafDfpnNodesLimit"追加。
	- docs/USI拡張コマンド.txtに↑の説明追加。

	// 5手詰めをdfpn 50nodesに置き換えても強さほぼ変わらない&nps 5%ほど上がる。(RTX 3090 4スレ時中盤の局面)
	// なので置き換えたほうが得だと思われる。
	// 指定するのはノード数なので細かい調整もできるだろうし…。

	engine1 = YaneuraOu-Deep-TensorRT_V604.exe , eval = deep\gct2020
	engine2 = YaneuraOu-Deep-TensorRT_V604DFPN50.exe , eval = deep\gct2020
	T1,n1600.n1600,266 - 61 - 261(50.47% R3.3[-21.58,28.17]) winrate black , white = 47.82% , 52.18%

	engine1 = YaneuraOu-Deep-TensorRT_V604.exe , eval = deep\gct2020
	engine2 = YaneuraOu-Deep-TensorRT_V604DFPN50.exe , eval = deep\gct2020
	T1,n800.n800,1223 - 615 - 1162(51.28% R8.89[-2.82,20.59]) winrate black , white = 51.32% , 48.68%

	engine1 = YaneuraOu-Deep-TensorRT_V604.exe , eval = deep\taya-model051
	engine2 = YaneuraOu-Deep-TensorRT_V604DFPN50.exe , eval = deep\taya-model051
	T1,n3000.n3000,505 - 80 - 499(50.3% R2.08[-15.95,20.1]) winrate black , white = 50.3% , 49.7%

	engine1 = YaneuraOu-Deep-TensorRT_V604.exe , eval = deep\gct2020
	engine2 = YaneuraOu-Deep-TensorRT_V604DFPN50.exe , eval = deep\gct2020
	T1,n3000.n3000,702 - 105 - 647(52.04% R14.17[-1.39,29.74]) winrate black , white = 50.33% , 49.67%


	// npsの計測データ。
	// RTX3090で計測

	evaldir taya-model052
	DNN_Batch_Size1 256
	UCT_Threads1 4
	isready
	position startpos moves 7g7f 8c8d 2g2f 8d8e 2f2e 4a3b 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a2b 4g4f 2b3c 3i3h 5a4b 6i7h 7a7b 3g3f 7c7d 3h4g 1c1d 2i3g 6c6d 1g1f 8a7c 5i6h 7b6c 4i4h 6a6b 9g9f 9c9d 4g5f 8b8a 6g6f 6c5d 2h2i 5d6c 6h7i 4b5b 7i8h 5b4b 5f6g 6c5d 3g4e 3c4d 2e2d 2c2d 2i2d B*1c 2d2i P*2h 2i4i 8e8f 8g8f 1c4f P*2b 4d4e 2b2a+ 8a2a 4h4g 4f1c 1f1e N*5e 1e1d 1c2d P*2e 5e6g+ 2e2d 6g7h 8h7h P*1e 4i4h 2a2d 7f7e 2d2g+ 7e7d 7c6e 6f6e S*3i
	go btime 10000 wtime 10000 inc 100000

	↓dfpn300
	info nps 22104 time 1615 nodes 35698 hashfull 10 depth 28 score cp 79 pv N*2d 2g2d 4h6h 2d2g B*8d G*7b N*3g N*5e 3g4e 5e4g+ N*2d 2g2d S*7c N*7e 8d7e 5d4e 6e6d P*6g 6h6g N*5e 6g6i 4g5h 6i3i 2h2i+ 3i3h G*6e 7e8d 6b7c

	↓dfpn80
	info nps 44287 time 1622 nodes 71835 hashfull 7 depth 26 score cp 149 pv N*2d 2g2d 4h6h 2d2g B*8d 6b6a N*3g N*5e B*4i 2g2f 3g4e 5e4g+ 6e6d G*5h 6h5h 4g5h 6d6c+ 5d4e 4i5h N*6e 7g6f 3i4h+ 5h7f 2f3f S*2d P*7g
	bestmove N*2d

	↓dfpn50
	info nps 55773 time 1619 nodes 90298 hashfull 9 depth 29 score cp 114 pv N*2d 2g2d 4h6h 2d2g B*8d G*7b N*3g N*5e 3g4e 5e4g+ N*2d 2g2d S*7c G*5b 7c6b 7b6b 7d7c+ 6b7c 8d7c+ N*7e 7g7f 4g5g 6h6i S*6g 7h7g 5d4e 7f7e 2d2g 6i3i

	↓5手詰め
	info nps 53620 time 1622 nodes 86972 hashfull 8 depth 26 score cp 103 pv N*2d 2g2d 4h6h 2d2g B*8d 6b6a N*3g N*5e B*4i 2g2f 3g4e 5e4g+ 6e6d G*5h 6h5h 4g5h 6d6c+ 5d4e 4i5h N*6e 7g6f 3i4h+ 5h7f 2f3f S*2d P*7g

	// dfpn50と同等でござったか…。

	↓dfpn50 with hash
	info nps 39798 time 1615 nodes 64274 hashfull 6 depth 26 score cp 135 pv N*2d 2g2d 4h6h 2d2g B*8d 6b6a N*3g N*5e B*4i 2g2f 3g4e 5e4g+ 6e6d G*5h 6h5h 4g5h 6d6c+ 5d4e 4i5h N*6e 7g6f 3i4h+ 5h7f 2f3f S*2d P*7g
	bestmove N*2d
	// 遅いでござる…。なんぞこれ…。


- 指し手Ordering有りDFPNルーチンを公開。


■ 2021/5/2


- ふかうら王、ビルドに用いるTensorRTのバージョンアップ
	// dlshogiで用いているバージョンに合わせておく
	TensorRT-7.2.1.6 → TensorRT-7.2.3.4

	TensorRT-7.2.1.6 → TensorRT-7.2.3.4にバージョンアップして、シリアライズファイルに互換性なくなってるのに、
	NV_TENSORRT_VERSIONが7203のままなんですけど:face_vomiting:  このシンボルの値、シリアライズするファイル名に使ってるので、
	同じ値のまま互換性失われてると困るんですけど:face_vomiting:


- ふかうら王、isreadyに対して、毎回modelファイルの存在チェックをしているの、無駄なので存在していたファイルは
 記憶しておくことにした。


- ふかうら王、引き分けの上位ノードへの伝播

	1. 子ノードすべてが負け
	2. 子ノードすべてが引き分け
	3. 子ノードすべてが引き分け or 負け
	引き分け とは、 2. or ( 3. and (not 1.))

	レアケースかもしれないが、弱くはなってなさそうなので採用。

	engine1 = YaneuraOu-Deep-TensorRT_V603_DRAW3.exe , eval = deep\gct2020
	engine2 = YaneuraOu-Deep-TensorRT_V603.exe , eval = deep\gct2020
	T1,n800.n800,1216 - 632 - 1152(51.35% R9.39[-2.35,21.14]) winrate black , white = 50.21% , 49.79%
	T1,n1600.n1600,943 - 275 - 840(52.89% R20.09[6.54,33.65]) winrate black , white = 49.8% , 50.2%
	T1,n3000.n3000,534 - 87 - 503(51.49% R10.39[-7.36,28.14]) winrate black , white = 52.65% , 47.35%

- 子ノード選択のAVX2化。
	→ dlshogiのコード、あまりよくないように思うので保留。
	https://github.com/TadaoYamaoka/DeepLearningShogi/blob/feature/avx2/usi/UctSearch.cpp#L1398




■ 2021/4/23


- ふかうら王、エンジンオプションにSoftmax_Temperature、百分率から千分率に変更


■ 2021/4/22


- ふかうら王、エンジンオプションにSoftmax_Temperature追加



■ 2021/2/25


- df-pnでメモリ確保できなかった時のnull check、忘れてたの修正。
	// あとで実装しようと思って忘れてたっぽい。


■ 2021/2/11


- 千日手の処理が非対称なのを修正
	- エンジンオプションのContempt , ComtemptForBlack廃止
	- やねうら王 , ふかうら王ともに、DrawValueBlack , DrawValueWhite に変更
		- やねうら王のほうは、cp , ふかうら王のほうは、0.0~1.0の実数値で勝率を指定
		- ふかうら王、Draw_Value_Black , Draw_Value_Whiteから、DrawValueBlack , DrawValueWhite に変更。
			// dlshogiとは異なる名前になってしまうが、まあええやろ…。

- dlshogiも同様の問題があるのでdlshogiのissueで報告

	千日手の処理が非対称 #36
	https://github.com/TadaoYamaoka/DeepLearningShogi/issues/36

	https://github.com/TadaoYamaoka/DeepLearningShogi/blob/2ec875c037c4abc3e6f5511e2169461cf3457ff4/usi/UctSearch.cpp#L1227

	これだと、例えば、draw_value_white = 1.0(勝ち)、draw_value_black = 0.5(引き分け)の時、先手は千日手を引き分け、後手は千日手を負けだと思って探索するという非対称な探索を行っていることになります。こういう非対称な探索がやりたい機会は現実的にはほとんどないので、これは無意味な設定だと思います。

	現実的には(例えば大会では)、先手番であるなら、引き分けを避けたくて、後手番なら引き分けは0.5勝扱いとみなして、対称的な探索をしたいのです。

	例えば、この時、次のように設定したいわけです。

 	 draw_value_black = 0
 	 draw_value_white = 0.5

	よって、上の当該箇所は、pos->turn() == BLACK ではなく、root_color(探索開始局面の手番) == WHITE になっているべきだと思うのです。


■ 2021/2/4


- TensorRTのモデル、デシリアライズしたものを読み込んだ時に、ドライバのバージョン違いなどが原因で読み込みに失敗した時に、
	デシリアライズからやりなおすコードを追加。
- TensorRTのモデルの読み込みに、FileOperator::ReadFileToMemory()を用いるようにする。
- ReadFileToMemory()の高速化。


■ 2021/2/3


- TRT: 最適化ファイル名からGPU_ID, PCI_BUS_ID削除、TensorRTバージョン追加 #166
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/166
	- TensorRT用にシリアライズしたmodelファイル、ドライバのバージョンが違うと互換性が無いようなので
	ドライバのバージョンをシリアライズしたファイル名に埋め込む。


- "benchmark"コマンド改善
  - ふかうら王で、benchコマンドでassertに引っかかるのを修正。
  - ふかうら王で、benchコマンドで定跡ファイルの読み込みをオフにしていなかったの修正。
  - benchmarkコマンドで、外部からsfen文字列、"startpos moves XXX"のような文字列などを書かれたファイルを読み込めるようにした。


■ 2021/2/2


- ふかうら王でbook.binを使う時、ponderの出力がおかしいかったの修正。
  - ponderの指し手がないときにvectorの範囲外にアクセスしてた。
  (ponderの指し手がMOVE_NONEであることを想定していなかった)

bookfile book.bin
USI_Ponder true
isready
position startpos moves 6i7h 8c8d 7g7f
go btime 64000 wtime 58000 binc 3000 winc 3000


■ 2021/2/1

- NNUE評価関数学習時、Windows環境下でCPUが2つある場合に、論理64コアに負荷が集中する問題を修正した #165
  tanuki-さんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/165


■ 2021/1/26


- V6.02
  - ふかうら王、2手前に思考した時の情報が使えていなかったのを修正。
    - これだけで+R200ぐらい変わるのか…。
    - やっとdlshogiと互角になった。
  - testcmd/normal_test_cmd.cpp追加
    - 指し手生成コマンド(s)は、そちらに移動させる。
    -"test genmoves"コマンド追加
    -"test autoplay"コマンド追加


- ふかうら王、同じ開始局面で手数が戻る時の処理を修正。
  - 自己対局でたまに落ちるのこれであった…。


- MATEエンジンのビルド出力先ディレクトリ名を修正
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/commit/3b84966402dbd0925b1cedf351ef519977f25682


■ 2021/1/25

- cibuild (#163)
  - Android等のビルドスクリプトの修正。
  - Clang/GCCでコンパイル通らなかったの修正。
  - Mizarさんのプルリク :  https://github.com/yaneurao/YaneuraOu/commit/83be784e51fea781cb3ec98149fdb74f66f92070


- DepthLimit , NodesLimitは、このオプションを探索部がサポートしている時だけ反映させるように。
- ドキュメント類の軽微な修正。


- ふかうら王、2手前に思考した時の情報が使えていなかったのを修正。
  - これだけで+R200ぐらい変わるのか…。
  - やっとdlshogiと互角になった。
  

- MainThreadにゲーム開始時のsfenとそこからの指し手を保存するようにした。
  - 探索部によっては必要になる。


- ふかうら王、奇数手詰めにMaxMovesToDrawの値が反映していなかったのを修正。
  - "go"コマンドに対してしか値が反映しないのであった…。


- testcmd/normal_test_cmd.cpp追加
  - 指し手生成コマンド(s)は、そちらに移動させる。
    - test genmoves
  -"test genmoves"コマンド追加
  -"test autoplay"コマンド追加
- source/testcmd/ 追加
  - benchmark.cppはそちらに移動
  - mate_test_cmd.cppもそちらに移動


- 時間固定で思考する、go movetime X サポートしているのに説明書くの忘れていたの修正。


■ 2021/1/22


- 並列メモリクリアの時に何スレッドでやっているのかを出力するようにした。


- "go movetime 100"
  のような"movetime"を指定した場合の時間固定での思考コマンド、ドキュメントに書いたまま実装するの忘れていたの修正。


- ふかうら王、Search::Limits.silentのときに読み筋等の出力を抑制するように。


- ふかうら王、詰んだときに相手の指し手、ponderで返そうとしてアクセス違反になることがあったのを修正。


■ 2021/1/20


- mate.hでinclude忘れ修正。


- df-pn mateルーチンにhash tableありのバージョンを導入
  - df-pnのNodeにrepeatedフラグを追加。
  - 循環が絡まない詰み・不詰を証明した局面だけこのフラグがfalseになる。
  - 延々と合駒を打てる3手詰め局面を用いてデバッグする。

isready
sfen 8k/7P1/8+P/9/9/9/9/9/R8 b 2b4g4s4n4l16p 1
test dfpn

// ↑の局面は1/4ぐらいのnodeで詰みが証明できるが、他の局面ではnps2/3ぐらいになるので全然得してないようである。
// 実際の対局だと違うかも知れないが…。

// 通常のdf-pnだと340万node
solved! , nodes_searched = 3424908
9i9a P*8a 9a8a B*7a 8a7a B*6a 7a6a S*5a 2b2a+ 1a2a 6a5a+ 2a3b B*2c 3b3c 5a5c 3c2d 2c1d+ 2d3e 5c5e 3e2f 5e2e 2f3g 2e3f 3g4h 3f4g 4h3i B*4h 3i2h 4g3g 2h1h P*1i 1h1i S*2h 1i1h 3g1g 1h2i 1g1i 2i3h 1i3i
d

// orderingありでも変わらず…。
solved! , nodes_searched = 3545390
9i9a+ P*8a 9a8a B*7a 8a7a B*6a 7a6a S*5a 2b2a+ 1a2a 6a5a 2a3b B*2c 3b3c 5a5c 3c2d 2c1d+ 2d3e 5c5e 3e2f 5e2e 2f3g 2e3f 3g4h 3f4g 4h3i B*4h 3i2i S*3h 2i1i 4h3g 1i1h P*1i 1h1g 3g2h 1g2h 4g2g 2h3i 2g2i 3i4h 1d4g

// 置換表ありだとその1/4ぐらい。
solved! , nodes_searched = 966759
9i9a B*8a 9a8a+ B*7a 8a7a G*6a 2b2a+ 1a2a 7a6a 2a3b B*2c 3b4b B*3a 4b4c G*5d 4c3c 3a4b 3c4b 2c4a+ 4b3c 4a2c

time = 1051
solved! , nodes_searched = 925689
9i9a P*8a 9a8a B*7a 8a7a G*6a 7a6a+ B*5a
// 置換表、saveで優劣関係を考慮するようにしたら、ちょっと改善したっぽい。

// 不詰を証明するのに単純なdfpnだと8Mほど読まないといけない局面
isready
sfen +B2B1n2K/7+R1/p2p1p1ps/3g2+r1k/1p3n3/4n1P+s1/PP7/1S6p/L7L b 3GS7Pn2l2p 1
test dfpn mem 4096
start mate.
time = 4200
solved! this is no mate. nodes_searched = 3159214
// 証明駒と反証駒導入しないと縮まないな…。
// もうちょっと考える…。

test matebench mode 63 file mate/mate13.sfen nodes 300 num 100000
info string Hash table allocation: Windows Large Pages used.
info string read book file : book/standard_book.db
info string read book done.
info string Start loading the model file, path = eval/model.onnx, gpu_id = 0, batch_size = 32
info string The model file has been loaded.
mate bench :
 num (number of problems) = 100000
 sfen file name           = mate/mate13.sfen
 mate_ply                 = 3
 nodes(nodes limit)       = 300
 verbose                  = 0
 mode                     = 63
 dfpn_mem [MB]            = 1024
 dfpn_hash[MB]            = 1024
read problems..
...........number of problems read = 100000
===== mate_odd_ply =====
test start
 number of times = 100000 , elapsed = 1668 , called per second = 59952
 , solved per second = 0
 solved = 0 , accuracy = 0%
mate_odd_ply test end
===== mate_dfpn1 : Node32bit =====
test start
 number of times = 10528 , elapsed = 2001 , called per second = 5261.37 nps = 1562834
 number of times = 20926 , elapsed = 4002 , called per second = 5228.89 nps = 1553225
 number of times = 31548 , elapsed = 6003 , called per second = 5255.37 nps = 1562167
 number of times = 42196 , elapsed = 8004 , called per second = 5271.86 nps = 1567220
 number of times = 52787 , elapsed = 10005 , called per second = 5276.06 nps = 1568865
 number of times = 63435 , elapsed = 12006 , called per second = 5283.61 nps = 1571204
 number of times = 74237 , elapsed = 14007 , called per second = 5299.99 nps = 1576118
 number of times = 85126 , elapsed = 16008 , called per second = 5317.72 nps = 1581675
 number of times = 95936 , elapsed = 18009 , called per second = 5327.11 nps = 1584355
 number of times = 100000 , elapsed = 18802 , called per second = 5318.58
 , solved per second = 129.454
 solved = 2434 , accuracy = 2.434%
mate_dfpn1 : Node32bit test end
===== mate_dfpn2 : Node16bitOrdering =====
test start
 number of times = 8808 , elapsed = 2001 , called per second = 4401.8 nps = 1294199
 number of times = 17373 , elapsed = 4002 , called per second = 4341.08 nps = 1276750
 number of times = 25915 , elapsed = 6003 , called per second = 4317.01 nps = 1270918
 number of times = 34630 , elapsed = 8004 , called per second = 4326.59 nps = 1274490
 number of times = 43157 , elapsed = 10005 , called per second = 4313.54 nps = 1270817
 number of times = 51867 , elapsed = 12006 , called per second = 4320.09 nps = 1272820
 number of times = 60499 , elapsed = 14007 , called per second = 4319.2 nps = 1272585
 number of times = 69072 , elapsed = 16008 , called per second = 4314.84 nps = 1271336
 number of times = 77795 , elapsed = 18009 , called per second = 4319.78 nps = 1273068
 number of times = 86314 , elapsed = 20010 , called per second = 4313.54 nps = 1271469
 number of times = 95052 , elapsed = 22011 , called per second = 4318.39 nps = 1272732
 number of times = 100000 , elapsed = 23168 , called per second = 4316.3
 , solved per second = 195.874
 solved = 4538 , accuracy = 4.538%
mate_dfpn2 : Node16bitOrdering test end
===== mate_dfpn3 : Node48bitOrdering =====
test start
 number of times = 8796 , elapsed = 2001 , called per second = 4395.8 nps = 1292400
 number of times = 17510 , elapsed = 4002 , called per second = 4375.31 nps = 1286723
 number of times = 26182 , elapsed = 6003 , called per second = 4361.49 nps = 1284066
 number of times = 34852 , elapsed = 8004 , called per second = 4354.32 nps = 1282521
 number of times = 43584 , elapsed = 10005 , called per second = 4356.22 nps = 1283273
 number of times = 52211 , elapsed = 12006 , called per second = 4348.74 nps = 1281233
 number of times = 60875 , elapsed = 14007 , called per second = 4346.04 nps = 1280513
 number of times = 69436 , elapsed = 16008 , called per second = 4337.58 nps = 1278046
 number of times = 77824 , elapsed = 18009 , called per second = 4321.39 nps = 1273538
 number of times = 85458 , elapsed = 20010 , called per second = 4270.76 nps = 1258826
 number of times = 93539 , elapsed = 22011 , called per second = 4249.65 nps = 1252491
 number of times = 100000 , elapsed = 23519 , called per second = 4251.88
 , solved per second = 192.95
 solved = 4538 , accuracy = 4.538%
mate_dfpn3 : Node48bitOrdering test end
info string MateHash Clear begin , Hash size =  2048[MB]
info string MateHash Clear done.
===== mate_dfpn4 : Node32bitWithHash =====
test start
 number of times = 7549 , elapsed = 2001 , called per second = 3772.61 nps = 1120520
 number of times = 15202 , elapsed = 4002 , called per second = 3798.6 nps = 1128236
 number of times = 22911 , elapsed = 6003 , called per second = 3816.59 nps = 1133631
 number of times = 30584 , elapsed = 8004 , called per second = 3821.09 nps = 1135570
 number of times = 38271 , elapsed = 10005 , called per second = 3825.19 nps = 1136917
 number of times = 46029 , elapsed = 12006 , called per second = 3833.83 nps = 1139618
 number of times = 53652 , elapsed = 14007 , called per second = 3830.37 nps = 1138848
 number of times = 61365 , elapsed = 16008 , called per second = 3833.4 nps = 1139851
 number of times = 69100 , elapsed = 18009 , called per second = 3836.97 nps = 1140866
 number of times = 76790 , elapsed = 20010 , called per second = 3837.58 nps = 1141111
 number of times = 84522 , elapsed = 22011 , called per second = 3839.99 nps = 1141987
 number of times = 92148 , elapsed = 24012 , called per second = 3837.58 nps = 1141268
 number of times = 99849 , elapsed = 26013 , called per second = 3838.43 nps = 1141474
 number of times = 100000 , elapsed = 26056 , called per second = 3837.89
 , solved per second = 95.0261
 solved = 2476 , accuracy = 2.476%
mate_dfpn4 : Node32bitWithHash test end
info string MateHash Clear begin , Hash size =  2048[MB]
info string MateHash Clear done.
===== mate_dfpn5 : Node48bitOrderingWithHash =====
test start
 number of times = 6517 , elapsed = 2001 , called per second = 3256.87 nps = 957420
 number of times = 12966 , elapsed = 4002 , called per second = 3239.88 nps = 952628
 number of times = 19537 , elapsed = 6003 , called per second = 3254.54 nps = 957134
 number of times = 25813 , elapsed = 8004 , called per second = 3225.01 nps = 949099
 number of times = 32116 , elapsed = 10005 , called per second = 3210 nps = 945074
 number of times = 38352 , elapsed = 12006 , called per second = 3194.4 nps = 940596
 number of times = 44823 , elapsed = 14007 , called per second = 3200.04 nps = 942437
 number of times = 51386 , elapsed = 16008 , called per second = 3210.02 nps = 945399
 number of times = 57910 , elapsed = 18009 , called per second = 3215.61 nps = 947201
 number of times = 64410 , elapsed = 20010 , called per second = 3218.89 nps = 948174
 number of times = 71000 , elapsed = 22011 , called per second = 3225.66 nps = 950232
 number of times = 77619 , elapsed = 24012 , called per second = 3232.51 nps = 952381
 number of times = 84121 , elapsed = 26013 , called per second = 3233.81 nps = 952929
 number of times = 90686 , elapsed = 28014 , called per second = 3237.17 nps = 953841
 number of times = 97294 , elapsed = 30015 , called per second = 3241.51 nps = 955083
 number of times = 100000 , elapsed = 30842 , called per second = 3242.33
 , solved per second = 149.115
 solved = 4599 , accuracy = 4.599%
mate_dfpn5 : Node48bitOrderingWithHash test end



test matebench mode 63 file mate/mate11.sfen nodes 300 num 100000
mate bench :
 num (number of problems) = 100000
 sfen file name           = mate/mate11.sfen
 mate_ply                 = 3
 nodes(nodes limit)       = 300
 verbose                  = 0
 mode                     = 63
 dfpn_mem [MB]            = 1024
 dfpn_hash[MB]            = 1024
read problems..
...........number of problems read = 100000
===== mate_odd_ply =====
test start
 number of times = 100000 , elapsed = 1930 , called per second = 51813.5
 , solved per second = 0
 solved = 0 , accuracy = 0%
mate_odd_ply test end
===== mate_dfpn1 : Node32bit =====
test start
 number of times = 9651 , elapsed = 2001 , called per second = 4823.09 nps = 1396021
 number of times = 20972 , elapsed = 4002 , called per second = 5240.38 nps = 1518112
 number of times = 32116 , elapsed = 6003 , called per second = 5349.99 nps = 1551960
 number of times = 42973 , elapsed = 8004 , called per second = 5368.94 nps = 1557527
 number of times = 54123 , elapsed = 10005 , called per second = 5409.6 nps = 1570232
 number of times = 65233 , elapsed = 12006 , called per second = 5433.37 nps = 1577475
 number of times = 76506 , elapsed = 14007 , called per second = 5461.98 nps = 1586107
 number of times = 87612 , elapsed = 16008 , called per second = 5473.01 nps = 1588972
 number of times = 98612 , elapsed = 18009 , called per second = 5475.71 nps = 1589707
 number of times = 100000 , elapsed = 18259 , called per second = 5476.75
 , solved per second = 445.26
 solved = 8130 , accuracy = 8.13%
mate_dfpn1 : Node32bit test end
===== mate_dfpn2 : Node16bitOrdering =====
test start
 number of times = 8951 , elapsed = 2001 , called per second = 4473.26 nps = 1259642
 number of times = 17883 , elapsed = 4002 , called per second = 4468.52 nps = 1256582
 number of times = 27001 , elapsed = 6003 , called per second = 4497.92 nps = 1265572
 number of times = 36100 , elapsed = 8004 , called per second = 4510.24 nps = 1268313
 number of times = 45083 , elapsed = 10005 , called per second = 4506.05 nps = 1268328
 number of times = 54092 , elapsed = 12006 , called per second = 4505.41 nps = 1268869
 number of times = 63137 , elapsed = 14007 , called per second = 4507.53 nps = 1269662
 number of times = 72176 , elapsed = 16008 , called per second = 4508.75 nps = 1270155
 number of times = 81395 , elapsed = 18009 , called per second = 4519.68 nps = 1272727
 number of times = 90413 , elapsed = 20010 , called per second = 4518.39 nps = 1272465
 number of times = 99333 , elapsed = 22011 , called per second = 4512.88 nps = 1271205
 number of times = 100000 , elapsed = 22161 , called per second = 4512.43
 , solved per second = 628.717
 solved = 13933 , accuracy = 13.933%
mate_dfpn2 : Node16bitOrdering test end
===== mate_dfpn3 : Node48bitOrdering =====
test start
 number of times = 8981 , elapsed = 2001 , called per second = 4488.26 nps = 1263907
 number of times = 17979 , elapsed = 4002 , called per second = 4492.5 nps = 1263436
 number of times = 26982 , elapsed = 6003 , called per second = 4494.75 nps = 1264668
 number of times = 36166 , elapsed = 8004 , called per second = 4518.49 nps = 1270674
 number of times = 45175 , elapsed = 10005 , called per second = 4515.24 nps = 1270909
 number of times = 54321 , elapsed = 12006 , called per second = 4524.49 nps = 1274265
 number of times = 63425 , elapsed = 14007 , called per second = 4528.09 nps = 1275411
 number of times = 72525 , elapsed = 16008 , called per second = 4530.55 nps = 1276167
 number of times = 81781 , elapsed = 18009 , called per second = 4541.12 nps = 1278785
 number of times = 90816 , elapsed = 20010 , called per second = 4538.53 nps = 1278246
 number of times = 99790 , elapsed = 22011 , called per second = 4533.64 nps = 1277128
 number of times = 100000 , elapsed = 22076 , called per second = 4529.81
 , solved per second = 631.138
 solved = 13933 , accuracy = 13.933%
mate_dfpn3 : Node48bitOrdering test end
info string MateHash Clear begin , Hash size =  2048[MB]
info string MateHash Clear done.
===== mate_dfpn4 : Node32bitWithHash =====
test start
 number of times = 7322 , elapsed = 2001 , called per second = 3659.17 nps = 1059027
 number of times = 14832 , elapsed = 4002 , called per second = 3706.15 nps = 1072538
 number of times = 22439 , elapsed = 6003 , called per second = 3737.96 nps = 1082946
 number of times = 30307 , elapsed = 8004 , called per second = 3786.48 nps = 1098017
 number of times = 38235 , elapsed = 10005 , called per second = 3821.59 nps = 1108191
 number of times = 46164 , elapsed = 12006 , called per second = 3845.08 nps = 1115518
 number of times = 53890 , elapsed = 14007 , called per second = 3847.36 nps = 1116375
 number of times = 61915 , elapsed = 16008 , called per second = 3867.75 nps = 1122517
 number of times = 69795 , elapsed = 18009 , called per second = 3875.56 nps = 1124878
 number of times = 77820 , elapsed = 20010 , called per second = 3889.06 nps = 1128915
 number of times = 85777 , elapsed = 22011 , called per second = 3897.01 nps = 1130945
 number of times = 93684 , elapsed = 24012 , called per second = 3901.55 nps = 1132394
 number of times = 100000 , elapsed = 25607 , called per second = 3905.18
 , solved per second = 320.576
 solved = 8209 , accuracy = 8.209%
mate_dfpn4 : Node32bitWithHash test end
info string MateHash Clear begin , Hash size =  2048[MB]
info string MateHash Clear done.
===== mate_dfpn5 : Node48bitOrderingWithHash =====
test start
 number of times = 6854 , elapsed = 2001 , called per second = 3425.29 nps = 963529
 number of times = 13666 , elapsed = 4002 , called per second = 3414.79 nps = 959821
 number of times = 20559 , elapsed = 6003 , called per second = 3424.79 nps = 962642
 number of times = 27081 , elapsed = 8004 , called per second = 3383.43 nps = 951470
 number of times = 33401 , elapsed = 10005 , called per second = 3338.43 nps = 938247
 number of times = 39474 , elapsed = 12006 , called per second = 3287.86 nps = 924517
 number of times = 45740 , elapsed = 14007 , called per second = 3265.51 nps = 918689
 number of times = 52352 , elapsed = 16008 , called per second = 3270.36 nps = 920366
 number of times = 59202 , elapsed = 18009 , called per second = 3287.36 nps = 925418
 number of times = 66126 , elapsed = 20010 , called per second = 3304.65 nps = 930216
 number of times = 73026 , elapsed = 22011 , called per second = 3317.7 nps = 933997
 number of times = 79968 , elapsed = 24012 , called per second = 3330.33 nps = 937306
 number of times = 86910 , elapsed = 26013 , called per second = 3341.02 nps = 940216
 number of times = 93813 , elapsed = 28014 , called per second = 3348.79 nps = 942560
 number of times = 100000 , elapsed = 29812 , called per second = 3354.35
 , solved per second = 471.891
 solved = 14068 , accuracy = 14.068%
mate_dfpn5 : Node48bitOrderingWithHash test end



■ 2021/1/17


- Clang++12からpragma packで警告が出るようになったので削除
  - 構造体18-bytesで、20-bytes確保されるのが気に食わなくてつけていた。
  - KPPTの学習いまさらやらないから関係なさげ。
  - 関連
    - clang++12における警告抑止措置 #161 : https://github.com/yaneurao/YaneuraOu/pull/161


■ 2021/1/13


- 256手引き分けルールの件、修正。
  - やねうら王通常探索部とふかうら王の両方
  - dlshogiもこのバグがあった。山岡さんに報告済み。

  // dlshogiの場合、デフォルトではleaf nodeで5手詰めは呼び出しているので、その5手詰めで普通1手詰めが漏れることはないので、
  // 256手ルールの256手目で1手詰めがあるのにそれを逃して257手目の局面に到達することはありえない…ということであれば、これは問題とはないならいですね。
  // leaf nodeで5手詰めを呼び出さないエンジン設定にした時に困りますけども。


- 256手引き分けルールに関するコメント追加。

		  初手(76歩とか)が1手目である。1手目を指す前の局面はPosition::game_ply() == 1である。
		  そして256手指された時点(257手目の局面で指す権利があること。サーバーから257手目の局面はやってこないものとする)で引き分けだとしたら
		  257手目(を指す前の局面)は、game_ply() == 257である。これが、引き分け扱いということになる。

			pos.game_ply() > limits.max_game_ply

		 で(かつ、詰みでなければ)引き分けということになる。

  関連)
    多くの将棋ソフトで256手ルールの実装がバグっている件
    https://yaneuraou.yaneu.com/2021/01/13/incorrectly-implemented-the-256-moves-rule/


■ 2021/1/11


- ふかうら王、mate関連のmax_moves_to_drawはisready応答で設定するように変更。
  - root node , leaf node用のmate solverの初期化を抽象化したのでmate solverの差し替えが比較的容易になった。


- ふかうら王、5手詰めに関して、MaxMovesToDrawの影響をちゃんと考慮するように。
  - MateOddPly、class化はされているので、draw plyだけ設定できればよさげ。

- ふかうら王、宣言勝ちのテストする
  - 将棋所とShogiGUIでどうなるか
  	-			sync_cout << "info score mate 1 pv MOVE_WIN" << sync_endl;
    - 将棋所、"MOVE_WIN"はそのまま読み筋に出力された。
    - "score mate"の"score"を書き忘れていたの修正。
    - ShogiGUIのほうは"MOVE_WIN"には非対応のようで、対応していない文字に関しては無視されるようである。
      - "rep_draw"とかは以前ShogiGUIの掲示板で伝えたから対応してもらえているのか…。そうか…。

- df-pnのmax_draw_plyによる制限、and nodeでの扱いが間違っていたので修正。
  - and nodeでは、例えば256手ルールにおける257手の局面のand node側の手番で、指し手がある(詰みではない)時に不詰扱い。
  - 「この指し手がある」という条件が考慮に入っていなかった。
  - or nodeであれば、257手目の局面で不詰(自分が詰んでいる可能性もあるが、自分が詰んでいる場合も
    いずれにせよ相手は不詰だから不詰扱いで問題ない)

- NNTensorRT::release() のコード、cudaGetDevice()でdevice id退避させてるのは、あまり良くないと思うのでお掃除。
  // Mizarさんのcommitに含まれていたコード。



■ 2021/1/10


- ふかうら王、dlshogi 2021/01/09へのキャッチアップ
  ※ 大改造につき、何かバグってる可能性がある。あとでなおす。

  cuDNN版を廃止 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/2134eedf3e1d8f37bab12444e55763a83eff1027
    - ふかうら王、元から対応してなかった。
  ノード管理の変更 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/f6d8ee9392c64e4696fab13da0bbd3e73b23c6d9
  mutex pool : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/aedc38482e2d240c6a2983d6d409fb8ef53de991
    - これは適用済み
  Draw_Ply対応 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/b17821705f90fbc0ef64e519f84355e294ed630e
    - ふかうら王、対応済みであったが、df-pnの詰将棋では対応してなかったので修正した。

  doMoveでgamePlyをインクリメントする : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/4827213e16c88150ab9312f17907d3eb4f132772
  undoMoveでgamePlyをデクリメントする : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/b62363b54b79d17c7b360e6bb9d05026c3b47775
    - 私が報告したAperyのバグ(仕様?)

  visited_nnrateの加算にノード展開チェックは不要 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/10faf5f4d8383ffdf57c10d5e2dccd1563cf1893
  未使用の引数削除 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/37a8424b17876f0bb16b0ca2e46bcab744d6437a
  ノードの詰みなどの状態チェックを再帰呼び出しの前に行う : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/070cc1217c645796844b8c16d876d93bf8063482
  ルートでの詰みチェックを削除 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/4d3637f3194d249e5a1208e1de943b13e6bf070e
    - これは残しておく。
  リファクタリング : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/671f6d0746389b8811c11e29ebd6d037978a4d03
  未使用コード削除 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/5357f1010149ec841e679485c0922d6210950166
    - 関係なさげ

  WinCountType → dlshogiに倣ってWinTypeに変更

  PrintInfo.cppのコード整理
    - ValueWinMoveCount削除 → 整理したら要らなくなった。

  stopがきたとき、EvalNode()呼ばずにバックアップしてるのまずい気がする…。修正した。

  ChildNumType導入。

  dtype_one,dtype_zero廃止。
    - fill_nで 1.0fと書かないと警告でるので、廃止しないでおく。

  MoveCountType u32にしたら、NOT_EXPANDEDがすごく大きな数になってしまい、dlshogiと違うところで結構ハマるな…。

  宣言勝ちの時、そのpvを出力する。
			sync_cout << "info mate 1 pv MOVE_WIN" << sync_endl;

- MaxMovesToDrawを超える手順の詰みは不詰扱いになっているかのテスト。
  - 150手引き分けにして、140手目において20数手の詰みがある局面を思考させてみる。

DebugMessage true
MaxMovesToDraw 150
isready
position startpos moves 6i7h 8c8d 7g7f 8d8e 8h7g 3c3d 7i6h 2b7g+ 6h7g 4a3b 3g3f 3a4b 5i6h 7a6b 2g2f 4b3c 3i4h 7c7d 4g4f 9c9d 2i3g 6b7c 4i3h 7c6d 2f2e 7d7e 7f7e 6d7e 2e2d 2c2d P*2e P*7f 7g8h 8e8f 2e2d 8f8g+ 8h8g P*2b 2h2e P*8f 8g9h 7e6d 4h4g 5a5b 2e2i 9d9e P*8h 9e9f 9g9f B*7d 6h5h 7d9f 7h6h 8f8g+ 9h8g 9f8g+ 8h8g 9a9i+ 6h7h 9i8i 2i8i S*7g P*7i 8b9b L*9i P*9h B*8c 9b9g+ 8c6a+ 5b6a B*4a 6a7b G*8h 7g8h+ 7h8h 9g9c 9i9h 9c7c 4a3b+ 7f7g+ 8h7g 7c7g G*7h 7g7c 3b4a N*5e 4a5a 5e4g+ 3h4g S*3h S*4i B*2i N*8d 7b8c 5a7c 6d7c 4i3h 2i3h+ R*4h 3h3i 8d9b+ S*3h 9h9c+ 8c7b 5h6h 8a9c 8i9i 9c8e 9i9c+ 3h4g+ S*8c 7b6b 4h4g G*4h 9c8b 7c8b 8c7b+ 6b7b 9b8b 7b8b S*9c 8b9c P*9d 9c9d P*9e 9d9e S*8f 9e8d 8f8e 8d8e 8g8f 8e8f 7h7g 8f9g P*9h 9g9h P*9i 9h9i 4g4h
go infinite



■ 2021/1/9


- ふかうら王、GPU周りの改善
  - Mizarさんのプルリク
  - deep: 複数デバイス検知周りの改善 #159 : https://github.com/yaneurao/YaneuraOu/pull/159

  deep/nn : モデル読込中の gpu_id, batchsize を出力
  出力する項目の追加。

  TensorRT : 存在しないCUDAデバイスを使おうとした時のエラー検知
  cudaSetDevice() した時のエラー検知、これだけだと存在しないデバイスのスレッド数を設定した場合にエンジンがエラーで落ちるだけなので、後述のコミットで緩和を試みています。

  TensorRT : cudaFree() の際、一時的に cudaMalloc() したデバイスに変更する
  b2c38ec の補強、念の為、cudaFree()後に元のデバイスに戻るようにする。

  TensorRT: シリアライズ時、ファイル名に device_name, pci_bus_id を含める
  gpu_idが同じデバイスがずっと同じデバイスとは限らないため、ファイル名に device_name, pci_bus_id を含めて混同の可能性を薄める。

  TensorRT : info string gpu_id , device_name , pci_bus_id
  NNTensorRT::load_model() の際、gpu_id , device_name , pci_bus_id の情報を出力する。

  indent YaneuraOu_dlshogi_bridge.cpp

  deep : 対応デバイス数以上のIDに設定されたスレッド数を無視する
  対応デバイスの数を検知し、デバイス数以上のIDに設定されたスレッド数を無視する事で、設定の食い違いによるエラー落ちを軽減する試み。
  同じ設定で、8GPUでも2GPUでも1GPUでもそこそこ動く構成が出来るようにしたい。
  ORT_DMLはその影響で、D3D12へのライブラリ依存を追加。とは言え、DirectMLはそもそもDirectX12対応が必須なので…。(自分の環境でしかテストしていないので、特にORT_DML版の方は何か拙い部分があるかもしれません)
  cf. Direct ML#minimum_requirements - onnx runtime

  The DirectML execution provider requires any DirectX 12 capable device. Almost all commercially-available graphics cards released in the last several years support DirectX 12. Examples of compatible hardware include:

  NVIDIA Kepler (GTX 600 series) and above
  AMD GCN 1st Gen (Radeon HD 7000 series) and above
  Intel Haswell (4th-gen core) HD Integrated Graphics and above
  DirectML is compatible with Windows 10, version 1709 (10.0.16299; RS3, “Fall Creators Update”) and newer.



- Makefile修正。evallearnを指定した時だけ関連ソースファイルをコンパイルするように。
  - そうでないときのビルド時間、少し短縮される?


■ 2021/1/8


- やねうら王 V6.01
  - V6.00→V6.01の主な更新内容
    - ふかうら王、マルチGPUに対応
      - 対応したつもりが対応できてなかった。
    - ふかうら王、探索開始局面でのdf-pn詰将棋を実装
    - ふかうら王でgo ponder で、stopもしくはponderhitを待たずにbestmoveを返す事があった
      - 関連 : https://github.com/yaneurao/YaneuraOu/pull/155 : go ponder で、stopもしくはponderhitを待たずにbestmoveを返す事があった #155
    - ふかうら王で評価関数ファイルの読み込み時にmodel pathを出力するようにした。
    - ふかうら王、ORT_MKL に エンジンオプション InterOpNumThreads, IntraOpNumThreads を追加。 #154

    - やねうら王、PV出力まわりの改善。(検討モードやponderで"stop"が来る前に最終的なPVを必ず出力するように)

    - やねうら王探索部、Stockfish 2021/01/05へのキャッチアップ
        engine1 = YaneuraOuV600.exe , eval = suishou_wcso1
        engine2 = YaneuraOuV601.exe , eval = suishou_wcso1
        T2,b1000,1392 - 122 - 1486(48.37% R-11.35[-22.01,-0.7]) winrate black , white = 50.87% , 49.13%
        T2,b2000,1455 - 149 - 1396(51.03% R7.19[-3.51,17.89]) winrate black , white = 52.61% , 47.39%
        T2,b4000,1174 - 162 - 1224(48.96% R-7.25[-18.92,4.43]) winrate black , white = 50.83% , 49.17%
        // 弱くはなってなさそう。

    - NNUEの学習でHalfKPE9以外のfactorizerが無効化されている件、修正。


- makebookコマンドは、EVAL_LEARNかつENABLE_MAKEBOOK_CMDが有効な時だけ使えるように変更。// NNUEのLEARN版などで使える。
- makebook2021.cpp書きかけ。
- TensorRT : release()のときも安全のためcudaSetDevice()呼び出すようにした。


■ 2021/1/7


- TensorRT: cudaSetDevice()の呼び出しタイミングの調整。


■ 2021/1/6


- TensorRT: cudaSetDevice() #157
  - ふかうら王、複数GPUがあるときに2つ目のGPU以降を使わなかったのを修正。
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/157



■ 2021/1/5


- Stockfish 2021/01/05へのキャッチアップ
  - Assorted parameter tweak : https://github.com/official-stockfish/Stockfish/commit/c57c71bf5c56665b0339fa983665bdef4bf8a099
  - Remove razoring : https://github.com/official-stockfish/Stockfish/commit/8ec97d161ed82b7c1d8f1f05c305e9a55d8ccff3
    - has become ineffective now.
  - Simplify condition for assigning static-eval based bonus : https://github.com/official-stockfish/Stockfish/commit/1f3b5b8b54fbf9d3b74bcba831466eeb1104b421
  - Assorted search and eval parameter tune : https://github.com/official-stockfish/Stockfish/commit/9fb6383ed804d0bc86d52b07def14352f44eb5b4
  - Increase reduction in case of stable best move : https://github.com/official-stockfish/Stockfish/commit/a88a38c3a91749181ffa5d6dc0af7314a70a1c41
  - PARAM_FUTILITY_RETURN_DEPTH 8→9に変更
  - PARAM_PROBCUT_MARGIN1 199→194に変更
  - 弱くはなってなさそう。(計測中)

- やねうら王、go ponderやgo infiniteで詰みを見つけた時に、その詰み筋をstopが来るまで出力しないことがあったのを修正。
    isready
    sfen l6nl/6k2/+P3p2p1/1B1p1Pp1p/1p7/7nP/3P1SP1L/2+p3GK1/L6+r1 b B2G2S5Prgs2np 0
    go infinite

    isready
    sfen l6nl/6k2/+P3p2p1/1B1p1Pp1p/1p7/7nP/3P1SP1L/2+p3GK1/L6+r1 b B2G2S5Prgs2np 0
    go ponder
    ponderhit
    stop

- やねうら王、詰みを見つけてからgo ponder,infiniteのときはmain以外の探索スレッドが停止していなかったのを修正。

- やねうら王、"go mate"コマンド対応コード削除。
  - checkmate XXXを返せていないので中途半端な対応は良くないと思った。


- ふかうら王、root nodeでのdf-pnによる詰み探索実装
  - エンジンオプションの"RootMateSearchNodesLimit"
  - これが0だと詰み探索を行わない。最大で指定したノード数まで詰み探索を行う。
  - ここで指定した数×16バイト、詰み探索用に消費する。
  - 例) 100万を指定すると16MB消費する。
  - これ、ponder中は延々と調べたい気はするが…。
    - 手順を記憶していないので長く読んで飛車を捨てる手からの詰み手順を見つけたとして
    2手後の局面がやってきたときに詰みを発見できなくて頓死する可能性があるの嫌だな…。
  - dlshogi、dfpnは19手・300msがデフォルト値になってて、これが最小値かつ最大値になっている。

- ふかうら王、go infiniteで詰みを見つけた時にPV出力せずにstopを待つの修正。

- NodeMutexs → MutexPoolに名前変更



isready
sfen ln1gkg1nl/6+P2/2sppps1p/2p3p2/p8/P1P1P3P/2NP1PP2/3s1KSR1/L1+b2G1NL w R2Pbgp 42
go btime 1000 wtime 1000 byoyomi 3000

// 反証駒 : https://tadaoyamaoka.hatenablog.com/entry/2018/05/31/001822
> 下の19手詰めの局面で最大深さまでループが発生していたため、優越関係を反証に利用すると、最大深さに達した局面が不詰み扱いになるため、誤って不詰みと判定されていた。

isready
sfen ln6K/1ksPg1sG1/5s2p/ppp3p2/9/P1P3P2/4+p3P/1+r7/LN3L2L w RBSb2g2n7p 1
go btime 1000 wtime 1000 byoyomi 3000

info nps 32 time 371 nodes 12 hashfull 0 depth 3 score cp 2327 pv 8h2h B*5e B*7c
info string solved by df-pn , mate = G*2a , mate_nodes_searched = 83649
info score mate 27 pv G*2a 2b2a G*1b 1a1b 3b2a 1b2a 8h2h B*2g B*3b 2a1b G*2a 1b1c P*1b 1c2d 2h2g R*2e B*4b S*3c 4b3c 2d3c N*4a 3c2d S*1c 2d1e 1c1d 1e2d 2g2e
bestmove G*2a
// 371[ms]で詰みを見つけた。



■ 2021/1/4



- HalfKPE9以外のfactorizerが無効化されている件、修正。
  - tanuki-さんからの指摘
  - HalfKPE9以外のfactorizerが無効化されている #156 : https://github.com/yaneurao/YaneuraOu/issues/156



- ふかうら王でgo ponder で、stopもしくはponderhitを待たずにbestmoveを返す事があった
  - 関連 : https://github.com/yaneurao/YaneuraOu/pull/155 : go ponder で、stopもしくはponderhitを待たずにbestmoveを返す事があった #155

- ふかうら王で評価関数ファイルの読み込み時にmodel pathを出力するようにした。


- ORT_MKL に エンジンオプション InterOpNumThreads, IntraOpNumThreads を追加。 #154
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/154
    InterOpNumThreadsはグラフ全体のスレッド数(default値1)、
      IntraOpNumThreadsはノード内の実行並列化の際のスレッド数設定(default値4)。
      使用スレッドを変更したい時は IntraOpNumThreads の設定値を変更する。
      InterOpNumThreads の効果はよく分からない。ORT_MKLでは効果無いかも。
      cf: https://tadaoyamaoka.hatenablog.com/entry/2020/06/06/190259
      TadaiYamaokaの日記 - 2020-06-06 - ONNX Runtimeを使ってみる その2(性能測定)


■ 2021/1/1


- やねうら王 V6.00
  - やねうら王 詰将棋エンジン追加
    - df-pnを用いた新しい詰将棋ルーチンを用いたもの。
    - 30手前後の詰将棋は従来のソフトより速く解ける(メモリはわりと必要)
    - 詰み・不詰を100%間違わない。不詰(nomate)と出力された場合、100%不詰。
    - 単玉問題に対応している。
  - ふかうら王(dlshogi互換エンジン)追加
    - CPU版、DirectML版、Intel MKL版、TensorRT版を用意。
    - 強さ的には本家dlshogiと同等ぐらいのはず。
    - MultiPVに対応している、やねうら王の定跡ファイルがそのまま使える、64スレッド超えにも対応しているなど、
      本家dlshogiより優れている点もある。
  - やねうら王の探索部の改良
    - やねうら王V5.00から比べると+R100以上。
    - PV(読み筋)を思考の最後に必ず出力するようにした。
    - 詰将棋問題(実戦形式)の生成に対応。
      - やねうら王公式からクリスマスプレゼントに詰将棋500万問を謹呈 : http://yaneuraou.yaneu.com/2020/12/25/christmas-present/
    - 詰みを見つけてから、その2倍のdepthは回すようにしていたが、これだと最短手順を見つけられないことがあるので
      2.5倍のdepthまで継続して探索するようにした。

2020年


■ 2020/12/31


- 詰みを見つけた時にPVの出力を省略することがあったのを修正。
  - issue #139 : https://github.com/yaneurao/YaneuraOu/issues/139
    // おかしいのではと言われている局面
    isready
    sfen l6nl/6k2/+P3p2p1/1B1p1Pp1p/1p7/7nP/3P1SP1L/2+p3GK1/L6+r1 b B2G2S5Prgs2np 0
    go btime 0 wtime 0 byoyomi 20000

- PVはstopであろうとbyoyomiであろうと必ず最後に出力することにした。(ConsiderationModeの時は別だが)
  - 電竜戦で、Qhapaqチームがやねうら王を合議に使ってmateの時にPVが出力されてなくて困ったという話があった。
    http://qhapaq.hatenablog.com/entry/2020/11/22/085822

- 詰みを見つけてから、その2倍のdepthは回すようにしていたが、これだと最短手順を見つけられないことがあるので
  2.5倍のdepthまで継続して探索するようにした。


- ふかうら王、子ノードの構造体からstd::mutexを取り除く。
  - メモリ使用量10%ぐらい削減?
  - dlshogiのbranch : https://github.com/TadaoYamaoka/DeepLearningShogi/compare/feature/new_node_manage
  - 将棋AIの進捗 その52(探索部の改良): https://tadaoyamaoka.hatenablog.com/entry/2020/12/30/113425
  > インデックスはノードに保持しなくても、探索中の局面のハッシュから導出した方がメモリの節約になる(←Discordでのやねうら氏からの指摘)。


- ふかうら王、UCBの定数をループの外で計算する
  - dlshogi , UCBの定数をループの外で計算する : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/f0b7710e16a5aa12af6c2004bf1bc9abcbf31f5e
- VSのプロジェクト構成間違っていたの修正。
  - Debug-Deep-ORT-CPUなど
  - 直近のプルリクで追加されたもの
- nn_types.hにあったincludeをnn_types.cppに移動
- VSのプロジェクトのeval/dlshogiフィルター削除


- .editorconfig #151
    *.props: no insert final newline
    Makefile: 4 tab indent
    *.mk: 2 space indent
    *.hpp: 4 tab indent
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/151


-  badge for DeepLearning CI #150
  - #149 依存
  - README.md への DeepLearning CI ビルド結果バッジの表示部分です。
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/150


- Pr cibuild #149
    ビルドスクリプトの YANEURAOU_ENGINE_MATERIAL*, YANEURAOU_MATE_ENGINE 対応
    GitHub自動ビルド用タスクランナーの修正
    Ubuntu18.04 → Ubuntu20.04
    DeepLearningビルド対応 (MSBuild)
    ビルド対象タスクの調整
    Releaseでの YANEURAOU_ENGINE_MATERIAL* の分離
    DeepLearning Onnx Runtime版でのCPU版構成の追加
    Onnx Runtimeソースコード内部での略称に倣い、Onnx Runtimeの略称を ONNX から ORT に変更
    従来の ONNX ターゲットは ORT-DML (Onnx RunTime DirectML) に名称変更
    ORT-CPU (比較的プレーンなCPU実行用)、ORT-MKL (Intel Math Kernel Library での高速化を図ったCPU実行用) を追加
    DeepLearning 版を clang++/g++ 上でビルドするためのコード修正
    指定不足ヘッダの補完
    例外禁止を回避するため、throwを使って記述していた部分の措置
      * - ORT-CPU, ORT-MKL, ORT-DML
      従来のONNXはORT-DML (Onnx RunTime DirectML)にリネーム
      ORT-CPU (ORTのCPUデフォルト動作) と ORT-MKL(Intel Math Kernel Library,
      CPU向け)を追加
    * - Makefile
    * - Android.mk
    * - build scripts
    * - runner settings
    * - deep fix
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/149


- bench.py: PvInterval 0 #148
    bench.py 実行時、エンジンオプションで PvInterval 0 を指定します。
    実行画面への影響は特に無い部分ですが、
    ファイルに出力されるログからPVをする時に役立つ場合もあるかと思います。
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/148


■ 2020/12/30


- やねうら王詰将棋エンジン、単玉対応

- magic bitboardで利きを求めるコード、盤外に玉がいる(SQ_NB)時に、飛車と角の利きがおかしくなるの修正。
  - これ、Aperyのコードそのままなのに…。
	  auto bb = rookEffect(SQ_NB,ZERO_BB);
	  std::cout << bb << std::endl;
  がなぜにZERO_BB相当でないのか…。

  - 詰将棋ルーチンで単玉問題で解けないことがあったのはこれのせいで、攻め方の玉が盤外だと王手がかかっていると誤認識して、
  回避かつ王手になる指し手がないということで1つ目のnodeで不詰だと返すことになっていたため。


■ 2020/12/29


- ふかうら王、ponderhit後、bestmoveを返さない件、修正。
  - Mizarさんからの報告。


- ふかうら王、Technology Preview #02
  - TensorRT対応(これはすでにMizarさんによって動作確認が完了しているみたい)
  - leaf nodeで5手詰め
    - MateSearchPlyエンジンオプション追加。
		  leaf node(探索の末端の局面)での詰み探索を呼び出す時の手数
		  奇数手詰めルーチンをを呼び出す。
		  0 なら 奇数手詰めを呼び出さない。
  - 宣言勝ち対応
  - PonderMove、bestmove出力してたの修正。
- やねうら王詰将棋エンジンの追加でコンパイルエラーになっていたの修正。



- やねうら王詰将棋エンジン追加

  メリット
  ・置換表を使わないので、詰み・不詰を間違えない。
  ・合流を処理しないので、千日手絡みのバグが起きようがない。
  ・nps、置換表を使う実装と比べてわりと速い。
  デメリット
  ・メモリ凄い速度で消費する:face_vomiting: 
  ・GC未実装

- MATE_ENGINE → TANUKI_MATE_ENGINE    // tanuki- 詰め将棋solver    (2017/05/06~)
 に変更。

- YANEURAOU_MATE_ENGINE                 // やねうら王 詰将棋solver (2020/12/29~)
 追加。

やねうら王詰将棋エンジンへのコマンドの例)
  NodesLimit 10000
  isready
  sfen ln1gkg1nl/6+P2/2sppps1p/2p3p2/p8/P1P1P3P/2NP1PP2/3s1KSR1/L1+b2G1NL w R2Pbgp 42
  go mate 100000

  NodesLimit 0
  isready
  sfen l2g5/2s3g2/3k1p2p/P2pp2P1/1pP4s1/p1+B6/NP1P+nPS1P/K1G4+p1/L6NL b RBGNLPrs3p 1
  go mate 100000

- mate_dfpn32.cpp , mate_dfpn64.cpp統合
  - mate_dfpn.hppに一本化
  // 似たファイル2つあると保守が大変なので

- USI::move(vector<Move>) 追加


■ 2020/12/28


- DFPN詰将棋ルーチン、Clangでエラーが出ていたのを修正。
- MateDfpnSolverInterfaceに仮想デストラクタ書くの忘れてたの修正。


- DFPN詰将棋ルーチン実装
  32bit版と64bit版を用意した。
  オーダリングは実験中。
  32bit版はメモリ使用量がおよそ半分で済むが、Node数が32bitまでしか扱えない。
  // ふかうら王で使うために実装した。


- mate_1ply()の両王手の時のバグ修正。
  - dlshogiの山岡さんからの指摘。
  - ただ、レアケースかつ、両王手・開き王手・離し飛車(角)の筋は、チェックはしてもしなくとも強さにほぼ影響がないので
  この部分はコメントアウトしてしまうことにした。

  engine1 = YaneuraOuNNUE_20201228.exe , eval = suishou_wcso1      ← 改造前
  engine2 = YaneuraOuNNUE_20201228no_dc.exe , eval = suishou_wcso1 ← 改良後
  T2,b1000,1447 - 116 - 1437(50.17% R1.2[-9.44,11.84]) winrate black , white = 51.49% , 48.51%
  T2,b2000,700 - 68 - 682(50.65% R4.53[-10.84,19.89]) winrate black , white = 50.8% , 49.2%  
  T2,b4000,302 - 52 - 316(48.87% R-7.87[-30.85,15.11]) winrate black , white = 51.29% , 48.71%

- Move16関係の関数追加。


■ 2020/12/25


- 初期化されていない max_batch_size の値(0)を参照してメモリ確保していたため、NNTensorRT::forward() での評価の際にエラーを起こしていました。
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/147


■ 2020/12/24


- KIF_CONVERT_TOOLS削除。
  - 使ってない & メンテしてないのでいったんold_engines/extraに移動。
  - また使うときに持ってくる。

// 棋譜の変換などを行なうツールセット。CSA,KIF,KIF2(KI2)形式などの入出力を担う。
// これをdefineすると、extra/kif_converter/ フォルダにある棋譜や指し手表現の変換を行なう関数群が使用できるようになる。
// #define USE_KIF_CONVERT_TOOLS


- tanuki-詰将棋ルーチン用のベンチコマンド移植
  - test matebench2


- test command整理
  - source/extra/test_cmd.cpp削除。
  - コマンド種ごとにファイルを分割する。
  - デザパタのDecoratorみたいな感じで新たなコマンドをplugできるようにする。
  - 使ってないコード(KPPT用)、ばっさり削除していいんじゃないかな。
      old_engines/test_code/test_cmd20201223.cpp
    に移動させて、いま使っているものだけ新規に書き直す。
  - evalmergeとか、KPPTでしか使ってないものもはや要らないのでは…。
  - test perftも、perftコマンド探索部にあるから、もはや不要。
  - test rp : ランダムプレイヤーによる対局コマンドも、mate_test_cmd.cppに対局のコードはあるからそれを参考にしたほうが良い。

  - mate/mate_test_cmd.cpp 追加。
    // 詰み関係のテストはここに追加。新規にいくつかコマンドを追加する。

  - test genmate移植。少し書き直す。
    - sfen化してmate_odd_ply()を呼び出さないとまずいことに気づいた。修正する。

  - 千日手の開始局面さかのぼり問題があるのでroot_game_plyが必要だとわかったので、
    MateSolverとしてクラス化する。
    USE_MATE_N_PLY → USE_MATE_SOLVER に変更。

  - mate.cppのコード整理。
  - mate_repetition()追加。

  - test matebenchコマンド移植。
  - test matedfpnコマンド追加。
    // df-pnルーチン、現在調整中につき非公開
  - kif_convert_tools.cppコンパイル通らない。Mizarさんに相談する。




■ 2020/12/23


- genmate、mutexの場所間違えていたの修正。
- matebenchコマンド追加。

- エンジンによっては"Threads"オプションが存在しないことがあるので修正。


■ 2020/12/22


- test_cmd.cppにて、thread_numを上限としたfor文のカウンタにintを使用していたのをsize_tに変更(警告対応) #145
  - たまさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/145

- define templated mated_even_ply() : Avoid C++20 features (#146)
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/146


■ 2020/12/21


- N手詰めルーチン修正
  - 100万局面ほど5手詰め作ってみたが、正常に動いているようであった。

- "test genmate"コマンド、ファイル書き出しの排他忘れてたの修正。


- 詰将棋生成コマンド"test genmate"追加
  - 使い方は、USI拡張コマンド.txtに書いた
  - Mateルーチンのテスト用
  - うまく生成できているっぽい。


- 奇数手詰めルーチン追加
  - Mate::mate_odd_ply()
  - dlshogiに存在するやつ。ふかうら王をdlshogiコンパチにするために必要。
  // デバッグ中
  - "test genmate"コマンド追加。(あとで消す)
  - is_mate_in_1ply_imp -> mate_1ply_impにrename
  - mate1ply -> mate_1plyにrename

- ふかうら王 dlshogiの修正をマージ
  - コピーからムーブに変更 : https://github.com/TadaoYamaoka/DeepLearningShogi/commit/50357035056a6c8da770d00d1d32bca8540681d9


- NNUE-LEARNでGENSFEN2019をdefineしてビルドするように変更。
- プロジェクト構成にDebug NNUE-LEARN追加
- LEARN版でGENSFEN2019をdefineするようにした。
- GENSFEN2019をdefineしたときにコンパイルエラーになっていたの修正。



- Makefile、修正忘れを修正。

- プロジェクト設定のRelease-NNUE-GEN削除
  - もはや使ってないので

- llvmのリンクオプション最適化
	https://github.com/yaneurao/YaneuraOu/pull/100
	llvmのリンクオプション最適化
	ちゃんと検証してからMakefile書き直す。
  → Mizarさんにお願いしてみた。
  → 以前やって、効果がなかったとのこと。
  → この件は、忘れよう。

- StockfishのEvalListの除去、これ将棋ではやる価値がないように思うのでスルーでいいや。

  Remove EvalList
  https://github.com/official-stockfish/Stockfish/commit/9b4967071e2fb116673820127522bc43d01d2257
  Use incremental updates more #3157
  https://github.com/official-stockfish/Stockfish/pull/3157



- config.h整理

- USE_MAKEFILEのシンボル削除


- ふかうら王、"GenerateAllLegalMoves"に対応。

- エンジンオプションの"GenerateAllLegalMoves"の処理、エンジン側に移動


■ 2020/12/20


- 詰み関係の処理を分離。
    source/extra/mate/ を
    source/mate/ に移動
  - Positionクラスから詰め将棋関係の関数をnamespace Mateに移動。
  - mate/mate.cpp追加。


- move_picker.cppの指し手のsortにsuper_sort導入。
  - TokusiNさん作のSuperSort。
  - sortが少し高速化されるらしい。
  - 安定ソートではないので並び順が以前のとは異なるから、benchコマンドの探索ノード数は変わる。
  - AVX2専用なので、AVX2とSSE4のようにCPUによってbenchコマンドの探索ノード数は変わる。(ので少し不便)
  - デフォルトではオフにしておく。


- NNUEの実験用に作ったarchitecturesをold_engines/nnueに放り込んでおく。
  - 2年近く前に作ったやつ。


- ふかうら王に引き分けの手数反映

dlshogi、draw_plyが未実装になっているような?

  // これ、PositionクラスのgamePly、現局面のgamePlyを返すように修正して、gamePlyがdraw_ply以上のときは、
  // UctSearch()で引き分け扱いするだけなので対応するのは簡単だと思うのですが、このタイミングだと、CreateChildNode()したあとなので
  // それが嫌なんですかねー😅 ← どうするのがベストなのかわかってない。

- SearchLimit → SearchLimitsとrename
  - draw_ply → max_moves_to_drawに変更。やねうら王のオプション名と同じにしておかないと紛らわしいと思ったので。
  - node_limit → nodes_limit
  - node_searched → nodes_searched // Stockfishで変数名、nodes_XXXとかになっているのでそれに合わせたほうが良さげ。

- hashfullの判定をponderより先にしないと、メモリ使い切って死ぬので修正。
- NodesLimit利いてなかったの修正。

- 全部詰みの時にもっと速く指せないのか…。
    - 詰将棋ルーチンがあればいいのか。
    - そのとき最短手数での詰みを見つけて欲しい気はするが。

- 後手の時の評価値、符号が反転してる気が? → そうでもなかった。



- ふかうら王、PVの出力と探索停止の判定は専用スレッドが行うように。
  - GPUがbatchで処理してるからお留守なことがあり、一定のタイミングでチェックできない。
    - 専用スレッドで行うことにする。
  - GC用のスレッドもやねうら王側で生成することにする。
    - スレッド管理のコードがGCから消せたのでとても綺麗なコードになった。
    → GCがガーベジ中だとスレッドの終了ができなくて長い時間がかかるということはあるのか…。そうか…。よくなかった
    → これrevertする。

    
- 持ち時間制御ムズすぎ、クソワロタ

  ふかうら王の時間制御、やねうら王のタイムマネージメントをそのまま持ってきたんですけど、よく時間切れになります😥
  dlshogiはこのへん、大雑把にbestmoveを返すようにしてあって、秒読み3秒のときに2.9秒まで使おうとかそんなセコイことは眼中にないのかも知れませんが、これはこれでわりと重要だと思うので頑張って書いているのですが、とてもムズかしいです😥

  狙った時間で探索を停止しようにも、探索スレッドが探索中で、EvalNode()から返ってきてないから、bestmoveを返せないためです。
  探索中は、Eval用のqueueにガンガン局面を積むので、これが終わるのを待っていると平気で1秒ぐらい経過します。

  そこで探索が停止(interruption == true)させないといけないことがわかった時点で、次のEvalNode()はskipするようにしました。
  それでも、他のスレッドがガンガンqueueに積んでるので、500[ms]ぐらいオーバーします。

  そもそも探索の停止を確認するのはdlshogiではどれか1つのスレッドだけになっているので、そのスレッドがEvalNode()で時間がかかり、チェックする間隔が甘くなることもあります。これでbatch sizeによっては数百[ms]の誤差がでます。

  仕方ないので、やねうら王では、探索の停止用のスレッドを一つ回すことにしました。

  あと、将棋所で動かしているとなぜかnpsが出ないことがあります。バックグラウンドプロセスなのでプロセスの優先度が低く、EvalNode()の処理(GPU側?)が遅くなっているのかも知れません。

  npsが下がると、EvalNode()に時間がかかるということで、このため800[ms]ぐらいのオーバーしうるので、マージンをどうとっても時間切れ負けする時は時間切れ負けになります。
  先行してbestmoveだけ返そうと思えば返すことはできるのですが、探索スレッドを停止させてからでないとvirtual lossが加算されたままになっています。

  結論的にはタイムマネージメント(というか、時間になってすぐにbestmoveを返す部分が)、とても難しいです。

  子ノードの構造体(child_node_t)をなくして、ノードの構造体(uct_node_t)にvirtual_lossという変数でも用意すれば、virtual lossによる訪問回数(move_count)への影響はなくせそうですけど、子ノードの構造体をなくすと、UCB最大の子ノードを選ぶ処理(SelectMaxUcbChild() )でメモリのランダムアクセスが発生して、将棋では(チェスと違って)平均100手も合法手があるから、このランダムアクセスが許容できない可能性があります。😥

  子ノードの構造体をなくせば、メモリ使用量が1/10ぐらいになりそうですけど、その代わりに30%速度ダウン(自己対戦で -R80ぐらい?)って我々は到底許容できないですしね。

  別案として、RootNodeだけvirtual lossを別枠で持っておくという実装が考えられます。
  // ソースコードがぐちゃぐちゃになりかねないので嫌なんですけど、わりとアリではないかと…。



- 持ち時間制御 終局までの平均手数を80→160とみなすように変更
  - 近年の将棋ソフトの対局からすると80は少なすぎる。
- Timer::round_upのコード、round upした結果、元の時刻より小さくなるなら、もう1秒使うように修正。
  network delay = 120で、round_up(900)が880になっていた。(1880にならないと時間の使い方としてもったいない)


- 切れ負けのテストをしていたら、将棋所のバグを見つけた。

  将棋所、isreadyに対してreadyok以外のメッセージを無視してくれないと連続対局で非合法手指すんだけど😥

  > 1:gameover win
  > 2:gameover lose     ← エンジン2が時間切れ負けになった
  > 1:isready
  > 2:isready
  > 1:readyok
  > 2:bestmove 8b5b     ← エンジン2の探索部が指し手を返した(isreadyに対してreadyokを送る前なので合法のはず)
  > 1:gameover win      ← エンジン2が開始局面で非合法手を送信して負けたことにされた
  > 1:quit

  これ、これを回避できるようにすることは探索部では不可能なので("isready"受信と入れ違いに"bestmove"を返すことはありうる)、この将棋所の仕様はおかしい。

  これ、いままで誰も気づかないのか…。まあ、切れ負けになる対局なんて普通、ないしな…。
  → よく見たら、将棋所、連続対局のとき、局後に2秒ぐらいwaitがあるので、それ以上にオーバーしてbestmove返す思考エンジンが悪い感もある。


■ 2020/12/19


- vcxproj: 依存ライブラリ分離 (#144)
  - Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/commit/bdbd85f1edce73d75e8f8243c44152492e70fa2d


- misc.hがgcc/clangでコンパイルエラーになっていたの修正。
  - include <atomic> が必要らしい。


- TensorRT用の時のエンジン名に"TensorRT-" の文字を追加。

- NNUE-LEARNのフォルダがsource/に作られていたの修正。
  - ひとつ前のcommitでは修正できてなかった😥
  - プロパティシートの順番なのか…そうか…。まあいいや。

- old_enginesをsource/から、上のフォルダに移動させる。
  - sourceフォルダは綺麗にしときたい。



- ふかうら王、持ち時間制御、修正その3
  - interrupt check、全スレッドで行うように変更。
  - 探索終了時にPVが2度出力されるの修正。
  - 探索ノードが0のときにnnrateが一番高い指し手をbestmoveとして返すように。
  - interruptするとき、なるべく即座に終了したいのでEvalNode()をskipするように。
  - UctSearcherGroup::InitGPU()削除。
  - DNN_Batch_Size1がpolicy_value_batch_maxsizeに反映してなかったの修正。
  - ふかうら王のNetworkDelay,NetworkDelay2の値、調整。
  - 時間制御のコード、optimum timeの半分は使うように。そのあと1,2番目の指し手が逆転しそうな時はoptimum timeまでは使うように。
  - DebugMessage = true のときの探索開始時の情報で、今回のminimum_time(),optimum_time(),maximum_time()を出力するようにした。
  - go infinite反映してなかったの修正。
  - 持ち時間の秒ぎりぎりまで思考するように修正。
  - 投了の時にresignを返していなかったの修正。
  - PV出力の時にchild nodeが展開されていなくともnnrateから最善手を返すように。
  - PV出力の時にmultipvとそうでない時の処理を分けるのやめた。
  - たまに時間めっちゃ使う // あとで調べる
     GCがメモリ回収するの、デバッグ用のランタイムだと遅くて、それで時間超過になっている可能性がある。
     他のソフトを起動すると顕著に遅くなることがある。(その間、探索が進んでない) なんぞこれ。EvalNodeでforwardしたときに
     画面描画とか忙しくて処理が後回しになっているのであろうか…。
  - DlshogiSearcher::debug_messageをsearch_optionsに移動。
  - optimumの何倍まで使うかという係数を用意した。

  // たまに時間切れ負けになるのであとで修正する。

  // dlshogiの探索の終了の処理、どのスレッドかが探索終了条件を満たしていることを見つけても、
  // 他のスレッド、batch分だけ探索してEvalNode()までしてしまい、
  // メインスレッドは全スレッドの探索の終了を待機してからbestmoveを返すので、止まる時のラグがひどい気がします。
  // (batch sizeが小さいなら無視できるのかもしれませんが)
  // 探索途中であっても、uct_search_stopになった時点で、EvalNode()はskipして、Virtual Loss戻してBackupして、
  // ParallelUctSearch()を抜けたほうがより正確なtime managementができると思います。

- プロジェクト構成にRelease-Deepが残っていたの削除。
- プロジェクト構成いじったときにNNUEがsource/にビルドされてたの修正。
- dlshogi_searcher.cpp追加。
- TensorRTを使う時、TENSOR_RTをDefineするようにした。


- "isready"を呼び出さずに"go"を呼び出した時に落ちるの修正。
  - これ落ちるとデバッグの時、面倒なので。


- inc timeの解釈が間違っていたの修正。

  - inc time(フィッシャールール)のとき、対局開始の初手、将棋所だと
    go btime 0 wtime 0 binc 5000 winc 5000
    のようにメッセージがやってくることに気づいた。
    これ知らずに、こう送られてきたら時間がない扱いで初手 0.1秒で指していたの修正。

- time managementのmax timeの係数、5.0f → 3.0fに変更。


- makebookコマンド、リファクタリングのときに壊していたの修正。
  - thanks! lefu777さん、Mizarさん



■ 2020/12/18


- ふかうら王、持ち時間制御 修正その2
  - 持ち時間がtime managerに反映してなかったの修正。
  - hashfullの出力のあとスペースが空いてなかったの修正。
  - YaneuraOu_dlshogi_bridge.cpp , utf8で保存されてなかったっぽい。修正。
  // 詰みを見つけた時にハングするときがあるようだ。明日調べる。


- ふかうら王、持ち時間修正など
  - "go ponder"に対してbestmoveを返していない件
    - "stop"が送られてくるまで待機するように修正した。
    - dlshogiのほう、ponderモードでの呼び出しだとponderhitでもいったんStopUctSearch()で探索を停止させているが、同一局面の再探索のコストが
        小さければこういう実装もあるのか。
        // stopでbestmove返さないのはちょっとおかしい気がするけど。

  - batch sizeが大きいと評価値がおかしいものを返すことがある件。
        //  評価値は、極めて短い時間で対局させると、rootを展開した直後とか、virtual lossのため、
        //  すべての指し手が負け扱いになっているので、すごく低い評価値に見えるのが原因ではないかと。
        //  というか、(技術的に可能かどうかはさておき)AlphaZero型のソフトは、virtual lossの効果を無効化して評価値を表示すべきでは。

        // 例) batch size = 256で 0.1秒の思考時間として、playout 256回で探索が終了するケース。
        // rootからすべての指し手を展開してleaf nodeでevalのため局面をqueueに積みvirtual lossを加算している状態になる。
        // rootのすべての子を展開したあと、どれも展開できなくなってdiscardしてbatch size maxになる。この時点でPVを表示するとすべてが負けの指し手に見える。

  - 詰みを見つけてMoveNoneを返すの修正
    - 他のスレッドの探索止めてなかった。修正。

  - USI_Ponderがfalseのときに"bestmove XXX ponder YYY"のようにponderの指し手を返すの修正。

  - movetimeの条件間違っていて時間指定ある時に即指しになっていたの修正。

  - 探索打ち切り条件の簡略化。

  - 持ち時間制御にやねうら王のtime manager導入。
    - 未調整。
    - 秒読みの時1秒指ししてるな…。あとでなおす。

- goコマンドでmovetimeを指定できるようにした。
- Timer::initの引数のconstつけ忘れ修正。

- プロジェクト構成でDeep-ONNXとDeep-TensorRT と分離。



- ふかうら王、TensorRT対応
  - nn_evaluate.h/cpp → nn_types.h/cppにrename
  - nn_gpu.h/cpp → nn.h/cppとnn_onnx_runtime.h/cppに分離
  - nn_tensorrt.h/cpp追加
  - コンパイルは通ったが、NVIDIAのGPUがないので動作確認しておらず。
  // そのうちやる。
  - ONNX RUNTIME版のビルドにCUDAが必要なの、ちょっと嫌なので、プロジェクト構成、次回分ける。

- ふかうら王
  - NodesLimitを超えたら、ではなく、同じ数以上になった時点で探索を打ち切るように修正。


■ 2020/12/17


- Stockfish PR#3254, PR#3261 
	- #143 (Mizarさんのプルリク)
	- https://github.com/yaneurao/YaneuraOu/pull/143


- ふかうら王(dlshogi互換エンジン) Technology Preview #01
	- dlshogi互換エンジン
	- dlshogiの詰将棋ルーチンをオフにして、1スレッドで5万ノードを探索して、探索したノードが完全に同一、NNへの入力特徴量の値と
	  出力特徴量の値が完全に同一であることを確認した。
	- いまのところONNX RUNTIMEのみ対応
	- CUDA,TensorRTのコードそのうち移植する
	- TimeManagementまだ。とりあえず、NodesLimitでノード数を指定できるのでこれで対局してください。
		- GPUなしで対局するときはいまのところDNN_Batch_Size1は1~16ぐらいが最適値かも。
	- GCT電竜の評価関数ファイル(model-0000167.onnx)をmodel.onnxとrenameして Evalフォルダに放り込むと読み込めることは確認した。
		- 世界将棋AI 電竜戦バージョン(「GCT電竜」同梱) : https://github.com/TadaoYamaoka/DeepLearningShogi/releases/tag/denryu2020
	- ふかうら王の実行ファイルの配置フォルダに onnxruntime.dll , DirectML.dll が必要っぽい。GCT電竜からコピーしてくるべし。
	- 詰将棋ルーチン、未搭載。あとで実装する。
	- 評価関数は独立して使えるように設計してあるが、もう少し手を入れないと。これは気が向いたら作業する。
	- いまのところVisual Studioでしかビルドできない。
		- ビルド方法については、docs/解説.txt に書きました。
	- dlshogiにない特徴
		- MultiPV対応
		- stopコマンド対応
		- USIまわりのUSIプロトコルへの準拠度の高さ
	- 今後の予定
		- CUDA,TensorRT対応
		- TimeManagement
		- 詰将棋探索
		- df-pn
		- VIRTUAL_LOSSを可変に
		- 高効率なメモリマネージメント
		- 特徴因子の追加
		- EvalフォルダにNNのアーキテクチャ(入出力特徴量含む)に関するtagファイルを配置すればそれを自動的に構築する機能。
		- Policy Network最適化

- USE_EVAL_LISTのifdefの範囲間違っていたの修正。


■ 2020/12/13


- USER_ENGINEをdefineした時にコンパイルが通らなかったの修正。
- Visual StudioのプロジェクトにMaterial追加。



- makebookコマンドにbook_save_interval追加。

- 一つ前のcommitで修正しきれてなかったの修正。

- プロジェクト設定など微修正。



-	GenerateAllLegalMovesオプションをトーナメント用でも有効に変更。

	//		読みの各局面ですべての合法手を生成する
	//		(普通、歩の2段目での不成などは指し手自体を生成しないのですが、これのせいで不成が必要な詰みが絡む問題が解けないことが
	//		あるので、このオプションを用意しました。オンにすると勝率が少し下がるのでデフォルトではオフになっています。)

			関連) 将棋ソフトは不成が読めないという嘘 : http://yaneuraou.yaneu.com/2020/12/12/all-legal-moves/


■ 2020/12/12


- sfen_packerにUSE_FV_VARのコード残っていたの修正。
	- learnコマンドでpacked sfenの読み込みの時にエラーになっていたのを修正。

- FORCE_BIND_THIS_THREADのendifの場所間違ってた。

- 盤面を180度回転させた時の升を返すFlip()追加。

- USE_EVALがないときにコンパイルエラーになっていたの修正。

- エンジンオプションを一部、やねうら王の通常探索エンジンのほうに移動
	SkillLevel
	Contempt
	ContemptFromBlack
// 他のエンジンではこのオプションは不要なので。



■ 2020/12/09


- モジュール化のための作業。オプションの整理。
	- USE_FV38削除。
	- NO_EVAL_IN_TT削除。
	- EVAL_NO_USE削除。

	- USE_PIECE_VALUE追加。
	- USE_EVAL_LIST追加。
	- USE_EVAL追加。

- 2つ前のcommitでmakebook.cppをVisual Studioのプロジェクトに追加するの忘れていたの修正。
- gensfen2019.cpp、learner.cppに追加してファイルの削除を忘れていたの修正。



- 駒得系評価関数 MaterialLv.9追加
	- 【連載】評価関数を作ってみよう!その11 : http://yaneuraou.yaneu.com/2020/12/07/make-evaluate-function-11/

- 一つ前のcommitでコンパイルエラーになっていたの修正。


- 定跡DBにwin,drawのfield追加。


- add .editorconfig #142
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/142



■ 2020/12/04


- makebook2015をplug-inのような処理に変更。
- BookMoves::size()
		// 指し		// 指し手の数は、MAX_MOVESであるので、intの範囲で十分であるのだが、
		// std::vector.size()とコンパチでないと色んなところで警告が出てうざいのでsize_tにしておく。
- gensfen2019.cpp削除。learn.cppに含める。
	- learnコマンド、コマンドごとにファイルを分けるなり整理したいが、動作検証が大変なので学習回すときにやる。
- book/makebook.cpp 追加。
- NNUEでClangでのコンパイル時に警告でてたの修正。
- 解説.txt 内容が古かったので修正。



- Makefile修正したのcommit忘れてた。


- book/makebook2021.cpp 追加。これから書く。
- book.cppにあったmakebookコマンドの処理ルーチン、book/makebook2015.cppに移動。
	- 2015年ごろに書いたコードだから。
- Aperyの定跡読み込みで使っているMT64bit、apery_book.cppでしか使っていないので無名namespaceに変更。


- 定跡クラス、秋の大ファクタリング祭り
	BookPos → BookMoveにrenameする
	BookPos::bestMove,nextMove → move,ponder にrenameする。
	BookPos::prob削除
	//		float prob;    // ↑のnumをパーセンテージで表現したもの。(read_bookしたときには反映される。ファイルには書き出していない。)
- Book読み込み高速化
	- 定跡読み込み時にBookPosのsortやめる。
	- 定跡読み込み時のprobの計算もやめる。
- BookMovesクラス、thread safeにして書き直す。
- 定跡DB拡張。採択回数の後ろにwin,loseを記入する。(optional)
- 定跡DBにwin,loseの数字が書かれていれば(1以上の数字がどちらかに書かれていれば)、定跡にhitしたときに採択率とともに win-draw-loseも出力するようにした。
- MemoryBook、ほぼASYNC化した。
- WriteBookのときにwin/loseも書き出すようにした。
- Bookにponderが記入されていない場合、1手進めて定跡にhitすればそのときのbestmoveをponderとして返すようにした。
- 定跡関連のファイルをsource/extra/book から source/book/に移動
- Aperyの定跡ルーチンのためのMT乱数のコードをapery_book.cppに移動
- Makefile修正


■ 2020/12/03


- FOREACH_BB()マクロ除去
- Bitboard::foreach_part()追加。

- Unroller、templateで書く。
	- Aperyのコードを参考にさせていただいています。: https://github.com/HiraokaTakuya/apery/blob/master/src/common.hpp
	- VC++でコンパイルしても以前のコードに比べて特に遅くはなっていないようだった。



- 指し手生成のコード、defineマクロ廃止する方向で書き直す。
	- defineマクロ、ちょっと減らす方向で(デバッグしにくいため)
	- Bitboard::foreach() 導入。
	- Moveに関して、MoveとMove16が紛らわしくて使いにくいので、もうちょっと厳密な規則を導入。
		- make_move()はMoveを返すなら、上位16bitに駒種が返ってきてないと紛らわしい。
		- 駒種の格納されていないMoveが返ってくるのはバグの原因となる。
		- make_move16()など追加。
	- 1手詰め判定はMoveの上位にきちんと動かす駒を入れて返すように変更。
	- move_to()廃止。
	- move_from()廃止。
- KEEP_PIECE_IN_GENERATE_MOVES 廃止。Moveの上位には常に移動先の駒が来て良い。
- USE_DROPBIT_IN_STATS廃止。これ結局、使わない。


■ 2020/12/02 V5.40


- MaterialLv8追加
	- 【連載】評価関数を作ってみよう!その9  : http://yaneuraou.yaneu.com/2020/12/01/make-evaluate-function-9/
	- 【連載】評価関数を作ってみよう!その10 : http://yaneuraou.yaneu.com/2020/12/02/make-evaluate-function-10/


- パラメーター、チューニング
	- Assorted search and eval parameter tune : https://github.com/official-stockfish/Stockfish/commit/9fb6383ed804d0bc86d52b07def14352f44eb5b4
- LMRで指し手がkillerの時のbonus削除
	- Remove bonus for killers. : https://github.com/official-stockfish/Stockfish/commit/66da1e802c22b1952c2a07af65c6224d0e01b3df
- SEEの条件式、単純化
	- Search simplification : https://github.com/official-stockfish/Stockfish/commit/6c429c4d6527a8e88d2ad1e7bfc8f4bd0ec05729
- Reduction、単純化
	- Reductions simplification : https://github.com/official-stockfish/Stockfish/commit/2442ba2b0e8a399b0dbfe9d23a8a2819cb0af987
	
	engine1 = YaneuraOu-NNUE_V540.exe , eval = suishou_wcso1  : 前回のやつ
	engine2 = YaneuraOu-NNUE_V540a.exe , eval = suishou_wcso1 : 今回のやつ
	T2,r100,1462 - 55 - 1483(49.64% R-2.48[-13.01,8.05]) winrate black , white = 49.58% , 50.42%
	T2,b1000,1414 - 111 - 1345(51.25% R8.69[-2.19,19.57]) winrate black , white = 50.56% , 49.44%
	T2,b2000,675 - 50 - 675(50.0% R-0.0[-15.55,15.55]) winrate black , white = 52.52% , 47.48%
	T2,b2000,666 - 48 - 686(49.26% R-5.14[-20.68,10.4]) winrate black , white = 50.15% , 49.85%

	// 強さ、ほぼ変わらん模様



- 探索、LMRまわりのコード、刷新
	- 強さほぼ変わらないが弱くはなってなさそう
- 探索パラメーター刷新(+R10~)
- MovePickerにパラメーターチューニング導入
- バージョンナンバー5.40にするの忘れてたの修正



- やねうら王 V5.40
	- MOVE_NULLのバグ修正(+R25)
	- NNUE高速化
	- MaterialLv.7追加



■ 2020/12/01


- NNUE高速化
	- Mizarさんのプルリク
	* Backport from Stockfish NNUE
	* - 4 tab indent style


- MOVE_NULLを代入すべきところMOVE_NONEになってたの修正。
	- これ修正したけど強さほぼ変わらないか、むしろ弱くなるようなのだが…。
		- https://twitter.com/mktakizawa/status/1330863774941646848
	- evaluate()まわりも同時に修正すれば、弱くはなっていないようなので採用。

		engine1 = YaneuraOu-NNUE_V533.exe , eval = suishou_wcso1
		engine2 = YaneuraOu-NNUE_V533a.exe , eval = suishou_wcso1
		T2,r100,1304 - 44 - 1652(44.11% R-41.09[-51.68,-30.51]) winrate black , white = 50.41% , 49.59%
		T2,b1000,1354 - 98 - 1548(46.66% R-23.26[-33.89,-12.63]) winrate black , white = 50.72% , 49.28%
		T2,b2000,1248 - 114 - 1488(45.61% R-30.56[-41.52,-19.59]) winrate black , white = 50.0% , 50.0%
		T2,b2000,1263 - 117 - 1440(46.73% R-22.78[-33.8,-11.77]) winrate black , white = 51.05% , 48.95%
		+R25ぐらいあがっとる。



- Directry::GetCurrentFolder()、起動フォルダによっては正常に返せていなかったの修正。
	- Stockfishに導入された、namespace CommandLineをそのままportingして、それを間接的に呼び出すようにした。
		cf. https://github.com/official-stockfish/Stockfish/commit/406979ea12ee7828e079871b0f9f3dc8f127a741
- Directry::GetCurrentFolder()は、working folderを返すように変更。
- Directry::CreateFolder()もworking folder相対で指定するようにコメントを追記。(以前からそうなっているはずだが)
- Path::GetFileName()、ファイル名しかないときに正常にファイル名が返せていなかったの修正。
- Path::GetDirectoryName()、GetFileName()を間接的に呼び出していたので同様のバグがあったのを修正。


■ 2020/11/30


- TUNING_SEARCH_PARAMETERSで、PARAM10がPARAM1に誤爆する問題を修正。


- 評価関数MaterialLv7追加。
	-【連載】評価関数を作ってみよう!その8 : http://yaneuraou.yaneu.com/2020/11/30/make-evaluate-function-8/


■ 2020/11/28 V5.33


- build scripts #138
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/138
		gensfen target対応 (MATE_ENGINE, USER_ENGINE, Ubuntu-MinGW NNUE* はビルド不能のため除外)
		MaterialLvX 対応
		AVXVNNI対応(Ubuntu + LLVM12のみ)
		ビルドターゲットにAVXVNNI,AVX512VNNI,AVX512追加
		自動リリースビルドのトリガとなるタグ名に 'V*' を追加
		自動リリース時の説明文を加筆 例: https://github.com/mizar/YaneuraOu/releases/tag/v5.32.0%2B20201128f.nnue


- やねうら王 V5.33

	- NNUE AVX512,AVX512VNNI対応

	- 駒得評価関数の拡張として、MATERIAL_LEVEL 1~6を追加。(詳しい内容は、以下の連載記事をご覧ください)
		【連載】評価関数を作ってみよう!その1 : http://yaneuraou.yaneu.com/2020/11/17/make-evaluate-function/
		【連載】評価関数を作ってみよう!その2 : http://yaneuraou.yaneu.com/2020/11/19/make-evaluate-function-2/
		【連載】評価関数を作ってみよう!その3 : http://yaneuraou.yaneu.com/2020/11/20/make-evaluate-function-3/
		【連載】評価関数を作ってみよう!その4 : http://yaneuraou.yaneu.com/2020/11/23/make-evaluate-function-4/
		【連載】評価関数を作ってみよう!その5 : http://yaneuraou.yaneu.com/2020/11/25/make-evaluate-function-5/
		【連載】評価関数を作ってみよう!その6 : http://yaneuraou.yaneu.com/2020/11/26/make-evaluate-function-6/
		【連載】評価関数を作ってみよう!その7 : http://yaneuraou.yaneu.com/2020/11/27/make-evaluate-function-7/

	- gensfen2019 追加
		- WCSC29のときに用意した教師生成コマンド。
		- GENSFEN2019をdefineしていると、"gensfen2019"というコマンドが使えるようになる。
		- 与えた棋譜の各局面を対局開始局面として、そこから自己対局を行い、教師を生成する。
		- オプション等についてはソースコード(gensfen2019.cpp)を読んでください。
			- 気が向いたらきちんと書く。



- Android用のMakefile修正。
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/136


- mate engineとuser engineのビルドが通らない件、makefile修正。


- NNUE AVX512,AVX512VNNI対応
	- NNUEのコード大改修。
		- 一部、複雑でportingまだ。残りはMizarさんに任せる。
	- IS_ARM → USE_NEONに変更 (StockfishNNUEがそうなった)


- 評価関数のEVAL_EXPERIMENTALのコード clean up


- eval/material/ 追加
- eval/experimental/ をold_engines/eval/ に移動移動

- 駒得評価関数の拡張として、MATERIAL_LEVEL 1~6を追加。(詳しい内容は、以下の連載記事をご覧ください)
	【連載】評価関数を作ってみよう!その1 : http://yaneuraou.yaneu.com/2020/11/17/make-evaluate-function/
	【連載】評価関数を作ってみよう!その2 : http://yaneuraou.yaneu.com/2020/11/19/make-evaluate-function-2/
	【連載】評価関数を作ってみよう!その3 : http://yaneuraou.yaneu.com/2020/11/20/make-evaluate-function-3/
	【連載】評価関数を作ってみよう!その4 : http://yaneuraou.yaneu.com/2020/11/23/make-evaluate-function-4/
	【連載】評価関数を作ってみよう!その5 : http://yaneuraou.yaneu.com/2020/11/25/make-evaluate-function-5/
	【連載】評価関数を作ってみよう!その6 : http://yaneuraou.yaneu.com/2020/11/26/make-evaluate-function-6/
	【連載】評価関数を作ってみよう!その7 : http://yaneuraou.yaneu.com/2020/11/27/make-evaluate-function-7/


- Makefileのターゲット"gensfen"でコンパイルエラーになっていたの修正
	- Visual Studioのプロジェクトファイルにgensfen2019.cpp入れてはいけなかったのでそれも修正。
	- これ、Visual Studioで編集しにくいから、気が向いたらなおす…かも…。


■ 2020/11/27


- USE_FV_VAR clean up
	- 残っていた古いコードを削除
- evaluate.hの説明修正。
- TUNING_SEARCH_PARAMETERSが定義されているときにEval::init()をisreadyに対して呼ぶように変更。
	- これしとかないと評価関数のほうのパラメーター調整ができない。


- gensfen2019 追加
	- WCSC29のときに用意した教師生成コマンド。
	- GENSFEN2019をdefineしていると、"gensfen2019"というコマンドが使えるようになる。
	- 与えた棋譜の各局面を対局開始局面として、そこから自己対局を行い、教師を生成する。
	- オプション等についてはソースコード(gensfen2019.cpp)を読んでください。
		- 気が向いたらきちんと書く。


- LearnerThink::calc_loss()内のワーカースレッドでWinProcGroup::bindThisThread()を呼び出すようにした #135
	- nodchipさん(たぬきさん)のプルリク : https://github.com/yaneurao/YaneuraOu/pull/135


- release.yml: SSE3 -> SSSE3 #134
	- 頭文字が "v*" にマッチする tag をpushした時に自動で作成する release において、本文テキストのtypoを修正
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/134


- msys2_build.ps1 : nice value to default #133
	- msys2_build.ps1 において、makeコマンドの実行優先度を実験用に -n 0 (通常) に設定していたままだったので、これをniceのデフォルト(+10、実行優先度を下げる)に戻す
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/133


- release archive: add source #132
	- 頭文字が "v*" にマッチする tag をpushした時に自動で作成する release において、zip/7z書庫に source/ 以下のファイルを追加する
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/132


- bench.py
	- StockfishのベンチマークのようなことができるPythonスクリプト
	- Mizarさんのプルリク : https://github.com/yaneurao/YaneuraOu/pull/131 



■ 2020/11/16


- Makefileからビルド時にTARGET_CPUをコンパイルオプションとして設定するようにした。
- エンジン起動時(usiコマンド送信時)に表示されるエンジン名は、ZEN2用は(従来のようにAVX2ではなく)ZEN2と表示されるようにした。


- 最初に:やねうら王遊び方説明.txt 追加
	- CI(自動ビルド)でこれが含まれていないと初めて使う人は、
		どの実行ファイルを選べば良いのかわからなくなる。


- V5.32リリース


- 片玉局面に対するコメント追加。
	- 王様がSQ_NBにいることを想定したコードに(元からPositionクラスはなってるはずだが)
	- 関連 : https://github.com/yaneurao/YaneuraOu/pull/130


■ 2020/11/15


- EVAL_LEARNをつけていると終了時にゼロ除算していたのを修正。
	- Tamaさん、Qhapaqさん、Mizarさん。サンクス。
		- cf. https://twitter.com/JKishi18gou/status/1327621478850826241


■ 2020/11/14


- 探索パラメーターの(自動?)チューニングについて、解説.txtに説明を追加。


■ 2020/11/13


- MakefileにEXTRA_CPPFLAGS追加
- position.h/.cpp整理
- コメントいくつか追加


■ 2020/11/11


- EvalHash、"isready"応答で毎回クリアするように変更。

// やねうら王系でEvalHash有効にしてて(してない人はしてないかも知れないけども)、tournamentモードだと、デフォルトで1024MB。短い時間の連続自己対局だと、ここにそこそこ開始局面付近のhash値が残るので、自己対局でわずかに有利みたいな理屈はあることに気づきました:disappointed_relieved: 
// これ無効化するエンジンオプションが存在しないですし、(仮にEvalHashを使用するほうが強いとしたら)自己対局のときに無効化するのが正しいのかどうかよくわかりません。
// しかし、EvalHash、エンジン起動後の1回目しかクリアしてないのはいずれにしてもおかしい気はします。😅 ここで、計測にノイズが入るのちょっと嫌なので…。


■ 2020/11/10


- 自動パラメーター調整のコード、Path.Combine()忘れていたので追加。

- 探索部、コメントの追加。



- build: add archcpu ZEN3,AVX512VNNI #129 (Mizarさんのプルリク)

	ビルド関係の archcpu ZEN3, AVX512VNNI 対応作業

	Makefile で TARGET_CPU=ZEN3 の場合、-march=znver3 の代わりに -march=znver2 を指定。

	-march=znver3 が使えるのはLLVM12からで、LLVM12は現時点ではリリースされていません

	AVX-VNNI (AVX512-VNNIの非512bit版), -march=alderlake もLLVM12から対応。

	Ubuntu 18.04 g++, MinGW でのビルドチェックにおいて ZEN3, AVX512VNNI を除外

	g++-8 系では -march=cascadelake, -march=znver2, -march=znver2 のいずれも未対応

	リリース用ビルドについては AVX512 を除外、 AVX512VNNI を追加


■ 2020/11/09


- 自動パラメーター調整フレームワーク導入
	- source/engine/yaneuraou-engine/yaneuraou-param-common.h追加
	- TUNING_SEARCH_PARAMETERS コンパイルオプション追加。

- パラメーターの自動変換スクリプト(Python用)追加
	- source/engine/yaneuraou-engine/param_conv.py追加
		#    yaneuraou-param.h から
		# 1) yaneuraou-param-extern.h
		# 2) yaneuraou-param-array.h
		# 3) yaneuraou-param-string.h
		# を自動生成するPythonのスクリプトです。



- AVX512対応 Makefile

- FORCE_BIND_THIS_THREADコンパイルオプション追加

- 金と小駒の成りを区別するDISTINGUISH_GOLDS、変更忘れてた箇所を修正。

- MovePickerなど、説明用のコメントいくつか追加。



- 金と小駒の成りを区別するDISTINGUISH_GOLDS導入。(tttakさんのコードより)
	- cf. https://github.com/tttak/YaneuraOu/blob/NNUE-features/source/eval/evaluate_bona_piece.cpp

- mulhi、バグる環境なんてなかったのでmiscからUnitTestのコード削除

- thread.cpp、コメント追加。
	- スレッド数変更時にsearch::init()を呼び出すようにした。

- probcutの適用depthのコード、間違ってたの修正。



■ 2020/11/08


- V5.31リリース。
	- "LargePageEnable"エンジンオプション追加。
	- USI_Hashなどのメモリ確保のタイミングをすべてisreadyのところに移動。
	- 探索停止条件のコード刷新。
	- aspiration searchのコード刷新。
	- 教師局面からの学習のコード、定期的に自分のスレッド用の置換表をクリアするコード追加。


- 8スレはbindThisThread()呼び出さない。9スレから。

- aspiration searchの増加量変更。16->17

- LargePageEnable反映されないことがあったの修正。

- GUI側からsetoptionでUSI_Hash、Threadsが送られてきたとき、そのハンドラで処理するのはやめて、isreadyに対して処理するように変更。
	- こうなっていないとUSI_Hashでメモリ確保してから、やっぱりLargePageに確保して!(LargePageEnable = true)とか送られてきても
	 もう確保したあとやっちゅーねん!みたいになる。

// USIプロトコルって、usiに対してエンジン側がoption返して、GUI側からsetoptionは、このoptionの順番は守られると仮定できるのかな?
// たぶん仮定できないよね。
// これ守ってくれないと、USI_Hash確保してからHashはやっぱりLarge Pageに確保!みたいなことをGUI側から言われることになって、大変困るんだけどな…。
// てか、setoptionのハンドラでhashとかスレッド確保するStockfishのコードがおかしいんだと思う。そんなところで確保したら…ごにょごにょ…。


- failHighCntまわりコード移植した
engine1 = YaneuraOu2018NNUE_V521b.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V521c.exe , eval = tanuki2018_nnue
T2,b1000,1478 - 91 - 1431(50.81% R5.61[-4.98,16.21]) winrate black , white = 49.36% , 50.64%

- 教師局面からの学習の時に、一定回数のqsearch()ごとに自分のスレッド用の置換表をクリアするようにした。

- aspiration searchのコード、刷新。

- 探索停止条件のコード、刷新。



■ 2020/11/07


- ProbCutのPARAM_PROBCUT_MARGIN2と書くべきところ、コピペミスでPARAM_PROBCUT_MARGIN1に
	してて盛大に弱くなってた。ごめん。
- 教師局面からの学習の時に定期的に各スレッドが置換表をクリアするようにした。


- android build fix, and checkout path change to ./main #128
	Android HalfKPE9ビルドの修正、他諸々
	自動ビルドにおいて、gitレポジトリの展開先をカレントディレクトリから./mainに変更
	ShogiDroid向けHalfKPE9実行サンプル:
	https://github.com/mizar/YaneuraOu/releases/download/v5.30-20201107c_androidfix/YOv5.30-Sylwi.zip



- "LargePageEnable"エンジンオプション追加。

// デフォルトtrue
//LargePage対応について、これをエンジンオプションでオフにできないと、自己対局のときに片側のエンジンだけLargePageを使うことがあって、不公平なのでエンジンオプションでオフにできるようにとの要望を、
//やねうら王のブログのコメントで頂戴致しました。確かにそうだと思ったので、これをオフにするエンジンオプションを追加する次第です。

- TanukiColiseumのほうでLargePageオフにするようにissueを投稿。
	https://github.com/nodchip/TanukiColiseum/issues/8



- TT.clear() , std::memset()のコンパイルでエラーになるの修正。

- probCutのコード刷新
YaneuraOu2018NNUE_V521a.exe
engine1 = YaneuraOu2018NNUE_V521.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V521a.exe , eval = tanuki2018_nnue
T2,b1000,550 - 36 - 544(50.27% R1.91[-15.37,19.18]) winrate black , white = 50.18% , 49.82%
// 誤差か。


- V5.30リリース
	- 置換表絡みの処理、デバッグコードが残っていたのを修正したので
	 スレッド数、置換表サイズによっては+R20以上あがっているはず。
	- 学習まわりでスレッド個別の置換表を用意するなど学習時のノイズを低減。
	- 探索部、ほぼStockfish 2020/11/07時点の最新に。
		(強くなることの実証が終わっていない枝刈りはまだ適用していない)


- TT.probe()デバッグ用のコードを有効にしていた。本番用のコードがコメントになっていた。すまぬ。
	- 置換表絡みでどやこや言われてるのはその半分はこれが原因だと思います。
	置換表サイズによっては+R20以上、上がります。
- EVAL_LEARN版の置換表、自分のスレッド用の置換表だけを非並列でクリアする処理を追加。
- gensfenのコードも対局シミュレーションにおいて、自分のスレッド用の置換表をクリアするコードを追加。


■ 2020/11/06


- IID(Step 11. Internal iterative deepening)削除
	- // Step 11. If the position is not in TT, decrease depth by 2
	- を追加
YaneuraOu2018NNUE_V520k.exe
engine1 = YaneuraOu2018NNUE_V520j.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520k.exe , eval = tanuki2018_nnue
T2,b1000,1033 - 86 - 1021(50.29% R2.03[-10.58,14.64]) winrate black , white = 52.43% , 47.57%

- Step 4.のコード
	if ((ss - 1)->moveCount <= 2 && !priorCapture)
		update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));
	に変更
	// こうなっていてもおかしくはないはずのコード
	// if ((ss - 1)->moveCount <= 2 && !pos.capture_or_pawn_promotion((ss - 1)->currentMove))
	//     update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + 1));

YaneuraOu2018NNUE_V520l.exe
engine1 = YaneuraOu2018NNUE_V520k.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520l.exe , eval = tanuki2018_nnue
T2,b1000,620 - 51 - 619(50.04% R0.28[-15.95,16.51]) winrate black , white = 52.62% , 47.38%

- search()の末尾のttPvの更新コード

		// もし良い指し手が見つからず(bestValueがalphaを更新せず)、前の局面はttPvを選んでいた場合は、
		// 前の相手の手がおそらく良い手であり、新しい局面が探索木に追加される。
		// (ttPvをtrueに変更してTTEntryに保存する)

		if (bestValue <= alpha)
			ss->ttPv = ss->ttPv || ((ss - 1)->ttPv && depth > 3);

		// それ以外の場合は、カウンターの手が見つかり、その局面が探索木のleafであれば、
		// その局面を探索木から削除する。
		// (ttPvをfalseに変更してTTEntryに保存する)

		else if (depth > 3)
			ss->ttPv = ss->ttPv && (ss + 1)->ttPv;

YaneuraOu2018NNUE_V520m.exe
engine1 = YaneuraOu2018NNUE_V520l.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520m.exe , eval = tanuki2018_nnue
T2,b1000,495 - 44 - 491(50.2% R1.41[-16.78,19.6]) winrate black , white = 53.65% , 46.35%





- V5.21リリース
	- halfKPE9対応作業中
	- CI Build導入
	- EVAL_LEARNまわり色々修正
	- Stockfish 2020/11/06時点まで主要な更新はほぼ取り込んだ


engine1 = YaneuraOu2018NNUE_clang_20201105_V520.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu_NNUE_V521official.exe , eval = tanuki2018_nnue
T2,b1000,1229 - 124 - 1187(50.87% R6.04[-5.59,17.67]) winrate black , white = 52.98% , 47.02%

// V5.20とはほぼ互角



- qsearch()駒を捕獲しない指し手の枝刈り変更。
engine1 = YaneuraOu2018NNUE_V520f.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520g.exe , eval = tanuki2018_nnue
T2,b1000,518 - 46 - 516(50.1% R0.67[-17.09,18.44]) winrate black , white = 51.16% , 48.84%
// ほぼ変わらないし、新しいコードのほうが断然シンプルなので新しいコードに差し替える。

- RazorMargin変更
	600 -> 510
	// これは経験上、計測できるほどの差を産まない。

- FutilityMargin変更
前)		return Value((PARAM_FUTILITY_MARGIN_ALPHA1/*175*/ - PARAM_FUTILITY_MARGIN_ALPHA2/*50*/ * improving) * d);
後)		return Value(223 * (d - improving));

YaneuraOu2018NNUE_V520d.exe
engine1 = YaneuraOu2018NNUE_V520c.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520d.exe , eval = tanuki2018_nnue
T2,b1000,606 - 64 - 600(50.25% R1.73[-14.72,18.18]) winrate black , white = 55.06% , 44.94%
// 誤差でしかない

- 一つ前のcommitでEVAL_LEARNでコンパイル通っていなかったの修正。



- EVAL_LEARNのときにreductionをスレッド数 = 1の時のものに設定する。(tanuki-さんからの指摘)
- Threads::get_best_thread()追加。探索のベストスレッドの選出のコード刷新。
- search()にmaxNextDepth導入

- stat bonus変更
	return d > 13 ? 29 : 17 * d * d + 134 * d - 134;

YaneuraOu2018NNUE_V520c.exe
engine1 = YaneuraOu2018NNUE_clang_20201105_V520b.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_V520c.exe , eval = tanuki2018_nnue
T2,b1000,328 - 31 - 321(50.54% R3.75[-18.67,26.17]) winrate black , white = 51.62% , 48.38%
// 計測できる差ではなさそう



- ThreadHolding導入。
	- 同一nodeを複数のスレッドで探索されるのを防ぐ。
	- 極めて多いスレッドで探索させるときに効果があるかも。
	// 少ないスレッドだとオーバーヘッドの分だけ損かも。
	engine1 = YaneuraOu2018NNUE_V520d.exe , eval = tanuki2018_nnue
	engine2 = YaneuraOu2018NNUE_V520e.exe , eval = tanuki2018_nnue
	T8,r100,607 - 36 - 547(52.6% R18.08[1.24,34.92]) winrate black , white = 48.35% , 51.65%
	T2,b1000,351 - 24 - 355(49.72% R-1.97[-23.46,19.53]) winrate black , white = 49.15% , 50.85%
	// 計測できない差
- CI Build (#126)でAndroid向けHALFKPE9無効化を入れたままだったの修正。
- 探索部のコメントいくつか修正。
- 探索部、Stockfishに近づくように関数の並び替えなど。
- 指し手のlegalityのチェックを行う場所、変更。
- Makefile、elseとif同じ行に書いてたの修正。


- CI Build (#126) , Mizarさんのプルリク
	#123 の修正
	ビルドスクリプトの改修
	コミットがレポジトリにpushされた際、自動全体ビルドによってバイナリが生成されるように
	この生成されたバイナリは自動でReleaseはされないものです
	ビルドに成功した場合、 https://github.com/yaneurao/YaneuraOu/actions の Artifacts(成果物) からビルド結果を参照する事ができます
	ただし、Artifactsの内容は永続的に保存はされない(おそらく生存期間は最大で90日)ので、必要なら個別に保存してください。
	タグがレポジトリにpushされた際、自動ビルドによって生成されたバイナリが自動でReleaseされるように
	draft: false # 下書きにしない(false)
	prerelease: true # 先行リリースのフラグを付ける(true)
	タグが追加される事が条件なので、通常のコミットではReleaseには乗りません
	README.md に CI Build ステータスの追加


■ 2020/11/05


- halfKPE9対応作業その1

	- 以下のファイル追加
		- nnue/features/
			- pe9.h
			- pe9.cpp
			- half_kpe9.h
			- half_kpe9.cpp
		- nnue/architectures/
			- halfkpe9_256x2-32-32.h
		- nnue/trainer/features/
			- factorizer_half_kpe9.h


	- tttakさんのリポジトリより。
		https://github.com/tttak/YaneuraOu
	- Mizarさんがやねうら王V5.00に対応させたもの。
		https://github.com/mizar/YaneuraOu/tree/v5.00-test20201103a/source/eval/nnue/features

	- Makefile修正
		- targetにYANEURAOU_ENGINE_NNUE_HALFKPE9を指定すればいける感じ。
		
	- halfKP -> halfKPE9 の変換器(Mizarさん)
		https://github.com/mizar/random-nnue-eval-rust/blob/master/src/eval_value.rs

	- サンプルのhalfKPE9の評価関数ファイル(Mizarさん , Sylwi WCSOC2020)
		https://github.com/mizar/YaneuraOu/releases/tag/sylwi_wcsoc2020
		初期局面でeval=25になるらしい
		evaldir kpe9
		isready
		eval
		で、eval = 25が得られたので全計算は合ってる。
		対局もさせてみる。
		→ R400ぐらい弱い。差分計算が間違っているのか?



- やねうら王V5.20


・やねうら王V5.10とV5.20との比較
engine1 = YaneuraOu2018NNUE_clang_20201104_V510.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_clang_20201105_V520.exe , eval = tanuki2018_nnue
T2,b1000,523 - 61 - 656(44.36% R-39.36[-56.1,-22.62]) winrate black , white = 51.15% , 48.85%


・Mizarさんの2020年5月のmブランチとの比較
engine1 = YaneuraOu_NNUE-m-202005-mizar.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_clang_20201105_V520.exe , eval = tanuki2018_nnue
T2,b1000,369 - 39 - 492(42.86% R-49.98[-69.64,-30.31]) winrate black , white = 48.2% , 51.8%
T2,b2000,345 - 40 - 395(46.62% R-23.51[-44.55,-2.47]) winrate black , white = 52.84% , 47.16%


・たまさんの最新のmブランチとの比較
engine1 = YaneuraOu_NNUE-m-202008-tama.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_clang_20201105_V520.exe , eval = tanuki2018_nnue
T2,b1000,551 - 53 - 606(47.62% R-16.53[-33.34,0.29]) winrate black , white = 51.86% , 48.14%


// どのmブランチに対しても有意に強い。
// 計測には公開されている 2018年のtanuki-評価関数を使用。


・mブランチ+2020年5月時点のStockfishをマージしたもの(Mizarさん)
	https://github.com/mizar/YaneuraOu/releases/tag/v4.89-test20200505

・mブランチ + 2020年8月ぐらい時点のStockfishをマージしたもの(たまさん)
	https://github.com/Tama4649/etc/tree/master/JKishi18gou_m




- Reductions配列の初期値変更。(+R25)
- Learner::search()がコンパイル通らなくなってたの修正。
- null moveの条件更新。
- VALUE_TB_LOSS_IN_MAX_PLY, VALUE_TB_WIN_IN_MAX_PLY導入。
- Step 13. Pruning at shallow depth (~200 Elo)のコード刷新。(+R15)
- LowPlyHistory、添字逆順にしたほうが掛け算がシフトで済むので高速化するが、コピーするコードがあってちょっと書き換え嫌だな…。


- continuationHistoryに[inCheck][captureOrPawnPromotion]の[2][2]を追加。
- Search::Stackに inCheck,ttPv追加。これを利用した枝刈り追加。
- ThreadPool::start_searching(),wait_for_search_finished()追加。
- update_continuation_histories(),条件変更。


engine1 = YaneuraOu2018NNUE_clang_20201104_V510.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_clang_20201104_V510c.exe , eval = tanuki2018_nnue
T2,r100,1435 - 57 - 1508(48.76% R-8.62[-19.16,1.92]) winrate black , white = 51.51% , 48.49%
T2,b1000,1408 - 150 - 1442(49.4% R-4.15[-14.85,6.56]) winrate black , white = 51.54% , 48.46%
// デグレはしてないが強くもなってないような…。


■ 2020/11/04


- やねうら王 V5.10
	- LowPlyHistoryの導入まわりでR70ほど上がったのでバージョンナンバーを0.1あげる。
	- Move16導入したことで、Aperyの定跡読み込みまわりにあったバグやMateルーチンにあった開始時に
		PV指定した時のバグが自然消滅した。

engine1 = YaneuraOu2018NNUE_clang_20201102_V500.exe , eval = tanuki2018_nnue
engine2 = YaneuraOu2018NNUE_clang_20201104_V510.exe , eval = tanuki2018_nnue
T2,b1000,920 - 105 - 1345(40.62% R-65.97[-78.2,-53.75]) winrate black , white = 52.58% , 47.42%
T2,b2000,371 - 50 - 569(39.47% R-74.3[-93.35,-55.24]) winrate black , white = 53.62% , 46.38%


- LowPlyHistory導入
	- LowPlyHistory導入
	- move ordering改善
	- update_all_stats追加
	- Search::Stack::ttHit追加
	- R70ぐらい上がってる模様。


- FV_VAR機能の削除
	- KPPTの差分計算を高速化するために導入したが、KPPT自体、もう使っていないし、
	 この機能のためにソースコードが複雑化する&保守するの大変なので残しておけない。
	- BonaPieceExpansionなど削除。これもはや使うこともなかろう…。


- PieceType導入
	- ソースコード大幅に修正になった。
	- 探索ノード数は変わっていないので機能的には等価。
	- コンパイル通らないところがあったら報告ください。


===========================
Total time (ms) : 10725
Nodes searched  : 5785406
Nodes/second    : 539431


■ 2020/11/03


- VisualStudioのプロジェクト設定の
	Release-NNUE-LEARN | x64
	のビルド時にEVAL_LEARNが指定されていなかったので追加。
- EVAL_LEARNをつけてコンパイルしたときにエンジン名に EVAL_LEARNの文字が入るようにした。



- やねうら王 V5.01
	engine1 = YaneuraOu2018NNUE_clang_20201102_V500.exe , eval = tanuki2018_nnue
	engine2 = YaneuraOu2018NNUE_clang_20201103_V501.exe , eval = tanuki2018_nnue
	T2,b1000,609 - 58 - 623(49.43% R-3.95[-20.22,12.33]) winrate black , white = 52.03% , 47.97%
	T2,b2000,267 - 26 - 277(49.08% R-6.39[-30.87,18.1]) winrate black , white = 48.71% , 51.29%
	デグレはしてなさそうなのでこれでV5.01にしておく。


- 置換表サイズ128GB制限の撤廃。
	- USI_Hashの新しい上限値は33554432MB(約33TB)
	- メモリが潤沢にある環境でのテストができていないので、誰かAWSで512GBぐらい確保した状態の動作テストをして欲しい😥
	- mul_hi64()導入。
	- 128bitの掛け算を行うのに、gccではgccの拡張を用いているので新しめのgcc/clangでないと
	  これがサポートされていないかも。
	- excluded_keyを含めたhash keyを生成するときにkeyの下位bitのみにxorをかけると、
		新しいTT.first_entry()の実装ではkeyの上位bitを用いるので
		同一TTEntryを指すことになってしまい探索性能が劇的に落ちる。
		Stockfishで導入されたmake_key()を改良して導入。
		// mブランチの作者、たぶんこれに気づかなかったので、このpatch導入できなかったのだと思う。
		types.hのmake_key()
		// 探索で、excludedMoveを考慮した局面のhash keyが欲しいので、それを生成するために
		// excludedMoveをseedとする擬似乱数を発生させる必要があり、そこで用いられる。
		// cf. https://github.com/official-stockfish/Stockfish/commit/de24fcebc873ce2d65b30e039745dbc2e851f443
	- mul_hi64()が正常に作動しない場合、
		"Error! : failed mul_hi() , please update gcc."と起動時に出力するようにした。
		→ このメッセージが表示されたなら、gcc/clangを最新版にしてください。
	- 上のため、Msys2のpacmanのupdateをしようとしたらエラーになった件。
		- Msys2 pacman PGP鍵の更新
			cf. 久々にMsys2のパッケージを更新しようとするとエラーが発生したのでその対処法 :  https://udon.little-pear.net/msys2-pacman-pgp-update/
	- "x & ~1"みたいなコードでxのbit0をマスクしてるつもりが、1はint32_tなので~1は32bitで、xの上位32bitを
	 0クリアしてた件について


- EVAL_LEARNを有効にしたときのコードのMove16の修正忘れ。
	- Move16にto_u16()追加。Move16::to_move()削除。
	- ↑に伴い、その周辺コード修正。


- tanuki-詰将棋、Move16を導入してエラーになっていたのを修正。
	- Move16まわり比較演算子追加。
	- USI::to_move()をto_move16()とrename。
	- MoveからMove16は暗黙の変換をサポート。逆の変換は暗黙にできるとバグの原因になる。
		(このときは普通、Position::to_move()を呼び出す必要があるので)
	- Limits.pv_checkはvector<Move>だが16bit MoveなのにこのままPosition::do_move()してるところがあったので
		vector<Move16>に変更して、その周辺のコードを合わせて修正した。
	

■ 2020/11/02


- (2つ前のcommitで)EVAL_LEARNを指定したときにコンパイルエラーになっていたの修正。
- LearnerThink::calc_loss()でTT.new_search()を呼び出していたの、不要なので削除。


- 16bitの指し手表現クラス、Move16を導入。
	- MemoryBook::insert()、32bitと16bitのMoveが混在しているとバグの原因となりやすい。

		- cf. https://twitter.com/nodchip/status/1321848707378106373
		> やねうら王のMemoryBook:insert()、overwriteにtrueを指定しても、
		> 予想手・評価値・探索深さの情報が更新iされない事に気づいた。
		> 少し前に作ったtanuki-定跡、テラショックになってなかったっぽい…。

		// たぬきさんより。

		> Moveの形式が定跡データベース中のものと引数で与えたものとで、16ビット版と32ビット版で異なる場合、
		> bool operator == (const BookPos& rhs) const { return bestMove == rhs.bestMove; }
		> でfalseとなり、エントリを置き換えずに追加する、というバグのようです。
		> 使用側が注意していれば起きない問題なのですが、ガードがあるとありがたいです。

	- Aperyの定跡読み込み部をMove16で書き直す。
		- 32bit Moveに直し忘れていて、定跡にhitしなかった局面がhitするようになった(気がする)
	- TTEntry::move()はMove16を返すように変更。(パフォーマンスダウンしてたら戻すかも)
	- 入玉宣言勝ち、定跡読み込み部等、すべてMove16で書き直した。
	- Position::move_to_move32(Move)をto_move(Move16)に変更。
	- Position::to_move()にis_ok()のチェック追加。
		- MOVE_WIN、置換表に書いてあることを想定してなかった。
	- USI::to_move()の返し値をMove16に変更。
	- テラショック定跡の生成部もMove16を使うようにした。

	- 何かデグレしてるかも。レビュー待ち。

		// 弱くはなってはなさげ。
		engine1 = YaneuraOu2018NNUE_clang_20201102_V500.exe , eval = tanuki2018_nnue
		engine2 = YaneuraOu2018NNUE_clang_20201102_V500a.exe , eval = tanuki2018_nnue  ←今回の

		T2,r100,1529 - 67 - 1404(52.13% R14.82[4.26,25.38]) winrate black , white = 50.39% , 49.61%
		T2,b1000,377 - 29 - 384(49.54% R-3.2[-23.9,17.51]) winrate black , white = 52.17% , 47.83%



- 学習用の実行ファイルでは置換表を探索スレッドごとに持つように変更。
	- これをしないと時々、hash衝突して他の局面の値を拾ってくることがある。
		- TTEntry::depth()の大きな値のエントリーがどんどん残っていくことになる。これがまずい。
	- スレッドごとに置換表の世代カウンターを持つ。
	- Learner::search(),qsearch()で自分のスレッド用のTTの世代カウンターを回すように。
	- これで教師生成の質が少し上がるはず。
	- Visual Studioでビルドするとき、デフォルトでEVAL_LEARNはundefに変更。


- やねうら王 V5.00
	- 探索部を刷新。(WCSC29版やねうら王相当)
		- V4.xx系からR100以上、上がってるはず。
		- MovePicker改良
		- 探索パラメーター最適化


■ 2020/08/18


- HandKind構造体を削除したのでLONG_EFFECT_LIBRARYがコンパイルできなくなっていたのを修正。


- Qhapaqさんの詰将棋エンジン修正のプルリク。(#120)



■ 2020/08/11


- ThreadIdOffset思考エンジンオプション追加
		3990XのようなWindows上で複数のプロセッサグループを持つCPUで、思考エンジンを同時起動したときに
		同じプロセッサグループに割り当てられてしまうのを避けるために、スレッドオフセットを
		指定できるようにしてある。

		例) 128スレッドあって、4つ思考エンジンを起動してそれぞれにThreads = 32を指定する場合、
		それぞれの思考エンジンにはThreadIdOffset = 0,32,64,96をそれぞれ指定する。

		※ 1つのPCで複数の思考エンジンを同時に起動して対局させる場合はこれを適切に設定すべき。


- Visual StudioのプロジェクトファイルのAVX2用にUSE_BMI2コンパイルオプション追加。
	- ZEN向けのcommitの修正忘れ。


- ユーザーの思考エンジンのコンパイルが通るように修正 #117
	- tasanumaさんのプルリク
		ユーザーの思考エンジンがデフォルトの状態だとコンパイルできませんでした。
		とりあえずEVAL_MATERIALにしておきました。


■ 2020/08/01


- Ryzen向け最適化

	- Apery型の遠方駒の利きを求めるコードをporting。

	- ZEN/ZEN2(Ryzen 第一世代、第二世代)のPEXTがμOPレベルでのemulationだから遅い。
	- ZEN/ZEN2向けに、PEXT使ってるところ、magic bitboard導入する。
		- Aperyのmagic bitboard実装をそのまま持ってくる。
		//  https://github.com/HiraokaTakuya/apery/blob/master/src/bitboard.cpp

	- やねうら王では、PEXT命令、飛車の利きなどで使っている。
		このsoftware emulationのコード、1になっているbitの数は64bitのうちの8個程度(平均的には5個程度?)であり、
		1のbitの回数だけループを回すようなアルゴリズムで、テーブルも参照しないコードなので、わりと速い気はする。
		やねうら王の状況では、やねうら王のsoftware emulationのコードのほうが断然速い。(実測で6%程度速いらしい)

	- magic bitboardにするとここがさらに速くなる。
		- ZEN/ZEN2向けはPEXTを完全に排除したので、V4.91から10%以上高速化しているはず。

	- AVX2(非ZEN/ZEN2)に対しても、今回実装した、新しい利きのコードを用いる。
		テーブルサイズは少し大きくなるが、速度はほぼ変わらないので。

	- 55将棋のようなものを作るときに、magic bitboardのmagic numberを求めるの、ちょっと嫌なので
		従来の実装は残しておく。
			USE_MAGIC_BITBOARDをdefineしたときだけ、今回追加されたApery型の遠方駒の利きを求めるコードを
			用いるようにする。


■ 2020/07/31


- 一つ前のcommitでNNUEがコンパイルできなくなっていたのを修正。


■ 2020/07/30


- update mate-engine (#115)
	tanuki-詰将棋エンジン、千日手絡みで不詰と判定される問題の一部を修正。(Qhapaqさんのプルリク)

15手詰め : https://tadaoyamaoka.hatenablog.com/entry/2017/09/26/082125
// ↓テスト用のコマンド

isready
position 1n1g3+Pl/k1p1s4/1ng5p/pSP1p1pp1/1n3p3/P1K3P1P/1P7/9/L1G5L b 2R2BG2SL5Pn 161
go mate infinite

info string pn 0 dn 100000000 nodes_searched 201736
info  time 1858 nodes 201736 nps 108576 hashfull 6
checkmate S*9c 8a9c G*9a 9b9a B*8b 9a8b 7d7c+ 7b7c 8d8c+ 8b7a B*8b 7a6b 8b7c+ 6b5c S*4b 5c4b R*3b 4b3b R*3a 3b2c N*3e 3d3e G*2b 2c1d 1f1e 1d2e 3a3e+
// 解ける


■ 2020/07/27


- MakefileにTARGET_CPU = ZEN1/ZEN2 (Ryzen 第一世代、第二世代)を追加
	- 対応作業中
- USE_BMI2導入
- CPU名末尾にBMI2追加。(usiコマンドの応答時にエンジン名として出力)
- 無駄なinclude削除


- 駒打ちの指し手の生成処理で、二歩にならない場所を生成するためにPEXTを用いていたのを愚直にやるように変更する。
	- AVX2環境で計測できないレベルのslow downしかしない。
	- 駒打ち用のテーブルサイズが半分になる
	- PEXTを使わないのでRyzen環境で高速化が望める。
- foreachBB()追加 (from Apery)

=============================================== ここから =========================================================

			// ここでは2)のためにソフトウェア飽和加算に似たテクニックを用いる
			// cf. http://yaneuraou.yaneu.com/2015/10/15/%E7%B8%A6%E5%9E%8Bbitboard%E3%81%AE%E5%94%AF%E4%B8%80%E3%81%AE%E5%BC%B1%E7%82%B9%E3%82%92%E5%85%8B%E6%9C%8D%E3%81%99%E3%82%8B/
			// このときにテーブルを引くので、用意するテーブルのほうで先に1)の処理をしておく。

			// 縦型Squareにおける二歩のmaskの取得。
			// 各筋に1つしか歩はないので1~8段目が1になっているbitboardを歩の升のbitboardに加算すると9段目に情報が集まる。これをpextで回収する。

			// これにより、RANK9のところに歩の情報がかき集められた。
			Bitboard a = pos.pieces(Us, PAWN) + rank1_n_bb(BLACK, RANK_8); // 1~8段目を意味するbitboard

			// このRANK9に集まった情報をpextで回収。
			u32 index1 = u32(PEXT64(     a.extract64<0>(),      RANK9_BB.p[0]));
			u32 index2 = u32(PEXT32((u32)a.extract64<1>(), (u32)RANK9_BB.p[1]));

			// 歩の打てる場所
			Bitboard target2 = Bitboard(PAWN_DROP_MASK_BB[index1].p[0],PAWN_DROP_MASK_BB[index2].p[1])
				& rank1_n_bb(~Us, RANK_8)
				& target;


// 歩が打てる筋を得るためのBitboard
// bit0 = 9筋に歩が打てないなら1 , bit1 = 8筋に… , bit8 = 1筋に歩が打てないなら1
// というbit列をindexとして、歩の打てるBitboardを返すためのテーブル。
// テーブルサイズが大きくなるのが嫌だったので2つに分割。
//Bitboard PAWN_DROP_MASK_BB[0x80]; // p[0]には1~7筋 、p[1]には8,9筋のときのデータが入っている。



	for (int i = 0; i < 0x80; ++i)
	{
		Bitboard b = ZERO_BB;
		for (int k = 0; k < 7; ++k)
			if ((i & (1 << k)) == 0)
				b |= FILE_BB[k];

		PAWN_DROP_MASK_BB[i].p[0] = b.p[0]; // 1~7筋
	}
	for (int i = 0; i < 0x4; ++i)
	{
		Bitboard b = ZERO_BB;
		for (int k = 0; k < 2; ++k)
			if ((i & (1 << k)) == 0)
				b |= FILE_BB[k+7];

		PAWN_DROP_MASK_BB[i].p[1] = b.p[1]; // 8,9筋
	}

=============================================== ここまで =========================================================


- ビルド手順など古い情報だったところを修正

- HandKind型削除
	- 0.28%ぐらい高速化したかも。(計測誤差レベル..)
	- RyzenだとPEXTが1箇所減ったのでもう少し得してるはず。


// 以下のコード
// これ、PEXT命令使ってるし、ここを乗算で書き換えたが、そもそもmovegenで使ってるだけなのでばっさり削除する。

=============================================== ここから =========================================================

// --------------------
// 手駒情報を直列化したもの
// --------------------

// 特定種の手駒を持っているかどうかをbitで表現するクラス
// bit0..歩を持っているか , bit1..香 , bit2..桂 , bit3..銀 , bit4..角 , bit5..飛 , bit6..金 , bit7..玉(フラグとして用いるため)
enum HandKind : u32 {
	HAND_KIND_PAWN   = 1 << (PAWN   - 1),
	HAND_KIND_LANCE  = 1 << (LANCE  - 1),
	HAND_KIND_KNIGHT = 1 << (KNIGHT - 1),
	HAND_KIND_SILVER = 1 << (SILVER - 1),
	HAND_KIND_BISHOP = 1 << (BISHOP - 1),
	HAND_KIND_ROOK   = 1 << (ROOK   - 1),
	HAND_KIND_GOLD   = 1 << (GOLD   - 1),
	HAND_KIND_KING   = 1 << (KING   - 1),
	HAND_KIND_ZERO   = 0,
};

// Hand型からHandKind型への変換子
// 例えば歩の枚数であれば5bitで表現できるが、011111bを加算すると1枚でもあれば桁あふれしてbit5が1になる。
// これをPEXT32で回収するという戦略。
static HandKind toHandKind(Hand h) {
#if defined(USE_BMI2)
	return (HandKind)PEXT32(h + HAND_BIT_MASK, HAND_BORROW_MASK);

#else

	// PEXT命令が遅い環境用では、PEXTのemulationではなくmagic bitboardの要領で乗算を使って求めるほうが速いと思われる。
	// 手駒は平均的には1,2種類しか持ってないのでPEXTのemulation codeのようにループを回したほうが速い可能性はある。
	
	static_assert(HAND_BORROW_MASK == 0x84488820);

	// この7bitに関しては、うまいmagic numberがないので、分割する。
	u32 u = h + HAND_BIT_MASK;
	u32 u0 = u & 0x00088820; // 1が立っているbit、下から4つ分
	u32 u1 = u & 0x84400000; // 1が立っているbit、上から3つ分

	return (HandKind)(
		(u32(u0 * 0x28849004) >> 28) | ((u32(u1 * 0xbd67e895) & /*上位3bitを*/ 0xe0000000) >> (29-4))
		);
#endif
}

// 特定種類の駒を持っているかを判定する
constexpr bool hand_exists(HandKind hk, Piece pt) { /* ASSERT_LV2(PIECE_HAND_ZERO <= pt && pt < PIECE_HAND_NB); */ return static_cast<bool>(hk & (1 << (pt - 1))); }

// 歩以外の手駒を持っているかを判定する
constexpr bool hand_exceptPawnExists(HandKind hk) { return hk & ~HAND_KIND_PAWN; }

// 手駒の有無を表示する(USI形式ではない) デバッグ用
std::ostream& operator<<(std::ostream& os, HandKind hk);

	
std::ostream& operator<<(std::ostream& os, HandKind hk)
{
	for (Piece pc = PAWN; pc < PIECE_HAND_NB; ++pc)
		if (hand_exists(hk, pc))
			std::cout << pretty(pc);
	return os;
}

=============================================== ここまで =========================================================


■ 2020/07/26


- 解説.txtの内容が古かったので修正。


- SSE3ではなくSSSE3らしいので修正。
	- SSE3とSSSE3は違うらしい。SSSE3はSSE3の後継らしい。うわー😥
	cf. https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%9F%E3%83%B3%E3%82%B0SIMD%E6%8B%A1%E5%BC%B5%E5%91%BD%E4%BB%A4#SSSE3
	- SSSE3にrenameする。


- SSE3対応 from Stockfish NNUE
	cf. https://github.com/nodchip/Stockfish/commit/081761d084452c2cb204614d14f919fc1c0cb567
	NNUEのSSE3向けの高速化。(いまや、そんなCPUのユーザー、ほとんどいないと思われるが…)

// AVX2
Total time (ms) : 7282
Nodes searched  : 3389007
Nodes/second    : 465395

// SSE4.2
Total time (ms) : 9385
Nodes searched  : 3389007
Nodes/second    : 361108

1) AVX2とSSE4.2 , SSE3用でbenchコマンドの探索node数が一致することを確認した。
2) 改造前と改造後で、benchコマンドの探索node数が一致することを確認した。


■ 2020/06/07


- NNUEの学習部でLargeMemoryのメモリ開放に失敗していたのを修正。
- NNUEの学習部で評価関数の書き出しに失敗したらエラーメッセージを出力して即終了するように。


■ 2020/06/01 V4.91


- V4.91
	- LargePage周り、一通り動作確認できたのでバージョンを上げておく。
	- 将棋神やねうら王のupdate3に収録するのは、このバージョンにする。
	- 将棋神やねうら王の実行ファイルのupdateはこれが最終になる予定。


- NNUE評価関数、Eval::load_eval()を連続して行うとクラッシュするのを修正。
	- 通常、Eval::load_eval()を2回呼び出さないが、学習部の実装によってはこれをやりうる。

- LargeMemory.alloc()によって256MB以上のメモリ空間を確保する場合、スレッド並列でクリアするように変更。
	- EvalHashが大きいときに少しだけ有利かも。


- Stockfishの現時点での最新コードのうち、探索に影響しない部分だけ取り入れる。
	- ONE_PLY マクロの削除
	- DEPTH_MAX削除。今後は、MAX_PLYを使うようにする。
	- DEPTH_ZERO削除。0を使う。
	- depthをtypedef intに変更。
	- reverse_move()追加。
	- TTのデストラクタでfree()を呼ぶコードになっていたの修正。
	- compiler_info()追加。
	- USIコマンドに"compiler"追加。
	- thread_win32.h → thread_win32_osx.hにrename
		- WIN32用のMutexクラス削除
		- OSX用のThreadクラス追加。

- benchコマンドに影響するのでConsiderationModeのとき、PV出力のときに置換表のconst性を保つように修正。
	- (置換表はPV出力によって一切書き換えない)
	- TT.read_probe()追加。
	- USE_TT_PVコンパイルオプション削除


// refactoring後に探索ノード数が一致するかのテスト
Total time (ms) : 7527
Nodes searched  : 3389007
Nodes/second    : 450246


■ 2020/05/31


- LargePageを使っているかどうかをLinux/Android環境でも初回だけ出力するようにする。


- misc.cpp、Large Pageのコード、Linuxでビルドが通らなくなっていたのを修正。
- KPPT/KKP_KKPTでEvalShare有効(default)のときは、評価関数テーブルはLargePage使えないが…。まあいいか…。


- ファイル構成、少しStockfishに近づける。
	- extra/benchmark.cpp → bench_mark.cpp に移動
	- sse.cpp → position.cppのなかに移動させて削除
- ifdefと書いてあるところ、if defined()で統一する。
	- Stockfishのコードでそう書かれているところはそのままにしておく
- コメント、色々整理した。


- Large Pageを使うメモリアロケーター用にLargeMemory class作った。
	- このclassを使って、ソースコード整理した。ずいぶん綺麗になった。


■ 2020/05/30


- 置換表にLarge Pageを使うように変更。

	Large Pageを使うには、SeLockMemoryPrivilegeが必要。

	Group Policy Editorで変更する手順。

	1. グループポリシーエディター(gpedit.msc)を起動する
	2. ローカルコンピューターポリシー → コンピュータの構成 → Windowsの設定 → セキュリティの設定 → ローカルポリシー
		 → ユーザー権利の割り当て → メモリ内のページのロック
	3. ここで適切なユーザーに権限を付与する。
	4. OSを再起動する

	cf.
	Enable the Lock Pages in Memory Option (Windows)
	https://msdn.microsoft.com/en-us/library/ms190730.aspx

===========================
Total time (ms) : 9944
Nodes searched  : 7129455
Nodes/second    : 716960
info string Hash table allocation: Windows large pages used.

===========================
Total time (ms) : 10523
Nodes searched  : 7129455
Nodes/second    : 677511
info string Hash table allocation: Windows large pages not used.

Surface Pro6で計測したところ、これにより5.8%程度、高速化しているようだ。
NNUE/KPPT/KKP_KKPT用のメモリもここから確保するように変更。1,2%程度高速化するようだ。

ついでにEvalHashもここから確保するように変更。
EvalHashが大きいときに(1024MBとか)、5%前後高速化するようだ。

この3つ合わせると、トータルで10数%高速化するようだ。

確保~開放を繰り返すと、断片化するのか、Large Pageのメモリ確保に失敗するようになることがある。(´ω`)
うーん、、なんぞこれ…。プロセス終了の時にここで確保したメモリ、開放していないのがいけないのかも…。
USIのquitコマンドで抜けても、そのときに開放してないという問題はあるのか..

- misc.h / prefetch2()、使ってないので削除。

- aligned_alloc()/aligned_free() 削除。
	C++17では、newでもalignasの指定が生きることになったので

	cf.
		C++17: アライメント付き動的メモリ確保
		https://qiita.com/niina/items/7a6c18c018c4100adb28


■ 2020/05/29


- KPPT/KKP_KPPT用の実行ファイルをビルドする時、Clangだと20GB以上消費する問題を修正。

	newでstd::arrayに関して巨大メモリを確保しようとすると、Clang10.0.0でのコンパイル時に
	メモリを20GB以上持っていかれる(´ω`) Clangのbugの何らかの最適化が悪さをしている可能性が…。


■ 2020/05/28 V4.90


- V4.90
	- 定跡まわり、問題なさげなのでバージョン上げておく。
	- 次回は、メジャーバージョンアップの予定。V5.00


■ 2020/05/26


- PV_OUTPUT_DRAW_ONLY オプション追加。(大人の都合により)

- TextFileReader、eof()の判定おかしかった。最後が改行コードがないと永久ループになることがあったのを修正。
 全面的に書き直した。(定跡の読み込み等で、ファイルの最後のほうが読み込まれていなかった可能性あり)

 テストコード:

	TextFileReader reader;
	if (reader.Open("test.txt").is_ok())
	{
		reader.SkipEmptyLine(true);
		reader.SetTrim(true);

		std::string line;
		while (reader.ReadLine(line).is_ok())
			std::cout << line << "//" << std::endl;
	}


■ 2020/05/19


- USI拡張コマンド.txtのUSI_Hashの説明を修正した。


■ 2020/05/01

- Book::read_book()で最終行の空行をnoneと解釈してしまう不具合を修正。
	- cf. https://github.com/yaneurao/YaneuraOu/issues/113
- TextFileReaderのReadLine()でtrimを引数の取るのやめる。
	- SetTrim()で設定するようにする。


■ 2020/04/01


- MemoryBookクラス、整理した。
- makebookコマンドでBookIgnorePlyをデフォルトfalseに設定するようにした。

// 定跡の生成テスト

usi_hash 2048
Threads 4
MultiPv 4
makebook think book/flood2018.sfen mybook.db startmoves 1 moves 4 depth 4


// 定跡テスト用のUSIコマンド

position startpos moves 5i5h 5a5b 5h5i 5b5a
// ↑ply違いの初期局面

---

IgnoreBookPly true
isready
go

IgnoreBookPly false
isready
go

IgnoreBookPly true
isready
position startpos moves 5i5h 5a5b 5h5i 5b5a
go

IgnoreBookPly false
isready
position startpos moves 5i5h 5a5b 5h5i 5b5a
go
---
BookOnTheFly true



- IgnoreBookPly==true(default動作)のときにmakebookthinkコマンドで思考済みの局面がhitしない問題を修正。
- IgnoreBookPly==trueのときに定跡を書き出す時は、sfenのplyのところを0にして書き出すようにした。(あまり嬉しくないけど、そうなってしまった)


■ 2020/03/13


- Tools::Result型を追加。一般的なエラーはこれを用いて返すように変更。RustのOption型みたいな何か。
- 置換表の初期化時に"USI_Hash clear"となっていたの"Hash clear"に修正。
- main()でDirectory::init()は格好悪いので、Misc::init()に変更。


■ 2020/03/09


- USI原案に従い、 "USI_OwnBook"というオプションの追加
	- cf. SkillLevelのオプション名について
    - https://github.com/yaneurao/YaneuraOu/issues/111
- "USI_SkillLevel"に変更するのは、しない。
- "Hash"オプションも、将棋所で個別にHash値が設定できるようになったので、USIプロトコルに従い
	"USI_Hash"にリネームする。(あちこちに影響でかねないが…)

	cf.
	やねうら王のエンジンオプションをUSIプロトコル原案に準拠させる件
	http://yaneuraou.yaneu.com/2020/03/09/%e3%82%84%e3%81%ad%e3%81%86%e3%82%89%e7%8e%8b%e3%81%ae%e3%82%a8%e3%83%b3%e3%82%b8%e3%83%b3%e3%82%aa%e3%83%97%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92usi%e3%83%97%e3%83%ad%e3%83%88%e3%82%b3%e3%83%ab/



// やっぱやめる
- floodgate用に、"isready"に対して即座に"readyok"を返すコンパイルオプションを追加。("FLOODGATE")

	// floodgateは、"isready"のあとタイムアウトチェックがあるので初期化があまりに遅いとrejectされる。
	// cf. https://twitter.com/JKishi18gou/status/1236667302134743042
	// 大きなメモリを確保しようとするとこれでrejectされる可能性はあるので、
	// この場合、先行して"readyok"を返す。(そのあと初期化を行うので思考時間は損をするが1分ぐらいなら…)

	floodgateの仕様、そうでもないらしい → https://twitter.com/JKishi18gou/status/1236934238198362112



- Android用Makefile、Windows版に合わせて更新。


■ 2020/03/08


- isreadyの応答まで、keep alive代わりに改行を送る処理、やっぱり元のように送るようにする。
	- https://github.com/yaneurao/YaneuraOu/commit/081511097b6f71ea14123c3227fd98dd1f99f830 のロールバック
	- cf. http://yaneuraou.yaneu.com/2020/03/08/isready%e5%be%8c%e3%81%aekeep-alive%e7%94%a8%e6%94%b9%e8%a1%8c%e3%82%b3%e3%83%bc%e3%83%89%e3%81%ae%e9%80%81%e4%bf%a1%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/
	- さらにworkerスレッドの生成完了を待機するコード追加する。



■ 2020/02/29


- EvalShareは、評価関数の格納フォルダ("EvalDir"オプションで指定)のフルパス名が一致した時に共有するように仕様変更。
	- これならハマる人もいないだろうから、KPPT/KPP_KKPTではEvalShareはデフォルトでOnに変更。

- Directory::GetCurrentFolder()追加。

- KPPT/KPP_KKPTのEvalShareの実装に使っている
		std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> cv;
	がdeprecated in C++17。
	なので、WindowsAPIを用いてマルチバイトからワイド文字列に変換するように変更。

- CreateDirectory()でcodecvt_utf8を使わないように変更。

- 評価関数ファイルの読み込み時にそのフォルダ名をフルパスで出力するようにした。
	- Linuxで動作確認した

- StringExtension::mid(str,start)削除
	- str.substr(start)と書いたほうがわかりやすい気がするので。

- main.cpp、文字コードがsjisになっていたのでutf-8に変更。

- my_insertion_sort → Tools::insertion_sortに変更
	- 前回の変更忘れも修正。(Tools::をつけずにmy_insertion_sortを呼び出している箇所が残っていた)


- mateエンジンでトーナメントビルドに失敗するのを修正。(Mizarさん)
	cf. https://github.com/yaneurao/YaneuraOu/pull/109


■ 2020/02/28 V4.89


- V4.89にバージョンナンバーを上げる。
	- 公開している実行ファイルから、YaneuraOu2018の2018の文字を取り除く。
	- tanuki-詰将棋エンジンは、tanuki_MATE_XXXというファイル名で公開するように変更する。


- misc.h/cppのリファクタリング
	- Pathをstructではなくnamespaceに。
	- misc.hにあったnamespaceの外に出てた独自拡張の関数をnamespace Toolsに。
	- my_exit() → Tools::exit()に移動。
	- uint64_t get_thread_id(); → 削除
	- sleep() → Tools::sleep()に移動。
	- struct Finally → BOOST:: BOOST_SCOPE_EXITに倣い、マクロで実装しなおす。
		- SCOPE_EXITマクロ追加。
	- StringExtension::trim_inplace()追加
	- StringExtension::trim()のコード、簡略化。
	- Dependency::getline() → Tools::getline()に移動。

このcommitによる機能的な変更は無し。


■ 2020/02/26


- 定跡読み込み高速化
  - ifstreamを使うのをやめた
  - istringstreamを使うのをやめた
  - 大改造になったので何かバグってたら教えてください(´ω`)


- 定跡にhitしたときに、読み筋(pv)のあとにscore等を出力していたの修正。
(USIプロトコルではpvのあとにサブコマンド(score,depth等)を書くことはできない
とされているのでこれはUSIの規約違反)

誤) info pv 3i4h 3c3d 6i7h 4a3b 2g2f (4.17%) score cp 31 depth 3 multipv 4
正) info score cp 31 depth 3 multipv 4 pv 3i4h 3c3d 6i7h 4a3b 2g2f (4.17%)


■ 2020/02/06


- NNUEの学習用のビルドで、gccで未初期化の配列がある警告が出ていたのを抑制。


■ 2020/01/20


- mkdir()→CreateFolder()に変更した件、test_cmd.cpp修正忘れ。(#106) Mizarさん。


- isreadyのあと、keepalive代わりに改行を5秒ごとに送信していた件、やめる。

cf. USIプロトコルでisready後の初期化に時間がかかる時にどうすれば良いのか? : http://yaneuraou.yaneu.com/2020/01/05/usi%e3%83%97%e3%83%ad%e3%83%88%e3%82%b3%e3%83%ab%e3%81%a7isready%e5%be%8c%e3%81%ae%e5%88%9d%e6%9c%9f%e5%8c%96%e3%81%ab%e6%99%82%e9%96%93%e3%81%8c%e3%81%8b%e3%81%8b%e3%82%8b%e6%99%82%e3%81%ab%e3%81%a9/


- BookOnTheFlyで定跡にhitしないことがあるのを修正。
	cf. https://github.com/yaneurao/YaneuraOu/issues/102


- nodestimeオプション廃止。
  - 秒読みを考慮していなかったが、それとは別に、将棋(やねうら王)の場合、NetworkDelay,NetworkDelay2やMinimumThinkingTimeなどの影響も計算しないといけなくて、そのへんまできちんと計算しようと思うと時間制御のコードがすごく複雑化するというのと、そもそもこの機能要らないんじゃ…みたいに思えてきたのでこの機能は削除する。
- EngineNumaオプションの説明削除。


- gcc/clangのためにMakefile修正。
	- gcc/clangの新しいバージョンでは、-std=c++1zではなく、-std=c++17と書く必要がある。
		- cf. https://cpprefjp.github.io/implementation.html


- C++17でコンパイルするように変更。
	- Makefile、gcc/clangでC++17でコンパイルするように変更。
	- alignasを指定しているとnewしたときもそれを守るようになったらしいので、
		custom allocatorのコードを削除する。
		cf. https://cpprefjp.github.io/lang/cpp17/dynamic_memory_allocation_for_over-aligned_data.html
	- alligned_malloc()自体は、HashTableで使っているので削除できない。


- 一つ前の修正でmisc.cpp、gcc/clangでコンパイル通らなくなっていたのを修正。
	cf. https://github.com/mizar/YaneuraOu/commit/3bcc7cda8176644261008f5ead0a964fb348ebf8


■ 2020/01/18


- misc.hにあった、mkdir、Directory::CreateDirectoryに移動。


- Visual C++ 2019では、C++14からC++17でコンパイルするように変更。
	- C++17のfilesystemを使うように変更。(misc.h/cppにDirectoryクラス追加)
	- gcc/clangではビルドの仕方よくわからん…。
- yaneuraou-search.cpp、utf8のBOMついてなかったのでつけた。


■ 2020/01/17

- fix "makebook endless_extend_tree" (#103)
	- "makebook endless_extend_tree"コマンドがバグっていたの修正。Mizarさん。

- perft LEGAL_ALL (#105)
	- perftコマンドで香の不成などを生成していなかったの修正。Mizarさん。
⚠️ **GitHub.com Fallback** ⚠️