古い質問ですが、上位のRcppタグを調べているときに偶然見つけたので、この回答はまだ役立つかもしれません。
あなたが書いたコードが完全にバグを取り除き、あなたが望むことをするとき、Dirkの答えは適切だと思いますが、例のような小さなコードのような新しいパッケージを書くのは面倒かもしれません。代わりにできることは、コードブロックをエクスポートし、ソースコードをコンパイルしてヘルパーを実行する「ヘルパー」関数をエクスポートすることです。これにより、CXX関数が使用可能になり、別のヘルパー関数を使用して呼び出すことができます。例えば:
# Snow must still be installed, but this functionality is now in "parallel" which ships with base r.
library(parallel)
# Keep your source as an object
src1 <- '
Rcpp::NumericMatrix xbem(xbe);
int nrows = xbem.nrow();
Rcpp::NumericVector gv(g);
for (int i = 1; i < nrows; i++) {
xbem(i,_) = xbem(i-1,_) * gv[0] + xbem(i,_);
}
return xbem;
'
# Save the signature
sig <- signature(xbe = "numeric", g="numeric")
# make a function that compiles the source, then assigns the compiled function
# to the global environment
c.inline <- function(name, sig, src){
library(Rcpp)
funCXX <- inline::cxxfunction(sig = sig, body = src, plugin="Rcpp")
assign(name, funCXX, envir=.GlobalEnv)
}
# and the function which retrieves and calls this newly-compiled function
c.namecall <- function(name,...){
funCXX <- get(name)
funCXX(...)
}
# Keep your example matrix
A <- matrix(rnorm(400), 20,20)
# What are we calling the compiled funciton?
fxname <- "TestCXX"
## Parallel
cl <- makeCluster(2, type = "PSOCK")
# Export all the pieces
clusterExport(cl, c("src1","c.inline","A","fxname"))
# Call the compiler function
clusterCall(cl, c.inline, name=fxname, sig=sig, src=src1)
# Notice how the function now named "TestCXX" is available in the environment
# of every node?
clusterCall(cl, ls, envir=.GlobalEnv)
# Call the function through our wrapper
clusterCall(cl, c.namecall, name=fxname, A, 0.5)
# Works with my testing
PSOCKとMPIの両方を使用して、クラスターコンピューティング用の並列パッケージとRhpcパッケージにある多くの機能をまとめたパッケージctools(恥知らずな自己宣伝)を作成しました。上記とほぼ同じ方法で、すべてのノードで「Rcpp::sourceCpp」を呼び出す「c.sourceCpp」という関数がすでにあります。上記を実行する「c.inlineCpp」を追加して、その有用性を確認します。
編集:
Coatlessのコメントに照らしてRcpp::cppFunction()
、実際には、ヘルパーはまだ必要ですがc.inline
、ここではヘルパーの必要性を否定しています。c.namecall
src2 <- '
NumericMatrix TestCpp(NumericMatrix xbe, int g){
NumericMatrix xbem(xbe);
int nrows = xbem.nrow();
NumericVector gv(g);
for (int i = 1; i < nrows; i++) {
xbem(i,_) = xbem(i-1,_) * gv[0] + xbem(i,_);
}
return xbem;
}
'
clusterCall(cl, Rcpp::cppFunction, code=src2, env=.GlobalEnv)
# Call the function through our wrapper
clusterCall(cl, c.namecall, name="TestCpp", A, 0.5)