Ubuntuのドライバー問題

Ubuntuで動画みているともっさりすると思っていたらどうも、UbutunはNvidiaGPUのドライバを自動でインストールしてくれるがそれはオープンソースのもので、NVIDIA社が公開しているものとはっきり性能が悪いかららしい。

インターネットを検索するとこういう記事があったhttps://qiita.com/y-vectorfield/items/72bfb66d8ec85847fe2f。 これの通り、nvidia-driver-525をインストールした。

実は私もまんまとhttps://qiita.com/abetomo/items/a114a3c423f110460549のような記事に騙されてrecommendedをインストールして再起動したら画面が真っ暗になった。

教訓recoomendを信じずに"-open"がついてない最新のドライバを入れろ。

__Boardの関数列挙

  • __Board()
  • __Board(string)
  • ~__Board()
  • void set(string)
  • bool set_position(string)
  • bool set_hcp(char*)
  • bool set_psfen(char*)
  • void reset()
  • string dump()
  • void push(int)
  • void pop()
  • int peek()
  • bool is_game_over()
  • int isDraw(int)
  • move(int, int, bool)
  • drop_move(int, int)
  • int move_from_usi(string&)
  • int move_from_csa(string&)
  • int move_from_move16(unsigned short)
  • int move_from_psv(unsigned short)
  • int turn()
  • int ply()
  • string toSFEN()
  • string toCSAPos()
  • void toHuffmanCodedPos(char*)
  • void toPackedSfen(char*)
  • int piece(int sq)
  • void toPackedSfen(char*)
  • int piece (int)
  • bool inCheck()
  • int mateMoveIn1Ply()
  • int mateMove(int)
  • bool is_mate(int)
  • unsigned long long getKey()
  • bool moveIsLegal(int)
  • bool is_nyugoyoku()
  • bool isOK()
  • vector piece_in_hand(int)
  • vector pieces()
  • void piece_planes(char*)
  • void piece_planes_rotate(char*)
  • unsigned long long bookKey()
  • void bbToVector(PiceType, Color, Piece, vector)

__Boardの変数

  • Position pos
  • deque<pair<Move, StateInfo>> history

ポインタ

スマートポインタについて読んだ C++11スマートポインタ入門

__LegalMoveListはshared_ptrでMoveListを管理している. 理由はよくわからない. 所有権を複数で保つ必要がなさそうに見えるが. MoveListのポインタを持っているのでMoveListについて読む MoveListはgenerateMovesで初期化したMoveの配列を管理するクラスっぽい. Pythonでのイテレータとしての機能を果たすための関数を用意してあげているような感じ. 他にもいろいろ関数がありそうだけど,知りたいことは合法手生成だからgenerateMovesをよむ. generateMoves.cppで作っているLanceAttackみたいな配列の計算. これは色,香車の位置,駒の配置の3軸のパターンで可能な移動先をbitboardなんかよくわからない.

generateLegalMoves

関数のながれは次のよう

  • generateMoves(moveList, pos)
  • GenerateMoves<Legal, US>()(moveList, pos)
    • GenerateMoves<Eavasion, US>()(moveList, pos)
      • makeNonPromoteMove(King, ksq, to, pos)
      • GeneratePieceMoves<Evasion, Pawn, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, Lance, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, Knight, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, Silver, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, Bishop, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, Rook, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<Evasion, GoldHorseDragon, US, false>()(moveList, pos, target, ksq)
    • GenerateMoves<NonEavasion, US>()(moveList, pos)
      • generateDropMoves(moveList, pos, target)
      • GeneratePieceMoves<NonEvasion, Pawn, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, Lance, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, Knight, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, Silver, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, Bishop, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, Rook, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, GoldHorseDragon, US, false>()(moveList, pos, target, ksq)
      • GeneratePieceMoves<NonEvasion, King, US, false>()(moveList, pos, target, ksq)

王手回避のEvasionの方は難しいので,NonEvasionを読む.

なんか読めた気がする.トップダウン・アプローチ大事. 関係関数省略できるもんね. GeneratePiceMovesのPawnと,Lanceを読んだ. bitboardの使い方がやっとわかった.PawnとLanceの合法手生成まででいちど書いてみるのもいいかもしれない. 一番めんどくさいのは,事前計算部分だと思う. 具体的にはinit.cppで作っているLanceAttackみたいな配列の計算. これは色,香車の位置,駒の配置の3軸のパターンで可能な移動先をbitboardとして返してくれる配列. これの計算パートはまだ読んでいない.... そうでした.ここが不思議かもしれない.

Goのメモ

packageとmodule

example.com/foo というモジュール内でbar1とbar2にパッケージが別れているときには

package bar1

import "example.com/bar2"

という感じで素直にimportすればよい.

一方でローカル開発時に2つのモジュールfoo1とfoo2がある場合はfoo1がfoo2を参照している場合はgo.modに

module exmpale.com/foo1
go 1.17
replace exmaple.com/foo2

という記載をしないといけない. これはgo modで

go mod edit -replace example.com/foo2=/path/to/foo2

という風に書き換えるらしい. Goの公式ドキュメントに書いてあった.

go.dev

220122

220122

Bitboardは平日に読んだとしてPositionを読む

postion.hpp

定義されているstructやclass

  • CheckInfo
  • StateInfo
  • BitStream
  • HuffmanCode
  • HuffmanCodeToPieceHash
  • HUffmanCodedPos
  • HuffmanCodedPosAndEval
  • PackedSfen
  • PackedSfenValue
  • Position
  • CharToPieceUSI

Postionでかすぎる. 正直本当に読みすすめるのが苦しい.理由は簡単で詳細が不明なものがいくつも並んでいて処理できないから. まず量に圧倒されているし,そしてその内容もそれぞれ難解.何十年と作り上げられたソフトなのだからそれはそうなのかもしれないが. 苦しんでばかりいられないので消化できるところは消化していきたい. ざっくりと受けた印象では,ここまででてきたものに複雑な処理はしているというよりはかんたんな処理をしてメンバを返すみたいな関数ではないかと思っている.

量に圧倒されているからメソッドを書き出してみる

  • set * 3
  • set_hcp
  • set_psfen
  • bbof * 9
  • occupiedBB
  • emptyBB
  • goldsBB
  • piece
  • hand
  • pinnedBB
  • noPawns
  • isPinnedIllegal
  • isDiscoverdCheck
  • checkersBB
  • prevCheckersBB
  • isCheck
  • moveGivesCheck * 2
  • movedPiece
  • attackersTo * 3
  • attackersToExceptKing
  • attackersToIsAny * 2
  • unDropCheckIsSupported
  • attacksFrom * 6
  • attacksSlider * 2
  • attacksAroundKingNonSlider
  • attacksAroundKingSlider
  • attacksAroundKingNonSiderIsAvoiding
  • attacksAroundKingInAvoiding
  • canPawnDrop
  • pinnedPieces
  • turn
  • pseudoLegalMoveIsLegal
  • pseudoLegalMoveIsEvasion
  • moveIsPseudoLegal
  • moveIsLegal
  • doMove * 2
  • undoMove
  • mateMoveIn1Ply * 2
  • gamePly
  • getBoardKey
  • getHandKey
  • getKey
  • getKeyExcludeTurn
  • print
  • toSFEN * 2
  • toCSAPos
  • toHuffmanCodedPos
  • toPackedSfen
  • isDraw
  • setStartPosPly
  • isOk
  • initZobrist

private:

  • clear
  • setPiece
  • setHand * 2
  • findCheckers
  • xorBBs
  • computeBoardKey
  • computeHandKey
  • computeKey
  • printHand
  • zobrist
  • zobTurn
  • zobHand

90近いメソッドがあることがわかった.これは一読で処理できるわけない. ボトムアップでは処理しきれない印象. トップダウン的にどう使われるかの観点から見ていく事も考えないといけない. というか理解できないコードの処理を読めばいいわけで,全部が全部を読む必要はそもそもないと思う.決して自分を慰めているわけではない.極めて冷静な状況分析である.

Positionが終わっても関数ラッシュ.これは外に定義されているだけでメソッドのようだ.テンプレートを使うために外に出している模様.これらを合わせると100以上あることになる.おかしい.

  • attacksFrom< Lance>
  • attacksFrom< Bishop>
  • attacksFrom< Rook>
  • attacksFrom< Horse>
  • attacksFrom< Dragon>
  • attacksFrom< Pawn>
  • attacksFrom< Lance>
  • attacksFrom< Knight>
  • attacksFrom< Silver>
  • attacksFrom< Bishop>
  • attacksFrom< Rook>
  • attacksFrom< King>
  • attacksFrom< Horse>
  • attacksFrom< Dragon>

いったんここらでcshogi.hppに戻るというのはどうだろうか. 少しposition.cppを見てみたが4000行近い.逐一見ている頃には春になっている.

コード読むばかりでは理解が深まらない気がするので,来週あたりから書きながら読むフェーズに入ってもいいかもしれない.

cshogi.hpp

class __Board

Postionをメンバにもっていて,基本的にはそのメソッドを呼び出している.だからPositionを無理に読もうとするよりもこちらから呼び出されているメソッドから読んでいくと読みやすいかもしれない. 実際問題bookから呼び出されているようなものもあるだろうし.

  • set
  • set_position
  • set_hcp
  • set_psfen
  • reset
  • dump
  • push
  • pop
  • peek
  • is_game_over
  • isDraw
  • move
  • drop_move
  • move_from_usi
  • move_from_csa
  • move_from_move16
  • move_from_psv
  • turn
  • ply
  • toSFEN
  • toCSAPos
  • toHuffmanCodedPos
  • toPackedSfen
  • piece
  • inCheck
  • mateMove
  • is_mate
  • getKey()
  • moveIsPseudoLegal
  • moveIsLegal
  • pieces_in_hand
  • pieces
  • pices_planes
  • pices_planes_rotate
  • bookKey
  • bbToVector

読んでみた感想としてはもう書いていいんじゃないかなって思う. 一応move系が残っているがまぁ大したことないんじゃないかなと思っている. 有効手の生成は大変な気もするけど.

220115

220115

cshogiとdlshogiのどちらを読むかというかと考え直した.ソースをざっと見た感じdlshogiはcshogiと大半は同じなように見えた.cshogiではpythonで実装していた部分がc++になっていそうなところもあり追加や更新があるように見える.とはいえほとんど同じソースでありそうなのでひとまずはcshogiの方を読んでいけばあとからdlshogiを読んでも無駄にはならないだろう,むしろ少ないソースのほうが読みやすくてよいだろうという判断からcshogiを読むことにした.

本日は自宅で作業をする.図書館に行く手もあるが手間だし,なるべく家で開発できる様になりたい.PCを自作するとどうしてもハードに引っ張られて家にこもらないといけなくなることになると予想している.仕事と同じ空間ではやりたくないので,またコロナが蔓延してもなるべく出社をしていきたいと思う.

今日の作業はcshogiのソースツリーの末端ノードから読んでいくこと.狙いは下記あたりを想定している. - overloadEnumOperator.hpp - ifdef.hpp - common.hpp - color.hpp - piece.hpp - hand.hpp - square.hpp

これらが終わると,bitoboard.hppを読むことができ,そしてそれが終わればmove.hpp,そしてgenerateMovesに進むことができる.このあたりが本丸なので今日はその前哨戦といったところだろうか.

overloadEnumOperator.hpp

C++enumクラスに加減乗除等の基本的な演算子オーバーロードして実装している.このマクロのおかげでPieceとかのenumに演算を実行することが可能になる.

ifdef.hpp

SIMD命令が使用可能か等をマクロ定義済みかで確認して,使うかどうかのマクロ定数を定義している.

  • 表関数のSIMD
  • 稲庭判定を有効にするか
  • 角の打ち場所の限定をするか
  • 入玉を24点法にする など設定をするために使われている模様.

common.hpp

とりあえず定義されているものを列挙しておく 正直どう使っているかわからないと内容を理解するのが難しい.というよりも理解する必要性に乏しい.

  • u32.. bit幅用の型の定義
  • Binary<> Binary標記to数値変換
  • firstOneFromLSB
  • lsb
  • firstOneFromMSB
  • msb これはLSBとかMSBを求めるための関数
  • count1s(popcount)
  • putb バイナリ表示
  • enum SyncCout
  • struct Unroller<>
  • prefetch
  • struct HashTable
  • class Timer
  • struct Mutex
  • struct TriangularArray

color.hpp

先手後手がそれぞれ黒と白としてenumで定義されている

piece.hpp

基本的にenumで駒を定義しているのと,関連の変換関数が定義されている. - enum PieceType - enum Pice - enum HandPiece - inverse(Piece) - pieceToColor - colorAndPieceTypeToPice - isSlider - pieceTypeToHandPiece - handPieceToPieceType - colorAndHandPieceToPiece

hand.hpp

初期化子について思い出した.ありがたい. これは持ち駒の管理をするHandクラスを定義している.Handクラスには持ち駒の数をPieceTypeごとに教えてくれたり,ある駒の持ち駒があるか教えてくれる関数があったりする.あとは駒の増減とか. - numoF - exists - exceptPawnExists - plusOne - minusOne - isEqualOrSuperior

square.hpp

盤上のマスの定義が行われている.主に下記の列挙子の定義が行われている.

  • Square
  • File
  • Rank
  • SquareDelta
  • Direction
  • SquareWithWall
  • Directions

Squareは盤上のマスそれぞれに数値を与えている. SquareWithWallはSquareに加え,そのマスから番外までの距離を含めた情報を保持するように設計されている. このソースだけ読んでも内容はわかるが,おそらくその設計の真価を判断するのには駒の利きを判断する合法手生成のソースであろう.

ということで今日の分は一通り読んだ.次回はbitboard.hppから初めていこうと思う. どのタイミングで実装を始めるかは悩みどころ.まだ定義部分でしかないので,これから本格的な部分に足を踏み入れていくのでそのときに判断かなとは思っている.今の部分だけ書き写しても意味というか意義が特にない.

22/1/13

参考ライブラリのソースコードを読み始めることにした.Cythonが読めるようになることが大事かなと思っていたが,ざっくりソースをみたかんじだと単純にcppで書かれたものをimportしているだけなのであまり重要ではなさそう.むしろその裏にあるC++のコードを早速読むことのほうが大事だと理解した.

C++についてはCythonから読み出されていたのがcshogi.hで,cshogi.hの中でメインとなるBoardクラスの中で重要な役割を担っていそうな方がPosition型で,それが定義されているのがposition.hだった.

position.hを読みたくなるがさらにこいつがincludeしているのが

  • bitboard.hpp
  • common.hpp
  • hand.hpp
  • piece.hpp

だった.common.hppは同様に

  • ifdef.hpp

をinclude していてこれは末端のヘッダの1つであった.hand.hppは

  • common.hpp
  • piece.hpp

をincludeしている.piece.hppは

  • color.hpp
  • overloadEnumOperators.hpp

color.hppは

  • overloadEnumOperators.hpp

をincludeしており,overloadEnumOperatos.hppは末端ヘッダであった.

.bitboard.hppは

  • common.hpp
  • square.hpp
  • color.hpp

includeしており,square.hppは

  • overloadEnumOperatos.hpp
  • common.hpp
  • color.hpp

をincludeしている.よってここまでを整理すると,

  • ifdef.hpp
  • common.hpp
  • overloadEnumOperatos.hpp
  • color.hpp
  • piece.hpp
  • hand.hpp
  • square.hpp
  • bitboard.hpp
  • position.hpp

の順で読むことが可能になることがわかった.大進歩である.

一旦これらを読み終わったら,再びcshogi.hpp に戻ってgenerateMoves.hppのような手強さそうなソースを読むことになるのだろうと思う.

ヘッダファイルごとに読んで内容をまとめていかないと記憶が発散しそうである. エッジ情報を書いたらグラフを書いてくれるツールがほしい.

22/1/9

課題本を読んだ.今日は6章を読めればいいかなと思ったけど通しで一通り読んだ. 7章8章も読んだけど正直内容が頭に入っているかといえば怪しい.

5章6章はcshogiを使ったpythonでのAIで,7章は強い将棋AIを作成すると言いながら新しい実装は何も書いていなくてdlshogiをライブラリとして完全にそのまま使用する感じだった.dlshogiを使って利用価値の高い棋譜を使って学習して強いAIになることを水匠4と対局してみて検証するということがコンセプトなのかなとは思う. 8章はdlshogiを使って,7章までで学習してモデルのチューニングを行った上でさらに強くするために,強化学習の手順,定跡の作成手順,ハイパパラメータの調整,棋力測定について記載していた.

詳しい内容はさわってみないと正直ピンとこない.少なくとも5,6章の内容で一度AIを作ってみるというのがいいと思う.それが2月末までの目標.