ОШИБКА: неопределенная ссылка на `sdot_ 'при использовании arma :: dot - PullRequest
0 голосов
/ 03 апреля 2020

Я использую R cpp :: source Cpp ("test. cpp") и выводит следующую информацию об ошибке. Обратите внимание, что check1 () работает, а check2 не работает. Разница между «arma :: ve c» и «arma :: fve c». Ошибка происходит, когда я пробовал на Windows. Когда я попробовал его на linux, он работает.

(РЕДАКТИРОВАТЬ: я добавил свою среду R на Linux. PS: Результаты на Linux показывают, что float быстрее, чем double, поэтому Я предпочитаю использовать float)

C:/RBuildTools/3.5/mingw_64/bin/g++  -std=gnu++11 -I"C:/PROGRA~1/R/R-36~1.1/include" -DNDEBUG -I../inst/include -fopenmp  -I"C:/Users/wenji/OneDrive/Documents/R/win-library/3.6/Rcpp/include" -I"C:/Users/wenji/OneDrive/Documents/R/win-library/3.6/RcppArmadillo/include" -I"Y:/"        -O2 -Wall  -mtune=generic -c check.cpp -o check.o
C:/RBuildTools/3.5/mingw_64/bin/g++ -shared -s -static-libgcc -o sourceCpp_3.dll tmp.def check.o -fopenmp -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lRblas -lgfortran -lm -lquadmath -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lR
check.o:check.cpp:(.text+0xa18): undefined reference to `sdot_'
collect2.exe: error: ld returned 1 exit status

Ниже приведена среда R на Windows

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)

Matrix products: default

Random number generation:
 RNG:     Mersenne-Twister 
 Normal:  Inversion 
 Sample:  Rounding 

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

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

loaded via a namespace (and not attached):
[1] compiler_3.6.1            tools_3.6.1               RcppArmadillo_0.9.850.1.0
[4] Rcpp_1.0.3 

Ниже приведена среда R на Linux

R version 3.6.3 (2020-02-29)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 16.04.6 LTS

Matrix products: default
BLAS:   /usr/lib/openblas-base/libblas.so.3
LAPACK: /usr/lib/libopenblasp-r0.2.18.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

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

loaded via a namespace (and not attached):
[1] compiler_3.6.3            tools_3.6.3              
[3] RcppArmadillo_0.9.850.1.0 Rcpp_1.0.4  

Ниже приведены коды "test. cpp"

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

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
  return x * 2;
}

// [[Rcpp::export]]
arma::vec check1(arma::vec x1, arma::vec x2, int rep){
  int n = x1.size();
  arma::vec y(n);
  y.fill(0);
  for(int i = 0; i < rep; i ++){
    y += x1 * arma::dot(x1, x2);
  }
  return y;
}

// [[Rcpp::export]]
arma::fvec check2(arma::fvec x1, arma::fvec x2, int rep){
  int n = x1.size();
  arma::fvec y(n);
  y.fill(0);
  for(int i = 0; i < rep; i ++){
    y += x1 * arma::dot(x1, x2);
  }
  return y;
}

// You can include R code blocks in C++ files processed with sourceCpp
// (useful for testing and development). The R code will be automatically 
// run after the compilation.
//

/*** R
timesTwo(42)
n = 100000
x1 = rnorm(n)
x2 = rnorm(n)
rep = 1000
system.time(y1 <- check1(x1, x2, rep))
system.time(y2 <- check2(x1, x2, rep))
head(y1)
head(y2)
*/

Ниже приведен вывод на Linux

> system.time(y1 <- check1(x1, x2, rep))
   user  system elapsed 
  0.156   0.000   0.160 

> system.time(y2 <- check2(x1, x2, rep))
   user  system elapsed 
  0.088   0.000   0.100

1 Ответ

1 голос
/ 03 апреля 2020

Здесь есть два вопроса:

  1. Почему это работает на Linux, а не Windows?

R имеет только int и double, но не float (или 64-битный integer). На Windows вы можете связываться с собственным внутренним LAPACK R, который, вероятно, имеет только double. На Linux float может присутствовать система LAPACK. Это мое лучшее предположение.

Можете ли вы / должны ли вы использовать float с Armadillo?

Не совсем. R имеет только double, а не float, поэтому для получения значений туда и обратно всегда требуются копии, и это менее эффективно. Я бы придерживался double.

...