最近こんな素晴らしい勉強会があったと知りまして。主催は7月の1ヶ月間で何故か3回も一緒に飲んだこの人。
元々WinBUGSは{R2WinBUGS}経由で使っていたんですが、やっぱり{Rcpp}経由でC++コンパイラで高速で走るStan良さそうだなーということで{RStan}を入れてみようと思ったのでした。
・・・ところが。RStan Getting Startedに書いてある手順を何度やっても色々エラーが出まくって動かないというorz 仕方ないのでTwitterでオッサン大仏様やら冒頭記事のブログ主に聞くなりして、ようやく解決して{Rcpp}も{RStan}も動くようになったのでした。
ということで、その一部始終を簡単にまとめておきます。まだるっこしい説明が嫌だという人は、全てすっ飛ばして一番後ろの「結論」だけ読めばOKです。
前提
最初に僕の環境をまとめておきます。
- OS: Windows 7 Professional 64bit
- R: R 3.0.2
- RStudio: RStudio for Windows 0.97.551
- Python: Python(x,y) 2.7.5.0
Windows環境なのは歴史的経緯(笑)によります。なお、今回Rtools + {Rcpp}を入れようとしているのはあくまでも{RStan}を入れるための前段階です。
Rtoolsを入れる
RtoolsはWindows環境でR本体をソースからビルドするためのツールパッケージです。なので、Rから読み込むのではなく、インストーラをDLしてきて入れる必要があります。これは普通に今使っているRのバージョンに対応したものをただ入れれば問題ないはずです。最新版であればgcc-4.6.3が入っています。
インストール手順は{RStan}のサイトのInstall Rtools on Windowsに書いてあるので、本当にただこの通りにやれば良い!はずなんですが。。。
Rcppが動くかどうか試してみたら!
一応入ったので、Install Rtools on Windowsに書かれているようにまずはWindows側のPATH設定に以下の通り追記します。
c:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;C:\Windows\system32;
さらに、gccのステータスをR側からチェックしてみます。
> system('g++ -v') Using built-in specs. COLLECT_GCC=C:\MINGW3~1\bin\G__~1.EXE COLLECT_LTO_WRAPPER=c:/mingw3~1/bin/../libexec/gcc/mingw32/4.5.2/lto-wrapper.exe Target: mingw32 Configured with: ../gcc-4.5.2/configure --enable-languages=c,c++,ada,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-werror --build=mingw32 --prefix=/mingw Thread model: win32 gcc version 4.5.2 (GCC)
あれ、gcc-4.5.2が入ってることになってる。それでもまぁいいや、gccが認識されていることだし、と思ってRStan Getting Startedにならって動作確認をしてみると。。。
> # using library inline to compile a C++ code on the fly > library(inline) > library(Rcpp) 次のパッケージを付け加えます: ‘Rcpp’ 以下のオブジェクトはマスクされています (from ‘package:inline’) : registerPlugin > src <- ' + std::vector<std::string> s; + s.push_back("hello"); + s.push_back("world"); + return Rcpp::wrap(s); + ' > hellofun <- cxxfunction(body = src, includes = '', plugin = 'Rcpp', verbose = FALSE) C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:196: warning: overriding recipe for target `.m.o' C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:189: warning: ignoring old recipe for target `.m.o' filea072b4c44.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in make: *** [filea072b4c44.o] Error 1 ERROR(s) during compilation: source code errors or compiler configuration errors! Program source: 1: 2: // includes from the plugin 3: 4: #include <Rcpp.h> 5: 6: 7: #ifndef BEGIN_RCPP 8: #define BEGIN_RCPP 9: #endif 10: 11: #ifndef END_RCPP 12: #define END_RCPP 13: #endif 14: 15: using namespace Rcpp; 16: 17: 18: // user includes 19: 20: 21: // declarations 22: extern "C" { 23: SEXP filea072b4c44( ) ; 24: } 25: 26: // definition 27: 28: SEXP filea072b4c44( ){ 29: BEGIN_RCPP 30: 31: std::vector<std::string> s; 32: s.push_back("hello"); 33: s.push_back("world"); 34: return Rcpp::wrap(s); 35: 36: END_RCPP 37: } 38: 39: Error in compileCode(f, code, language = language, verbose = verbose) : Compilation ERROR, function(s)/method(s) not created! C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:196: warning: overriding recipe for target `.m.o' C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf:189: warning: ignoring old recipe for target `.m.o' filea072b4c44.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in make: *** [filea072b4c44.o] Error 1 In addition: Warning message: running command 'C:/PROGRA~1/R/R-30~1.2/bin/x64/R CMD SHLIB filea072b4c44.cpp 2> filea072b4c44.cpp.err.txt' had status 1 > cat(hellofun(), '\n') Error in cat(hellofun(), "\n") : could not find function "hellofun"
全力でコケてますorz 明らかにコンパイラが認識されてません。
悪さをしているのはどいつだ?
コンパイラが認識されていないということで、思い当たるのは既に書いたように「gcc-4.6.3 (Rtools)を入れてるはずなのにR側ではgcc-4.5.2しか認識されていない」という点。そこで、Windows内のどこにあるか探してみます。すると。。。ありました。
C:\MinGW32-xy\lib\gcc\mingw32\4.5.2
こいつか!このPython(x,y)で一緒に入ってくるやつ!!こいつがgcc-4.5.2の正体だったのかぁぁぁっっっ!!! ということで、こいつをWindows側のPATHから削除します。その上で、R + RStuidioを再起動してからもう一度gccのバージョンをチェックすると。。。
> system('g++ -v') Using built-in specs. COLLECT_GCC=c:\Rtools\GCC-46~1.3\bin\G__~1.EXE COLLECT_LTO_WRAPPER=c:/rtools/gcc-46~1.3/bin/../libexec/gcc/i686-w64-mingw32/4.6.3/lto-wrapper.exe Target: i686-w64-mingw32 Configured with: /data/gannet/ripley/Sources/mingw-test3/src/gcc/configure --host=i686-w64-mingw32 --build=x86_64-linux-gnu --target=i686-w64-mingw32 --with-sysroot=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/mingw32 --prefix=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/mingw32 --with-gmp=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --with-mpfr=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --with-mpc=/data/gannet/ripley/Sources/mingw-test3/mingw32mingw32/prereq_install --disable-shared --enable-static --enable-targets=all --enable-languages=c,c++,fortran --enable-libgomp --enable-sjlj-exceptions --enable-fully-dynamic-string --disable-nls --disable-werror --enable-checking=release --disable-win32-registry --disable-rpath --disable-werror CFLAGS='-O2 -mtune=core2 -fomit-frame-pointer' LDFLAGS= Thread model: win32 gcc version 4.6.3 20111208 (prerelease) (GCC)
ちゃんとgcc-4.6.3が認識されました!後はダメ押しでhello worldのコードを回してみると。。。
> # using library inline to compile a C++ code on the fly > library(inline) > library(Rcpp) 次のパッケージを付け加えます: ‘Rcpp’ 以下のオブジェクトはマスクされています (from ‘package:inline’) : registerPlugin > src <- ' + std::vector<std::string> s; + s.push_back("hello"); + s.push_back("world"); + return Rcpp::wrap(s); + ' > hellofun <- cxxfunction(body = src, includes = '', plugin = 'Rcpp', verbose = FALSE) cygwin warning: MS-DOS style path detected: C:/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf Preferred POSIX equivalent is: /cygdrive/c/PROGRA~1/R/R-30~1.2/etc/x64/Makeconf CYGWIN environment variable option "nodosfilewarning" turns off this warning. Consult the user's guide for more details about POSIX paths: http://cygwin.com/cygwin-ug-net/using.html#using-pathnames > cat(hellofun(), '\n') hello world
無事動きました。。。もちろんこの後{RStan}もインストールして、ちゃんと動きました。よかったよかった。
結論:システム内に既に入っているgccに注意!
要は、WindowsのPATH編集ダイアログを開いて、システム内既存のgccへのパスである(この場合はMinGW)
C:\MinGW32-xy\bin
を手動で削除し、代わりにRStan Getting StartedのInstall Rtools on Windowsでも指定されている
C:\Rtools\bin;c:\Rtools\gcc-4.6.3\bin;C:\Windows\system32;
を追記して、OKして保存したらR + RStudioを再起動すれば、ちゃんとgcc-4.6.3へのパスが通って{Rcpp}が動くようになります。恒久的にこのままにしておくとPython側で不具合を起こす可能性はゼロではありませんが、Python側でMinGWが必要なことをやらない限りはこのままでも問題ないと思います。
ということで、RとPython(x,y)を共存させているWindows環境だったり、MinGWやその他gccを入れていて、どーしても{Rcpp}が走らない!という人はこの辺チェックしてみると良いでしょう。お粗末様でした。