Я пересматриваю свой пакет 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]
Задача ещё не решена.
Других решений пока нет …