我正在修改我的 biglasso 包以适应不同的数据类型big.matrix
。当前版本仅支持double
类型。源代码在这里。
我所做的只是简单地添加标题并对以作为输入template
的函数进行必要的更改。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;
}
但是,在我进行更改后,R 包无法编译。以下是错误消息。对我来说,它说明了一些与crossprod_bm
出错有关的事情:
Symbol not found: __Z12crossprod_bmIdEdN4Rcpp4XPtrI9BigMatrixNS0_15PreserveStorageEXadL_ZNS0_25standard_delete_finalizerIS2_EEvPT_EEEEPdPiddii
谁能告诉我是什么虫子?这些错误与类型转换有关吗?我假设计算中的类型转换可以自动完成。
非常感谢您!
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, ...)
...
}
[结束更新]
[更新 2]
我将所有更改提交到GitHub,以便您可以看到全貌。如果您能提出任何意见,我将不胜感激。
[更新 2]
[更新 3]
我认为cdfit_gaussian_edpp_cpp
应该返回Rcpp::List
。我纠正了这个(如上),但仍然有类似的错误。
似乎我的代码中的模板一定有问题,也许是定义模板?调用模板?
如果我不使用模板,一切都会好起来的!例如,如果我将错误消息中捕获的函数恢复为不是模板函数,那么发生的情况是该函数不会在错误中捕获。但是下一个模板函数将被捕获并带有类似的错误消息。
但是,另一方面,我尝试使用and来遵循示例Rcpp
bigmemory
。我更改了模板功能如下,这类似于我在包中使用模板的方式。但它有效!这让我觉得我正确使用了模板。
我在这里真的很困惑,如果任何专家可以指出错误,我将不胜感激!太感谢了!
// 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!");
}
}
[更新 3]