Rcpp: ошибки произошли при использовании функции шаблона

Я пересматриваю свой пакет 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, Я исправил это (как указано выше), но все равно получил похожую ошибку.

Кажется, что-то не так с шаблонами в моем коде, может быть, определение шаблона? вызывать шаблоны?

Если я не использую шаблоны, все работает! Например, если я верну функцию, захваченную в сообщении об ошибке, обратно, чтобы она не была функцией шаблона, то получится, что эта функция не будет зафиксирована в ошибке. Но следующая функция шаблона будет записана с аналогичным сообщением об ошибке.

С другой стороны, однако, я пытался следовать пример использования 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]

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]