Rcpp・inlineパッケージを使ってC++とRを連携させる
「R単体だと遅いので計算のボトルネックはC++で書くようにすればいいんじゃないか、せっかくそのためのRcppなる便利パッケージもあるし」とずっと思っていたものの毎回インストール方法を調べることすら億劫がってやっていなかったのですが、前回の記事に書いたバイブル本にその辺りも書いてあったので、ここで一発奮起してやってみることにした。
まずは導入編ということでRcpp・inlineを使うための環境のインストールから。手元のOS等の環境は
- windows 7(32bit)
- R-2-14-1が既にデフォルトのインストール先(C:\Program Files\R\R-2.14.1)にインストール済み
とりあえずC++コンパイラ等を勝手に入れてくれるツール・Rtools.exeが必要なので最寄りのミラーである筑波のミラーサイトから自分のインストールしているRのバージョンに合わせたものをダウンロード*1&既定のフォルダにインストール、YES連打で無事に入る。
私と同じようにRをデフォルトのインストール先に入れた状態だとこの先の作業で
以下にエラー compileCode(f, code, language = language, verbose = verbose) : Compilation ERROR, function(s)/method(s) not created! cygwin warning: MS-DOS style path detected: C:/PROGRA~1/R/R-214~1.1/etc/i386/Makeconf Preferred POSIX equivalent is: /cygdrive/c/PROGRA~1/R/R-214~1.1/etc/i386/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 g++.exe: C:/Program: No such file or directory g++.exe: Files/R/R-2.14.1/library/Rcpp/lib/i386/libRcpp.a: No such file or directory
なるエラーにぶつかることになるのですが、「あぁこれは、Rのインストールフォルダにスペース文字があるのがよくないっぽいんだろうな」と思ってCompilation ERROR, function(s)/method(s) not created! cygwin warning:MS-DOS style path detected: C:/PROGRA~1/R/R-214~1.1/etc/i386/MakeconfPreferred POSIX equivalent is: /cygdrive/c/PROGRA~1/R/R-214~1.1/etc/i386/MakeconfCYGWIN 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-pathnamesg++.exe: C:/Program: No such file or directory - Google 検索ググったら皆さんやはり引っかかっていた。しょうがないので既存のRをアンインストールしてC直下にRフォルダを作って「C:\R\R-2.14.1\」フォルダに再インストール。
〜追記〜
どうやらR本体というよりもパッケージのインストールフォルダの問題らしい。
@teramonagi 拝読させて頂きました.勉強になりました.最初のエラーはRのインスコ先ではなく,ライブラリのインスコ先にスペースがあるからです.ユーザー用のライブラリインスコ先を別に用意すれば通ると思います.私も注意しますです...
2012-02-01 23:14:13 via web to @teramonagi
情報ありがとうございます!
それから以下のディレクトリにパスを通しておく。これをやっておかないとコンパイルがうまく走らない。RtoolsやRのインストール先が違うなら以下のパスもちょっと違うので注意。特にMinGWは64bit版も同梱されているので64bitOSの方はそっちのほうがいいかも?
- C:\Rtools\bin
- C:\Rtools\MinGW\bin
- C:\R\R-2.14.1\bin
次にRを起動して以下のパッケージをインストール
install.packages("Rcpp") install.packages("inline")
これで動く状態まで持っていけたので、適当なサンプルコードを動かしてみる。
library(Rcpp) library(inline) src <- ' Rcpp::NumericVector xa(a); Rcpp::NumericVector xb(b); int n_xa = xa.size(), n_xb = xb.size(); Rcpp::NumericVector xab(n_xa + n_xb - 1); for (int i = 0; i < n_xa; i++){ for (int j = 0; j < n_xb; j++){ xab[i + j] += xa[i] * xb[j]; } } return xab; ' fun <- cxxfunction(signature(a = "numeric", b = "numeric"), src, plugin = "Rcpp")
これは
”R上にRcppパッケージを使ったC++のコードを文字列として書いておいて、それをinlineパッケージのcxxfunction関数に食わせることによってそのままDLLとしてコンパイル、更に自動でR上へロードしてそれをfun関数として割り当てる”までやってもらってるってことに該当する。すごい!!!
そして実行すると、なんか警告は出てるけど
> fun <- cxxfunction(signature(a = "numeric", b = "numeric"), src, plugin = "Rcpp") cygwin warning: MS-DOS style path detected: C:/R/R-214~1.1/etc/i386/Makeconf Preferred POSIX equivalent is: /cygdrive/c/R/R-214~1.1/etc/i386/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 > fun(1:3, 1:4) [1] 1 4 10 16 17 12
と所望の結果となる。ここで出てきた警告を消すためには警告メッセージ本文中に
「CYGWIN environment variable option "nodosfilewarning" turns off this warning.」
とあるように環境変数CYGWINに”nodosfilewarning”という値を設定すればOKだった。
ここまでできれば後は以下のDirk氏の資料
- Rcpp: Seamless R and C++ Integration
- Frequently Asked Questions about Rcpp
- Writing a package that uses Rcpp
を読んでおけばいいのかと。さらにちょっと調べたら上の資料も含めてvignetteとして大量に資料が配布されているのがわかった。以下がそのリストでR上で実行すると当該資料がPDFビューアーで起動します。「Rを使いつつもちょこっとC++で書こうかな?」くらいのライトユーザーならvignette("Rcpp-quickref")のクイックリファレンスを見るのが良さげです。
vignette("Rcpp-FAQ") vignette("Rcpp-extending") vignette("Rcpp-introduction") vignette("Rcpp-modules") vignette("Rcpp-package") vignette("Rcpp-quickref") vignette("Rcpp-sugar")
*1:私はRtools214.exeを落とした