r - 没有内联/创建本地包的 Rcpp 并行化
问题描述
我正在创建一个包,希望最终能放到 CRAN 上。C++
我已经在的帮助下编写了大部分包,Rcpp
现在希望启用此C++
代码的并行化。我正在使用该软件包,但是,如果这会更好foreach
,我愿意切换到其他库或其他库。snow
我首先尝试并行化一个简单的函数:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
arma::vec rNorm_c(int length) {
return arma::vec(length, arma::fill::randn);
}
/*** R
n_workers <- parallel::detectCores(logical = F)
cl <- parallel::makeCluster(n_workers)
doParallel::registerDoParallel(cl)
n <- 10
library(foreach)
foreach(j = rep(n, n),
.noexport = c("rNorm_c"),
packages = "Rcpp") %dopar% {rNorm_c(j)}
*/
我添加了.noexport
因为没有,我得到了错误Error in { : task 1 failed - "NULL value passed as symbol address"
。这使我看到了这篇建议这样做的 SO 帖子。
但是,我现在收到错误Error in { : task 1 failed - "could not find function "rNorm_c""
消息,大概是因为我没有按照最佳答案说明在每个节点上分别加载函数。我不确定如何做到这一点。
这个 SO 帖子演示了如何通过编写C++
内联代码来做到这一点,但是,由于C++
我的包的代码是多个函数,这可能不是最好的解决方案。这篇 SO 帖子建议为工作人员创建一个本地包以加载和调用,但是,由于我希望在 CRAN 包中提供此代码,除非我想要,否则似乎无法使用本地包尝试发布两个 CRAN 包。
任何有关如何处理此问题的建议或对 Rcpp 代码并行化资源的参考将不胜感激。
编辑:
我使用上述函数创建了一个名为rnormParallelization
. 在这个包中,我还包含了几个 R 函数,其中一个利用包来并行化使用该函数snow
的 for 循环:rNorm_c
rNorm_samples_for <- function(num_samples, length){
sample_mat <- matrix(NA, length, num_samples)
for (j in 1:num_samples){
sample_mat[ , j] <- rNorm_c(length)
}
return(sample_mat)
}
rNorm_samples_snow1 <- function(num_samples, length){
clus <- snow::makeCluster(3)
snow::clusterExport(clus, "rNorm_c")
out <- snow::parSapply(clus, rep(length, num_samples), rNorm_c)
snow::stopCluster(clus)
return(out)
}
这两个功能都按预期工作:
> rNorm_samples_for(2, 3)
[,1] [,2]
[1,] -0.82040308 -0.3284849
[2,] -0.05169948 1.7402912
[3,] 0.32073516 0.5439799
> rNorm_samples_snow1(2, 3)
[,1] [,2]
[1,] -0.07483493 1.3028315
[2,] 1.28361663 -0.4360829
[3,] 1.09040771 -0.6469646
但是,并行版本的工作速度要慢得多:
> microbenchmark::microbenchmark(
+ rnormParallelization::rNorm_samples_for(1e3, 1e4),
+ rnormParallelization::rNorm_samples_snow1(1e3, 1e4)
+ )
Unit: milliseconds
expr min lq
rnormParallelization::rNorm_samples_for(1000, 10000) 217.0871 249.3977
rnormParallelization::rNorm_samples_snow1(1000, 10000) 1242.8315 1397.7643
mean median uq max neval
320.5456 285.9787 325.3447 802.7488 100
1527.0406 1482.5867 1563.0916 3411.5774 100
这是我的会话信息:
> sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] rnormParallelization_1.0
loaded via a namespace (and not attached):
[1] microbenchmark_1.4-7 compiler_4.1.1 snow_0.4-4
[4] parallel_4.1.1 tools_4.1.1 Rcpp_1.0.7
解决方案
推荐阅读
- forms - SqPaymentForm 不安全
- sql - 使用 Blob 存储作为数据源对 SQL On-Demand 中的数据进行分区
- sql - Google Bigquery - 创建活动记录数的时间序列
- assembly - 分析 AVX2 中的比较结果
- sql-server - Docker (Linux) 和 Windows 主机中的 SQL Server 的 MSDTC 配置问题
- sql - 如何使用联接编写此代码,Oracle
- python - Python评估csv文件中的重复元素
- r - 增强后向消除变量选择中的 R 代码
- javascript - 为什么我们应该更喜欢使用 createReadStream 而不是 readFile 在 nodejs 中服务器静态文件?
- python - 迭代创建新列表