機械学習周りのプログラミング中心。 イベント情報
ポケモンバトルAI本電子書籍通販中

やねうら王をSPMパッケージにする【やねうら王・ふかうら王iOS移植】

やねうら王・ふかうら王をiOSで動くようにする移植に成功したのでポイントを解説します。ただしMacの将棋所と連携しないと動かない研究用のものとなります。 動機およびC++ファイル1個の簡単な将棋エンジンshogi686microを移植した前回の記事はこちら。

select766.hatenablog.com

shogi686microの時はSwiftのプロジェクトにC++のソースファイルを直接追加して、Xcodeのデフォルト設定でのビルドで問題ありませんでした。C++コンパイルオプションには無頓着で動きましたし、ソースが短いので手直しも容易でした。やねうら王は探索アルゴリズムの指定やSIMD命令のためのコンパイラオプションが必要かつ、ソース規模が大きいため手直しは最小限にしたいです。

Xcodeのプロジェクトに直接やねうら王のソースツリーを投入するのは、コンパイラオプションの設定などがわかりづらく、また本家の変更への追従が難しいと考えました。そのため、GUIを含むアプリとは分離して、Swift Package Manager (SPM)形式のパッケージとしてやねうら王をビルドし、それをアプリから参照する形式で実装することにしました。C++のソースツリーがあるときに、それをSPMパッケージとしてビルドする方法は以下のサイトが参考になりました。

zenn.dev

作成したコードへのリンクはこちら。

やねうら王固有のポイント

上記の記事ではカバーされない、やねうら王をビルドする際に注意が必要だったポイントについて説明します。

C++コンパイラのオプション

CMakeLists.txtで指定します。

target_compile_options(yaneuraou PUBLIC -fno-exceptions -fno-rtti -Wextra -MMD -MP...

というような行がそれに相当します。

本家のビルドで与えられるコンパイルオプションは、makeを実際に走らせてみて確認しました。

make -C source COMPILER=g++ YANEURAOU_EDITION=YANEURAOU_ENGINE_DEEP_COREML TARGET_CPU=APPLEAVX2

アプリ側のビルド設定で、 libc++.tbd が必要

これがないと、ビルド時にC++標準ライブラリの関数が"undefined symbol"となり失敗します。

Swift側から呼びたい関数はextern "C"が必要

名前マングリングを無効にする必要があります。

main関数を入れてはいけない

main関数を含むC++コードをビルドに入れてしまうと、ビルドは成功するもののアプリが強制終了します。やねうら王の全ソースファイルをビルド対象とするのではなく、必要なものを選別し、またiOS固有の事情に対応するためのソースファイルを追加する必要があります。yaneuraou_ios_mainという別の関数を作り、これをSwift側から呼ぶと思考エンジンのスレッドが立ち上がる仕組みにしました。

標準入出力が使えない

やねうら王は、別プロセスとして動いているGUIに対して指し手の送受信を標準入出力で行います。iOSでも標準入出力自体は存在していますが、そこにデータを与える手段がありません。次回の記事で解説します。

やねうら王(水匠5評価関数埋め込み)のビルド

NNUE型評価関数を用いる場合のビルドについてです。iOSではPCとは異なる形でファイルが管理されるため、評価関数を独立したファイルとして持つとそのパスを探すのが少々面倒です。WebAssembly向けのビルドスクリプトで、 ソースコード上の定数として評価関数パラメータを埋め込む方法があったので、この方法で水匠5評価関数を埋め込んだビルドができました。ただしビルド結果のファイルが100MBを超えてしまったのでGithubには上げられませんでした。代わりによりファイルサイズが小さい"SuishoPetite"評価関数を埋め込んだものを上げてあります(動くことは確認できましたが、この評価関数の内容がどこかに書いてあれば教えてもらえると助かります)。

https://github.com/yaneurao/YaneuraOu/blob/master/script/wasm_build.js

ふかうら王のビルド

深層学習モデルをNeural Engine(機械学習専用チップ)で動作させる必要があり、そのAPIがSwiftまたはObjective-C言語からしか使えません。そのためやねうら王より少々手間が増えます。C++Objective-Cを混在できるObjective-C++コードでインターフェースを記述します。原則はMac版と同じです。ただし、Mac版ではmlmodelファイルを実行時にmlmodelcファイルにコンパイルしていましたが、iOS版ではアプリ側にバンドルし、アプリのビルド時にXcodeが自動的にコンパイルしたものを用いる形になります。

select766.hatenablog.com

以上の取り組みにより、やねうら王・ふかうら王がiPad上で動くことを確認できました。