scramble cadenza

技術ネタのガラクタ置き場

Mac で apery を compile する

イントロ

最近、職場の後輩に将棋で負けたことをきっかけに、将棋がマイブーム。

apery って?

将棋プログラムの一種。2014 年の世界大会で優勝したとかなんとか。
一部界隈では、あの ponanza 先生をも凌ぐとかなんとか言われている?らしく、とにかくすごく強いソフト。

Apery - Wikipedia

で、そんな世界大会で優勝した将棋エンジンが github 公開されているのを知ったので、compile してみました。

HiraokaTakuya/apery

そのままやると...

すさまじい警告が出て、失敗する

$ make
24 warnings generated.
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -march=native  -o ../obj/common.o -c common.cpp
g++ -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -march=native  -o ../obj/pieceScore.o -c pieceScore.cpp
g++ -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../obj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/hand.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/thread.o ../obj/common.o ../obj/pieceScore.o -lpthread  -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -march=native
ld: library not found for -lgomp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [apery] Error 1

gomp というライブラリが無いと言われているようだ。

gomp とは

GOMP — An OpenMP implementation for GCC - GNU Project - Free Software Foundation (FSF)

openMP で実装している GNU project らしい。

openMP とは

複数CPU を効率的に計算するライブラリのこと。所謂スレッド。
http://www.cc.u-tokyo.ac.jp/support/kosyu/03/kosyu-openmp_c.pdf

計算を早く行うためにマルチスレッドで処理しているのだろう、と想像。

それと URI protocol の仕様として、計算中でも入力を受け取れるようにしなければならないので、そういうところでもスレッドの出番はありそう。

Mac でどう compile するか

g++-4.9 で compile する

環境

  • OSX 10.11.2
$ brew install gcc49
$ g++-4.9 --version
g++-4.9 (Homebrew gcc49 4.9.3) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,4 +1,4 @@
-COMPILER = g++
+COMPILER = g++-4.9
 #COMPILER = mpicxx
 CFLAGS   = -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp
 CFLAGS   += -march=native

結果

$ cd src
$ make
g++-4.9 -o apery ../obj/main.o ../obj/bitboard.o ../obj/init.o ../obj/mt64bit.o ../obj/position.o ../obj/evalList.o ../obj/move.o ../obj/movePicker.o ../obj/square.o ../obj/usi.o ../obj/generateMoves.o ../obj/evaluate.o ../obj/search.o ../obj/hand.o ../obj/tt.o ../obj/timeManager.o ../obj/book.o ../obj/benchmark.o ../obj/thread.o ../obj/common.o ../obj/pieceScore.o -lpthread  -std=c++11 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fopenmp -march=native

というわけでうまくいった。

うまくいったけど、どういうことなのか

HiraokaTakuya/apery の README.md より。

Linux のディストリビューションによっては、Makefile に記述されている '-lpthread' を '-pthread' にしなければ、
実行時にエラーになってしまう場合があります。
Linux, Windows で G++ 4.8 以上のバージョンで動作確認をしています。
Clang では正しくビルド出来ているか確認出来ていません。
Visual Studio でビルドすることは現状では出来ません。
Windows でビルドする場合は、MinGW64 をお使い下さい

というわけで、g++4.9 を使うとうまくいく、と。
mac のデフォルトでは、gcc コマンドが clang コマンドの alias になるという罠があり、明示的に 4.9 以上の gcc を指定する必要があった、というオチ。
普段の生活では gcc に馴染みがないので、少しハマった。

起動を早くする

初回起動時は評価関数生成のため、起動が非常に遅い。
ので、以下を行って評価関数のみ生成しておく。

linux,macでのコンパイルと使い方 · HiraokaTakuya/apery Wiki

$ git submodule init
$ git submodule update --depth=1

# コンパイル済みの apery を bin 以下に移動させる
$ cp ../src/apery . 

$ ls bin
20151105                  Readme.txt                apery                     book                      make_synthesized_eval.bat make_synthesized_eval.sh

# bin の directory 上で `make_synthesized_eval.sh` を実行する。
$ cd bin
./make_synthesized_eval.sh
info string start setting eval table
info string end setting eval table

で成功。
make_synthesized_eval.sh が、bin 以下で実行されること前提の実装になっていたのが難しかった。

動かしてみる

# 入力待ちになる
$ ./apery

# 標準入力で通信開始の合図を入れる
usi

# apery が標準出力でレスポンスを返してくれる
id name Apery Debug Build
id author Hiraoka Takuya

option name Best_Book_Move type check default false
option name Book_File type string default book/20150503/book.bin
option name Byoyomi_Margin type spin default 500 min 0 max 2147483647
option name Clear_Hash type button
option name Emergency_Base_Time type spin default 200 min 0 max 30000
option name Emergency_Move_Horizon type spin default 40 min 0 max 50
option name Emergency_Move_Time type spin default 70 min 0 max 5000
option name Eval_Dir type string default 20151105
option name Max_Book_Ply type spin default 32767 min 0 max 32767
option name Max_Random_Score_Diff type spin default 0 min 0 max 32600
option name Max_Random_Score_Diff_Ply type spin default 40 min 0 max 32767
option name Max_Threads_per_Split_Point type spin default 5 min 4 max 8
option name Min_Book_Ply type spin default 32767 min 0 max 32767
option name Min_Book_Score type spin default -180 min -32601 max 32601
option name Minimum_Thinking_Time type spin default 1500 min 0 max 2147483647
option name MultiPV type spin default 1 min 1 max 594
option name OwnBook type check default true
option name Skill_Level type spin default 20 min 0 max 20
option name Slow_Mover type spin default 100 min 10 max 1000
option name Threads type spin default 4 min 1 max 64
option name Use_Sleeping_Threads type check default false
option name USI_Hash type spin default 256 min 1 max 65536
option name USI_Ponder type check default true
option name Write_Synthesized_Eval type check default false
usiok

というわけで無事動かせた。
これで世界レベルの将棋ソフトが動かせる!!!

参考