我打算用从一系列步骤中得出的值来填充一个稀疏矩阵,以使其更加高效,使用OpenMP来加速这些进程,我发现它在使用1个线程时可以正常工作,但是在多线程中捕获了segfault -threads,我准备了一个简单的演示代码来重现该错误,衷心希望有人能帮我一个忙。
#include <RcppArmadillo.h>
#include <omp.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(bigmemory, BH)]]
using namespace std;
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
arma::sp_mat test(arma::vec x, int n, int threads = 1){
omp_set_num_threads(threads);
arma::sp_mat m(n, n);
#pragma omp parallel for schedule(dynamic)
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
m(i, j) = x[i * n + j];
}
}
return m;
}
# run
a<-test(sample(c(0,1,2),100*100,rep=T), n=100, threads=1)
a<-test(sample(c(0,1,2),100*100,rep=T), n=100, threads=10)
答案 0 :(得分:3)
tl; dr:您不能。
更长的故事:(Rcpp)Armadillo的主要优点之一是在底层操作之上的非常好且一致的API,介于混乱和难以使用之间。缺点之一是我们很容易看不到底层数据结构。
密集矩阵(基本上总是)是固定的内存块。本质上,大小为行x列的向量。这就是让我们在R和(Rcpp)Armadillo之间进行有效的“零复制”传输的原因。它还允许我们在不重叠的块上并发工作。这很重要,例如 RcppParallel可以充分利用它。 OpenMP在这里工作。
稀疏矩阵是(并且我在这里简化)相互依赖的动态列表/向量类型。因此并发工作根本行不通。伤心。但这就是事实。一旦您更仔细地研究稀疏矩阵的通用数据结构,就会变得很清楚(例如例如 R的Matrix包)。例如this wikipedia piece是一个相当不错且详尽的介绍。