簡體   English   中英

將R包的錯誤與Rcpp鏈接:“undefined symbol:LAPACKE_dgels”

[英]Linking error of R package with Rcpp: “undefined symbol: LAPACKE_dgels”

我正在創建一個R包'lapacker'來為R提供和使用的內部LAPACK庫提供C接口(使用雙精度和雙復合),使用R API頭文件“R_ext / Lapack.h”。 源代碼: https//github.com/ypan1988/lapacker/

而項目結構:

/lapacker
  /inst
    /include
      /lapacke.h
      /someother header files
  /R
    /zzz.R
  /src
    /lapacke_dgetrf.c
    /lapacke_dgetrf_work.c
    /loads of other utility functions provided by LAPACKE 
    /rcpp_hello.cpp
  DESCRIPTION
  NAMESPACE

在項目內部,我在rcpp_hello.cpp文件中嘗試了一個測試函數(注意這個例子來自https://www.netlib.org/lapack/lapacke.html#_calling_code_dgels_code ):

//'@export
// [[Rcpp::export]]
void example_lapacke_dgels()
{
  double a[5][3] = {{1,1,1},{2,3,4},{3,5,2},{4,2,5},{5,4,3}};
  double b[5][2] = {{-10,-3},{12,14},{14,12},{16,16},{18,16}};
  lapack_int info,m,n,lda,ldb,nrhs;
  int i,j;

  m = 5;
  n = 3;
  nrhs = 2;
  lda = 3;
  ldb = 2;

  info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*b,ldb);

  for(i=0;i<n;i++)
  {
    for(j=0;j<nrhs;j++)
    {
      printf("%lf ",b[i][j]);
    }
    printf("\n");
  }
}

整個包可以正確編譯而沒有錯誤,在R中它給出了正確的答案(表示符號LAPACKE_dgels可以找到):

> example_lapacke_dgels()
2.000000 1.000000 
1.000000 1.000000 
1.000000 2.000000 

但是,當我創建一個單獨的C ++文件時,假設demo3.cpp具有完全相同的功能,

#include <Rcpp.h>

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

// [[Rcpp::export]]
void lapacke_dgels_test()
{
  double a[5][3] = {{1,1,1},{2,3,4},{3,5,2},{4,2,5},{5,4,3}};
  double b[5][2] = {{-10,-3},{12,14},{14,12},{16,16},{18,16}};
  lapack_int info,m,n,lda,ldb,nrhs;
  int i,j;

  m = 5;
  n = 3;
  nrhs = 2;
  lda = 3;
  ldb = 2;

  info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*b,ldb);

  for(i=0;i<n;i++)
  {
    for(j=0;j<nrhs;j++)
    {
      printf("%lf ",b[i][j]);
    }
    printf("\n");
  }
}

它不再正常編譯(實際上我在macOS和ubuntu下嘗試過相同的鏈接問題),並提供鏈接錯誤消息(找不到符號LAPACKE_dgels):

> Rcpp::sourceCpp("~/Desktop/demo3.cpp", showOutput = TRUE)
/usr/lib/R/bin/R CMD SHLIB -o 'sourceCpp_6.so'  'demo3.cpp'  
g++  -I/usr/share/R/include -DNDEBUG   -I"/home/yipan/R/x86_64-pc-linux-gnu-library/3.4/Rcpp/include" -I"/home/yipan/R/x86_64-pc-linux-gnu-library/3.4/lapacker/include" -I"/home/yipan/Desktop"    -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-AitvI6/r-base-3.4.4=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c demo3.cpp -o demo3.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_6.so demo3.o -L/usr/lib/R/lib -lR
Error in dyn.load("/tmp/RtmpUsASwK/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_159e6145591d/sourceCpp_6.so") : 
  unable to load shared object '/tmp/RtmpUsASwK/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_159e6145591d/sourceCpp_6.so':
  /tmp/RtmpUsASwK/sourceCpp-x86_64-pc-linux-gnu-1.0.0/sourcecpp_159e6145591d/sourceCpp_6.so: undefined symbol: LAPACKE_dgels

我還檢查了/R/x86_64-pc-linux-gnu-library/3.4/lapacker/libs下的lapacker.so,發現:

000000000000c6b0 g    DF .text  00000000000001bf  Base        LAPACKE_dgels

我是否想錯過讓demo3.cpp正確編譯的內容? 非常感謝您的耐心和時間!

你在這里面臨一個難題。 你正在試圖解決的象征LAPACKE_dgels是部分lapacker.so ,包安裝過程中建立。 問題是,R包的庫不用於鏈接。 相反,它們在運行時由R動態加載。 基本上,我看到四種可能性:

  1. lapacke轉換為僅頭文件庫並將其安裝在inst/include (cf RcppArmadillo )。
  2. 鏈接lapacke的系統安裝(在Linux上很簡單......)
  3. 使用R注冊所有函數並使用R提供的方法鏈接到它們(cf WREnloptr )。
  4. 編譯用於鏈接的庫並將其與R包一起安裝。 你仍然需要一個插件才能工作,因為你必須將-L<path/to/lib> -l<libname> ....PKG_LIBS

我確信CRAN上有一些使用方法4的例子,但現在沒有人想到。 但是,作為“代碼kata”,我已經將我最近的測試包轉換為使用此結構,請參閱https://github.com/rstub/levmaR/tree/static


(原始不完整的答案。)

src/Makevars你有

PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

通過Rcpp屬性編譯cpp文件時需要模擬設置。 實現這一目標的最佳方法是使用Rcpp插件,參見RcppArmadillo的解決方案 (調整未經測試!):

inlineCxxPlugin <- function(...) {
    plugin <-
        Rcpp::Rcpp.plugin.maker(
                  include.before = "#include <lapacke.h>",
                  libs           = "$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)",
                  package        = "lapacker"
              )
    settings <- plugin()
    settings$env$PKG_CPPFLAGS <- "-I../inst/include"
    settings
}

順便說一下,為什么你想直接與LAPACK接口,當RcppArmadillo已經這樣​​做了?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM