Win10のAnaconda環境にpyopenclをmingwビルドで入れた話

pyopenclをpip installしようとしたら、cl.exeを要求されてC++ Build Tools入れるのが面倒なので軽く絶望したけど、なんやかんやでMinGWでのビルドに成功したのでメモ。

環境

  • Windows10 pro 64bit
  • Anaconda3 5.1.0
  • pip 9.0.1
  • pyopencl 2018.1.1
  • MinGW w64 7.3.0

前準備

  • g++にパスを通しておく
  • OpenCLのヘッダをインクルードパスを通しておく(set CPLUS_INCLUDE_PATHしておく)
  • pip install makoMakoを入れておく

pipのエラー回避

こちら*1で解説されている現象が発生したので、記載されている通りの対処を実施

コンパイラの切り替え

Anaconda3\Lib\distutils\distutils.cfg ファイルを新規作成する。

[build]
compiler = mingw32

これでcl.exeからg++に切り替わる。

pyopenclのパッケージファイルを入手する

手っ取り早いのは一度pip install pyopenclで失敗させておいて「Using cached〜」と表示されている箇所を見てファイルのURLを確認してブラウザなどでダウンロードする。

以降はダウンロードしたファイルを解凍してpyopencl-2018.1.1フォルダにカレントディレクトリを移して作業する。

MinGWのヘッダ改変

mingw\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c++\cmathの「using ::hypot;」をコメントアウトする。pyopenclのインストールが終わったら元に戻しておく。
少しググった感じだとpythonのヘッダとC++ヘッダのinclude順で発生する問題?っぽいけど、該当箇所がビルド時に生成されるソースのようで編集が難しそうなのでMinGW側のヘッダ改変で対処する。

pyopenclの独自スレッドライブラリを無効化する

pyopencl-2018.1.1\src\c_wrapper\mingw-std-threadsに入っている3つのヘッダファイルを無効化する。ヘッダファイルの中身を#if 0でくくるなり、全削除するなりで無効化する。
(なぜかSTLのスレッド系ライブラリが独自定義されていてMinGWSTLライブラリと衝突してしまうため)

コンパイル

いったんコンパイルする。リンクでこける。

pyopencl-2018.1.1>python setup.py build

コンソールにリンクで実行されるコマンドとオプションが表示されているのでコピーする。

リンク

先ほどコピーしたリンクのコマンドを改変する。

  • 「-lmsvcr140」を削除する
  • OpenCLのライブラリ(.a)ファイルがある場合はライブラリパスの設定を追加する
  • OpenCLのライブラリがない場合は「-lOpenCL」を削除して代わりに「C:\Windows\system32\OpenCL.dll」を入れる

改変後のコマンドを実行してpydを生成する。

インストール

リンクが正常にできていれば以下のコマンドでインストールできる。

pyopencl-2018.1.1>python setup.py install

余談

  • OpenCLのヘッダファイルはKhronos OpenCL Registryで公開されているものでOK
  • AMDビデオカードならビデオドライバをインストールしていればOpenCL.DLLが入っている(はず)
  • つまりAMD APP SDKがなくてもOK(いつの間にか行方不明に。今どこで公開されているの?)