2017-09-02 11 views
0

私はそれを並列化する前にRcppコードを書きました。コードをopenmpと並列化しました。これは私のcppcodeです:なぜRcpp openmp parallizedコードが与えられるのか:セグメンテーションフォールト(コアダンプ)

#include <Rcpp.h> 
#include <omp.h> 

using namespace Rcpp; 
// [[Rcpp::export]] 
float fsvalue(NumericMatrix X1, NumericMatrix X2,int n_cpu=2) { 
    int p = X1.ncol(); 
    if (p !=X2.ncol()) 
    stop ("Number of Dimentions should be equal"); 
    int n1 = X1.nrow(); 
    int n2 = X2.nrow(); 
    float gamma = (float) n1/ (float) n2; 
    int step = 0; int max=p*n1*(n1-1)*n2*(n2-1); 
    int sums = 0; 
    float FS_Sum = 0; 
    omp_set_dynamic(0);   // Explicitly disable dynamic teams 
    omp_set_num_threads(n_cpu); // Use n_cpu threads for all 
    /* 
    * 
    */ 
    #pragma omp parallel 
    { 
    float sum_thread = 0; 
    #pragma omp for 
    for (int k=0; k<p;k++){ 
     for (int i=0; i<n1;i++){ 
     for (int j=0;j<n1;j++){ 
      for (int s=0;s<n2;s++){ 
      for (int t=0;t<n2;t++){ 
       if (i==j || s==t) 
       continue; 
       step++; 
       sum_thread += ((X1[i*p + k] - X2[s*p + k])*(X1[j*p + k]) - X2[t*p + k])/(gamma); 
      } 
      } 
     } 
     } 
    } 
    #pragma omp critical 
    { 
     FS_Sum += sum_thread; 
    } 
    } 
    return (FS_Sum/(n1*(n1-1)*n2*(n2-1))); 
    //return (X1[3*10 + 1]); 
} 

と私のRコード内:

library("Rcpp") 
#generate two matrixes for test 
source("MovingAverage_data.r") 
Sys.setenv("PKG_CXXFLAGS"="-fopenmp") 
sourceCpp("teststat.cpp") 
fsvalue(fsdata1,fsdata2) 

その後、いくつかの時間が私のコードは、結果を与え、いつかこのエラーを与える:

Segmentation fault (core dumped) 

私は絶対にnewbiていますopenmpに変更し、hereを学習しました。何が原因なの? 助けていただければ幸いです。

編集 私はこのエラーを取得する、のSessionInfo(の出力)があまりにもエラーです:

> sessionInfo() 
Error in eval(formal.args[[deparse(substitute(arg))]]) : there is no .Internal function '�l�' 

が、私は出力に含まを得ることができたときに、のSessionInfoの出力は次のとおりです。

> sessionInfo() 
R version 3.2.3 (2015-12-10) 
Platform: x86_64-pc-linux-gnu (64-bit) 
Running under: Ubuntu 16.04.3 LTS 

locale: 
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C   LC_TIME=fa_IR   
[4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=fa_IR  LC_MESSAGES=en_US.UTF-8 
[7] LC_PAPER=fa_IR   LC_NAME=C    LC_ADDRESS=C   
[10] LC_TELEPHONE=C   LC_MEASUREMENT=fa_IR LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] Rcpp_0.12.12 

loaded via a namespace (and not attached): 
[1] tools_3.2.3 

そして、私はこの関数でデータを生成します:

# @getdata function 
# @params i, p, i \in \{1,2\} and k in \{i,\ldots,p\} 
# @return X_{ijk} vector - X{ijk} has n_i length 
get_data_of_dim_k <- function(i,n_i,k,p,lambda=10,scenario=1,randomize=TRUE,seed=342373){ 
    if (k>p){ 
     stop("your dimention (k) should not be greater than maximum number of dimentions (p)"); 
    } 
    l_i = c(3,4) 
    rho_generator <- function(){ 
     #rho11 rho12 rho13 - rho21 rho22 rho23 rho24 
     rho = c(); 
     set.seed(seed) 
     for (i in c(1:8)){ 
      rho[i]= runif(1,2,3) 
     } 
     rho = matrix(rho,nrow=2); 
     rho[1,4] = 0 
     if (randomize){ 
      set.seed(as.numeric(format(Sys.time(), "%OS3"))) 
     } 
     return (rho) 
    } 
    mu_generator = function(p,lambda=10,Seed){ 
     set.seed(Seed) 
     mu = runif(p,0,lambda) 
     set.seed(as.numeric(format(Sys.time(), "%OS3"))) 
     return(mu) 
    } 
    mu_ij = mu_generator(p,Seed = seed) 
    rho = rho_generator() 

    #Check this on windows and macintash 
    set.seed(as.numeric(format(Sys.time(), "%OS3"))) 
    #innov = runif(100, -0.5, 0.5) -------> http://stackoverflow.com/questions/39925470/simulate-an-ar1-process-with-uniform-innovations 
    rho = rho_generator() 
    #TODO add \mu_{ij} 
    switch(scenario, 
     "1" = { 
      X_ij = arima.sim(list(ma=rho[i,c(1,l_i[i])]),n=n_i)+mu_ij[k] 
     }, 
     "2" = { 
      if (k<=(p/2)){ 
       X_ij = arima.sim(list(ma=rho[i,c(1,l_i[i])]),n=n_i)+mu_ij[k] 
      }else{ 
       X_ij = arima.sim(list(ma=rho[i,c(1,l_i[i])]),n=n_i,innov = rgamma(n_i,1,rate=4))+mu_ij[k]   
      } 
     } 
    ) 
    return (as.vector(X_ij)) 
} 
#get_data_of_dim_k(1,35,1,25) 
get_data = function(i,n_i,p){ 
    data = matrix(get_data_of_dim_k(i,n_i,1,p),ncol=1) 
    for (j in c(2:p)){ 
     data = cbind(data,get_data_of_dim_k(i,n_i,j,p)) 
    } 
    return(data) 
} 
    # @var fsdata1 just for test 
fsdata1 = get_data(i = 1,n_i = 8,p = 10) 

# @var fsdata2 just for test 
fsdata2 = get_data(i= 2, n_i=8,p = 10) 
+0

あなたは私たちがはっきり*一部を逃した*あなたがマルチスレッドコードからRデータにアクセスすることはできません文書。ドキュメントとサンプルをもう一度読んで、並列コードで 'RMatrix'クラスを使用してください。 –

+0

問題を再現できません。あなたは@DirkEddelbuettelからループ内で 'RcppParallel :: RMatrix'を使うよう提案しましたか? –

答えて

2

ここでセグメンテーションフォールトで役立つはずRMatrix使用の可能性:

// [[Rcpp::depends(RcppParallel)]] 
#include <RcppParallel.h> 
#include <Rcpp.h> 
#include <omp.h> 

using namespace Rcpp; 
// [[Rcpp::export]] 
float fsvalue(NumericMatrix x1, NumericMatrix x2,int n_cpu=2) { 
    RcppParallel::RMatrix<double> X1(x1); 
    RcppParallel::RMatrix<double> X2(x2); 
    ... [your code as above] ... 
+0

ありがとうございました!その通り!私はそれをテストし、それは働いています。しかし、別の関数の引数型としてRMatrixを使用することはできません。ポインタ型の 'SEXPREC *'(多分、おそらく)のメンバー 'begin' in '(SEXPREC *&)(&source)あなたは ' - >'を使うつもりだったのですか?) '。あなたはそれについてアドバイスをしていますか? – SirSaleh

+0

これ以上の文脈ではありません。これは新しい質問をするのが一番良いでしょう。 –

+0

そうです。ありがとうラルフ。 – SirSaleh

関連する問題