C++ Rcpp:使用模板函数时出错

C++ Rcpp:使用模板函数时出错,c++,templates,rcpp,r-bigmemory,C++,Templates,Rcpp,R Bigmemory,我正在修改我的biglasso包,以适应不同数据类型的big.matrix。当前版本仅支持double类型。源代码是 我所做的只是简单地添加模板标题,并对以big.matrix作为输入的函数进行必要的更改。下面的函数是一个示例:xpMat是指向big.matrix的指针 template<typename T> double crossprod_bm(XPtr<BigMatrix> xpMat, double *y_, int *row_idx_, double cent

我正在修改我的biglasso包,以适应不同数据类型的
big.matrix
。当前版本仅支持
double
类型。源代码是

我所做的只是简单地添加
模板
标题,并对以
big.matrix
作为输入的函数进行必要的更改。下面的函数是一个示例:
xpMat
是指向
big.matrix
的指针

template<typename T>
double crossprod_bm(XPtr<BigMatrix> xpMat, double *y_, int *row_idx_, double center_, 
                               double scale_, int n_row, int j) {
  // Previous code:
  // MatrixAccessor<double> xAcc(*xpMat);
  // double *xCol = xAcc[j];
  MatrixAccessor<T> xAcc(*xpMat);
  T *xCol = xAcc[j];

  double sum = 0.0;
  double sum_xy = 0.0;
  double sum_y = 0.0;
  for (int i=0; i < n_row; i++) {
    // row_idx only used by xP, not by y;
    sum_xy = sum_xy + xCol[row_idx_[i]] * y_[i];
    sum_y = sum_y + y_[i];
  }
  sum = (sum_xy - center_ * sum_y) / scale_;

  return sum;
}
有人能告诉我这些bug是什么吗?这些错误与类型转换有关吗?我假设计算中的类型转换可以自动完成。

提前非常感谢

clang-omp++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG  -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/RcppArmadillo/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include"  -fopenmp -std=c++11 -O3 -funroll-loops -fPIC  -Wall -mtune=core2 -g -O2  -c gaussian_hsr.cpp -o gaussian_hsr.o
clang-omp++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG  -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/RcppArmadillo/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include"  -fopenmp -std=c++11 -O3 -funroll-loops -fPIC  -Wall -mtune=core2 -g -O2  -c gaussian_hsr_dome.cpp -o gaussian_hsr_dome.o
clang-omp++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG  -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/RcppArmadillo/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include"  -fopenmp -std=c++11 -O3 -funroll-loops -fPIC  -Wall -mtune=core2 -g -O2  -c utilities.cpp -o utilities.o
clang-omp++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o biglasso.so binomial_hsr.o binomial_hsr_approx.o gaussian_edpp.o gaussian_hsr.o gaussian_hsr_dome.o utilities.o -fopenmp -lgomp -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
installing to /Users/yazeng/GitHub/biglasso.Rcheck/biglasso/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) : 
  unable to load shared object '/Users/yazeng/GitHub/biglasso.Rcheck/biglasso/libs/biglasso.so':
  dlopen(/Users/yazeng/GitHub/biglasso.Rcheck/biglasso/libs/biglasso.so, 6): Symbol not found: __Z12crossprod_bmIdEdN4Rcpp4XPtrI9BigMatrixNS0_15PreserveStorageEXadL_ZNS0_25standard_delete_finalizerIS2_EEvPT_EEEEPdPiddii
  Referenced from: /Users/yazeng/GitHub/biglasso.Rcheck/biglasso/libs/biglasso.so
  Expected in: flat namespace
 in /Users/yazeng/GitHub/biglasso.Rcheck/biglasso/libs/biglasso.so
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/Users/yazeng/GitHub/biglasso.Rcheck/biglasso’
[更新以响应@Coatless]

我确实有调度员,就像下面一样

template<typename T>  
List cdfit_gaussian_edpp_cpp(XPtr<BigMatrix> xMat,
                             SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_);

RcppExport SEXP cdfit_gaussian_edpp(SEXP X_, SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_) {
  XPtr<BigMatrix> xMat(X_);
  int xtype = xMat->matrix_type();

  switch(xtype)
  {
  case 2:
    return cdfit_gaussian_edpp_cpp<short>(xMat, y_, row_idx_, lambda_,nlambda_, 
                                         lam_scale_, lambda_min_,alpha_, 
                                         user_, eps_, max_iter_, multiplier_, 
                                         dfmax_, ncore_, verbose_);
  case 4:
    return cdfit_gaussian_edpp_cpp<int>(xMat, 
                                       y_, row_idx_, lambda_,nlambda_, 
                                       lam_scale_, lambda_min_,alpha_, 
                                       user_, eps_, max_iter_, multiplier_, 
                                       dfmax_, ncore_, verbose_);
  case 6:
    return cdfit_gaussian_edpp_cpp<float>(xMat,
                                         y_, row_idx_, lambda_,nlambda_, 
                                         lam_scale_, lambda_min_,alpha_, 
                                         user_, eps_, max_iter_, multiplier_, 
                                         dfmax_, ncore_, verbose_);
  case 8:
    return cdfit_gaussian_edpp_cpp<double>(xMat,
                                          y_, row_idx_, lambda_,nlambda_, 
                                          lam_scale_, lambda_min_,alpha_, 
                                          user_, eps_, max_iter_, multiplier_, 
                                          dfmax_, ncore_, verbose_);
  default:
    throw Rcpp::exception("the type defined for big.matrix is not supported!");
  }
}

template<typename T>  
List cdfit_gaussian_edpp_cpp(XPtr<BigMatrix> xMat,
                             SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_) {
...    
// Within this function, need call lower-level functions, e.g. crossprod_bm 
double res = crossprod_bm<T>(xMat, y, row_idx, ...)
...


}

[Update 3]

“无法加载共享对象”,hm。下一行给出一些提示:
未找到符号:\uuuuuuuuz12CrossProd\uBmidedN4rcpp4xptri9BigMatrixNS0\u15PreserveStorageExadl\uzns0\u25Standard\uDelete\uFinalizeris2\uEEVPT\uEEPEPDIDII
。我们可以看到捕获了
crossprod\u bm
。但不确定消息的确切含义。问题是函数pass中从未定义
T
。您还应该使用类似于:@Coatless的模型。谢谢你的反馈。但是,我的理解是,
crossprod\u bm
可以通过
crossprod\u bm(xpMat,y,row\u idx,…)
调用,它不需要在函数pass中定义
t
。请参阅和“无法加载共享对象”,hm。下一行给出了一些提示:
未找到符号:\uuuuuz12crossprod\ubmidedn4rcpp4xptri9bigmarixns0\u15preserveStorageExadl\uzns0\u25standard\udelete\ufinalizeris2\ueevpt\ueeppiddii
。我们可以看到捕获了
crossprod\u bm
。但不确定消息的确切含义。问题是函数pass中从未定义
T
。您还应该使用类似于:@Coatless的模型。谢谢你的反馈。但是,我的理解是,
crossprod\u bm
可以通过
crossprod\u bm(xpMat,y,row\u idx,…)
调用,它不需要在函数pass中定义
t
。看到和
template<typename T>  
List cdfit_gaussian_edpp_cpp(XPtr<BigMatrix> xMat,
                             SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_);

RcppExport SEXP cdfit_gaussian_edpp(SEXP X_, SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_) {
  XPtr<BigMatrix> xMat(X_);
  int xtype = xMat->matrix_type();

  switch(xtype)
  {
  case 2:
    return cdfit_gaussian_edpp_cpp<short>(xMat, y_, row_idx_, lambda_,nlambda_, 
                                         lam_scale_, lambda_min_,alpha_, 
                                         user_, eps_, max_iter_, multiplier_, 
                                         dfmax_, ncore_, verbose_);
  case 4:
    return cdfit_gaussian_edpp_cpp<int>(xMat, 
                                       y_, row_idx_, lambda_,nlambda_, 
                                       lam_scale_, lambda_min_,alpha_, 
                                       user_, eps_, max_iter_, multiplier_, 
                                       dfmax_, ncore_, verbose_);
  case 6:
    return cdfit_gaussian_edpp_cpp<float>(xMat,
                                         y_, row_idx_, lambda_,nlambda_, 
                                         lam_scale_, lambda_min_,alpha_, 
                                         user_, eps_, max_iter_, multiplier_, 
                                         dfmax_, ncore_, verbose_);
  case 8:
    return cdfit_gaussian_edpp_cpp<double>(xMat,
                                          y_, row_idx_, lambda_,nlambda_, 
                                          lam_scale_, lambda_min_,alpha_, 
                                          user_, eps_, max_iter_, multiplier_, 
                                          dfmax_, ncore_, verbose_);
  default:
    throw Rcpp::exception("the type defined for big.matrix is not supported!");
  }
}

template<typename T>  
List cdfit_gaussian_edpp_cpp(XPtr<BigMatrix> xMat,
                             SEXP y_, SEXP row_idx_, SEXP lambda_, 
                                    SEXP nlambda_, SEXP lam_scale_,
                                    SEXP lambda_min_, SEXP alpha_, 
                                    SEXP user_, SEXP eps_, SEXP max_iter_, 
                                    SEXP multiplier_, SEXP dfmax_, 
                                    SEXP ncore_, SEXP verbose_) {
...    
// Within this function, need call lower-level functions, e.g. crossprod_bm 
double res = crossprod_bm<T>(xMat, y, row_idx, ...)
...


}
// Logic for BigColSums.
template <typename T>
vector<int> BigColSums2(XPtr<BigMatrix> pMat) {

  // Create the vector we'll store the column sums in.
  MatrixAccessor<T> mat(*pMat);
  vector<int> colSums(pMat->ncol());
  for (size_t i=0; i < pMat->ncol(); i++) {
    for (size_t j=0; j < pMat->ncol(); j++) {
      colSums[i] += mat[i][j];
    }
  }
  return colSums;
}

// Dispatch function for BigColSums
//
// [[Rcpp::export]]
NumericVector BigColSums(SEXP pBigMat) {
  // First we have to tell Rcpp what class to use for big.matrix objects.
  // This object stores the attributes of the big.matrix object passed to it
  // by R.
  XPtr<BigMatrix> xpMat(pBigMat);

  // To access values in the big.matrix, we need to create a MatrixAccessor
  // object of the appropriate type. Note that in every case we are still
  // returning a NumericVector: this is because big.matrix objects only store
  // numeric values in R, even if their type is set to 'char'. The types
  // simply correspond to the number of bytes used for each element.
  switch(xpMat->matrix_type()) {
  case 1:
    return Rcpp::wrap(BigColSums2<char>(xpMat));
  case 2:
    return Rcpp::wrap(BigColSums2<short>(xpMat));
  case 4:
    return Rcpp::wrap(BigColSums2<int>(xpMat));
  case 8:
    return Rcpp::wrap(BigColSums2<double>(xpMat));
  // case 1:
  //   return BigColSums<char>(xpMat);
  // case 2:
  //   return BigColSums<short>(xpMat);
  // case 4:
  //   return BigColSums<int>(xpMat);
  // case 8:
  //   return BigColSums<double>(xpMat);
  default:
    // This case should never be encountered unless the implementation of
    // big.matrix changes, but is necessary to implement shut up compiler
    // warnings.
    throw Rcpp::exception("unknown type detected for big.matrix object!");
  }
}