diff options
author | Pjotr Prins | 2020-05-22 07:15:37 -0500 |
---|---|---|
committer | Pjotr Prins | 2020-05-22 07:15:37 -0500 |
commit | 8c82a8294483ffac4d8e9635376723f26a8ae27b (patch) | |
tree | c987e3646be820fe703452ad250979e4f3c112a9 /src | |
parent | f112b0fa5f29651b5af8cb3bd1c2933f010c2960 (diff) | |
download | pangemma-8c82a8294483ffac4d8e9635376723f26a8ae27b.tar.gz |
Fixes for gcc (GCC) 10.1.0
Started to remove eigenlib (again)
Diffstat (limited to 'src')
-rw-r--r-- | src/eigenlib.cpp | 107 | ||||
-rw-r--r-- | src/eigenlib.h | 35 | ||||
-rw-r--r-- | src/fastblas.cpp | 39 | ||||
-rw-r--r-- | src/fastblas.h | 2 | ||||
-rw-r--r-- | src/fastopenblas.h | 4 | ||||
-rw-r--r-- | src/gemma.cpp | 22 | ||||
-rw-r--r-- | src/gemma_io.cpp | 2 | ||||
-rw-r--r-- | src/lmm.cpp | 4 | ||||
-rw-r--r-- | src/param.cpp | 3 | ||||
-rw-r--r-- | src/vc.cpp | 22 |
10 files changed, 66 insertions, 174 deletions
diff --git a/src/eigenlib.cpp b/src/eigenlib.cpp deleted file mode 100644 index 470aa08..0000000 --- a/src/eigenlib.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Genome-wide Efficient Mixed Model Association (GEMMA) - Copyright (C) 2011-2017, Xiang Zhou - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "Eigen/Dense" -// #include "gsl/gsl_linalg.h" -#include "gsl/gsl_matrix.h" -// #include "gsl/gsl_vector.h" -#include <cmath> -#include <iostream> -#include <vector> -// #include <cblas.h> - -using namespace std; -using namespace Eigen; - - -// On two different clusters, compare eigen vs lapack/gsl: -// -// dgemm, 5x or 0.5x faster or slower than lapack, 5x or 4x faster than gsl -// dgemv, 20x or 4x faster than gsl, -// eigen, 1x or 0.3x slower than lapack -// invert, 20x or 10x faster than lapack -// -void eigenlib_dgemm(const char *TransA, const char *TransB, const double alpha, - const gsl_matrix *A, const gsl_matrix *B, const double beta, - gsl_matrix *C) { - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - A_mat(A->data, A->size1, A->size2, OuterStride<Dynamic>(A->tda)); - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - B_mat(B->data, B->size1, B->size2, OuterStride<Dynamic>(B->tda)); - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - C_mat(C->data, C->size1, C->size2, OuterStride<Dynamic>(C->tda)); - - if (*TransA == 'N' || *TransA == 'n') { - if (*TransB == 'N' || *TransB == 'n') { - C_mat = alpha * A_mat * B_mat + beta * C_mat; - } else { - C_mat = alpha * A_mat * B_mat.transpose() + beta * C_mat; - } - } else { - if (*TransB == 'N' || *TransB == 'n') { - C_mat = alpha * A_mat.transpose() * B_mat + beta * C_mat; - } else { - C_mat = alpha * A_mat.transpose() * B_mat.transpose() + beta * C_mat; - } - } -} - -void eigenlib_dgemv(const char *TransA, const double alpha, const gsl_matrix *A, - const gsl_vector *x, const double beta, gsl_vector *y) { - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - A_mat(A->data, A->size1, A->size2, OuterStride<Dynamic>(A->tda)); - Map<Matrix<double, Dynamic, 1>, 0, InnerStride<Dynamic>> x_vec( - x->data, x->size, InnerStride<Dynamic>(x->stride)); - Map<Matrix<double, Dynamic, 1>, 0, InnerStride<Dynamic>> y_vec( - y->data, y->size, InnerStride<Dynamic>(y->stride)); - - if (*TransA == 'N' || *TransA == 'n') { - y_vec = alpha * A_mat * x_vec + beta * y_vec; - } else { - y_vec = alpha * A_mat.transpose() * x_vec + beta * y_vec; - } -} - -void eigenlib_invert(gsl_matrix *A) { - Map<Matrix<double, Dynamic, Dynamic, RowMajor>> A_mat(A->data, A->size1, - A->size2); - A_mat = A_mat.inverse(); -} - -void eigenlib_dsyr(const double alpha, const gsl_vector *b, gsl_matrix *A) { - Map<Matrix<double, Dynamic, Dynamic, RowMajor>> A_mat(A->data, A->size1, - A->size2); - Map<Matrix<double, Dynamic, 1>, 0, OuterStride<Dynamic>> b_vec( - b->data, b->size, OuterStride<Dynamic>(b->stride)); - A_mat = alpha * b_vec * b_vec.transpose() + A_mat; -} - -void eigenlib_eigensymm(const gsl_matrix *G, gsl_matrix *U, gsl_vector *eval) { - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - G_mat(G->data, G->size1, G->size2, OuterStride<Dynamic>(G->tda)); - Map<Matrix<double, Dynamic, Dynamic, RowMajor>, 0, OuterStride<Dynamic>> - U_mat(U->data, U->size1, U->size2, OuterStride<Dynamic>(U->tda)); - Map<Matrix<double, Dynamic, 1>, 0, OuterStride<Dynamic>> eval_vec( - eval->data, eval->size, OuterStride<Dynamic>(eval->stride)); - - SelfAdjointEigenSolver<MatrixXd> es(G_mat); - if (es.info() != Success) - abort(); - eval_vec = es.eigenvalues(); - U_mat = es.eigenvectors(); -} diff --git a/src/eigenlib.h b/src/eigenlib.h index 7fb69ad..e69de29 100644 --- a/src/eigenlib.h +++ b/src/eigenlib.h @@ -1,35 +0,0 @@ -/* - Genome-wide Efficient Mixed Model Association (GEMMA) - Copyright (C) 2011-2017, Xiang Zhou - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __EIGENLIB_H__ -#define __EIGENLIB_H__ - -// #include <vector> - -// using namespace std; - -void eigenlib_dgemm(const char *TransA, const char *TransB, const double alpha, - const gsl_matrix *A, const gsl_matrix *B, const double beta, - gsl_matrix *C); -void eigenlib_dgemv(const char *TransA, const double alpha, const gsl_matrix *A, - const gsl_vector *x, const double beta, gsl_vector *y); -void eigenlib_invert(gsl_matrix *A); -void eigenlib_dsyr(const double alpha, const gsl_vector *b, gsl_matrix *A); -void eigenlib_eigensymm(const gsl_matrix *G, gsl_matrix *U, gsl_vector *eval); - -#endif diff --git a/src/fastblas.cpp b/src/fastblas.cpp index b3fcddb..e9e38d0 100644 --- a/src/fastblas.cpp +++ b/src/fastblas.cpp @@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "gsl/gsl_matrix.h" +// #include "gsl/gsl_matrix.h" #include <algorithm> // std::min #include <cmath> #include <iomanip> @@ -235,8 +235,39 @@ void fast_dgemm(const char *TransA, const char *TransB, const double alpha, void fast_eigen_dgemm(const char *TransA, const char *TransB, const double alpha, const gsl_matrix *A, const gsl_matrix *B, const double beta, gsl_matrix *C) { - if (is_legacy_mode()) - eigenlib_dgemm(TransA,TransB,alpha,A,B,beta,C); - else fast_cblas_dgemm(TransA,TransB,alpha,A,B,beta,C); } + +/* + * Inverse in place + */ + +#include <gsl/gsl_permutation.h> +#include <gsl/gsl_linalg.h> + +void gsl_matrix_inv(gsl_matrix *m) +{ + size_t n=m->size1; + + gsl_matrix *temp1=gsl_matrix_calloc(n,n); + gsl_matrix_memcpy(temp1,m); + + gsl_permutation *p=gsl_permutation_calloc(n); + int sign=0; + gsl_linalg_LU_decomp(temp1,p,&sign); + gsl_matrix *inverse=gsl_matrix_calloc(n,n); + + gsl_linalg_LU_invert(temp1,p,inverse); + gsl_matrix_memcpy(m,inverse); + + gsl_permutation_free(p); + gsl_matrix_free(temp1); + gsl_matrix_free(inverse); + +} + +void fast_inverse(gsl_matrix *m) { + gsl_matrix_inv(m); +} + + diff --git a/src/fastblas.h b/src/fastblas.h index 343a73a..cca3258 100644 --- a/src/fastblas.h +++ b/src/fastblas.h @@ -37,4 +37,6 @@ void fast_eigen_dgemm(const char *TransA, const char *TransB, const double alpha const gsl_matrix *A, const gsl_matrix *B, const double beta, gsl_matrix *C); +void fast_inverse(gsl_matrix *m); + #endif diff --git a/src/fastopenblas.h b/src/fastopenblas.h index e98e62f..2fc743e 100644 --- a/src/fastopenblas.h +++ b/src/fastopenblas.h @@ -25,9 +25,9 @@ #include <iostream> extern "C" { - #include <cblas.h> // For OpenBlas / Atlas + // #include <cblas.h> // For OpenBlas / Atlas } -#include "gsl/gsl_matrix.h" +// #include "gsl/gsl_matrix.h" void fast_cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, diff --git a/src/gemma.cpp b/src/gemma.cpp index 0ced70c..6bc739b 100644 --- a/src/gemma.cpp +++ b/src/gemma.cpp @@ -2697,25 +2697,25 @@ void GEMMA::BatchRun(PARAM &cPar) { CalcLambda('L', eval, UtW, &UtY_col.vector, cPar.l_min, cPar.l_max, cPar.n_region, cPar.l_mle_null, cPar.logl_mle_H0); - assert(!std::isnan(UtY->data[0])); + assert(!isnan(UtY->data[0])); CalcLmmVgVeBeta(eval, UtW, &UtY_col.vector, cPar.l_mle_null, cPar.vg_mle_null, cPar.ve_mle_null, &beta.vector, &se_beta.vector); - assert(!std::isnan(UtY->data[0])); + assert(!isnan(UtY->data[0])); cPar.beta_mle_null.clear(); cPar.se_beta_mle_null.clear(); - assert(!std::isnan(B->data[0])); - assert(!std::isnan(se_B->data[0])); + assert(!isnan(B->data[0])); + assert(!isnan(se_B->data[0])); for (size_t i = 0; i < B->size2; i++) { cPar.beta_mle_null.push_back(gsl_matrix_get(B, 0, i)); cPar.se_beta_mle_null.push_back(gsl_matrix_get(se_B, 0, i)); } - assert(!std::isnan(UtY->data[0])); - assert(!std::isnan(cPar.beta_mle_null.front())); - assert(!std::isnan(cPar.se_beta_mle_null.front())); + assert(!isnan(UtY->data[0])); + assert(!isnan(cPar.beta_mle_null.front())); + assert(!isnan(cPar.se_beta_mle_null.front())); // the following functions do not modify eval CalcLambda('R', eval, UtW, &UtY_col.vector, cPar.l_min, cPar.l_max, @@ -2726,8 +2726,8 @@ void GEMMA::BatchRun(PARAM &cPar) { cPar.beta_remle_null.clear(); cPar.se_beta_remle_null.clear(); - assert(!std::isnan(B->data[0])); - assert(!std::isnan(se_B->data[0])); + assert(!isnan(B->data[0])); + assert(!isnan(se_B->data[0])); for (size_t i = 0; i < B->size2; i++) { cPar.beta_remle_null.push_back(gsl_matrix_get(B, 0, i)); @@ -3124,7 +3124,7 @@ void GEMMA::BatchRun(PARAM &cPar) { return; } -#include "Eigen/Dense" +// #include "Eigen/Dense" void GEMMA::WriteLog(int argc, char **argv, PARAM &cPar) { string file_str; @@ -3144,7 +3144,7 @@ void GEMMA::WriteLog(int argc, char **argv, PARAM &cPar) { outfile << "## GCC version = " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << endl; #endif outfile << "## GSL Version = " << GSL_VERSION << endl; - outfile << "## Eigen Version = " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl; + // outfile << "## Eigen Version = " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl; #ifdef OPENBLAS #ifndef OPENBLAS_LEGACY diff --git a/src/gemma_io.cpp b/src/gemma_io.cpp index 3c71ea6..2380d45 100644 --- a/src/gemma_io.cpp +++ b/src/gemma_io.cpp @@ -1470,7 +1470,7 @@ bool BimbamKin(const string file_geno, const set<string> ksnps, gsl_vector_set(geno_miss, i, 0); n_miss++; } else { - double d = stod(field); + double d = atof(field); if (is_strict_mode() && d == 0.0) enforce_is_float(std::string(field)); // rule out non NA and non-float fields gsl_vector_set(geno, i, d); diff --git a/src/lmm.cpp b/src/lmm.cpp index 16fc3c8..b811594 100644 --- a/src/lmm.cpp +++ b/src/lmm.cpp @@ -1582,7 +1582,7 @@ void LMM::Analyze(std::function< SnpNameValues(size_t) >& fetch_snp, continue; double geno = gs[i]; - if (std::isnan(geno)) { + if (isnan(geno)) { gsl_vector_set(x_miss, pos, 1.0); n_miss++; } else { @@ -1829,7 +1829,7 @@ void LMM::AnalyzePlink(const gsl_matrix *U, const gsl_vector *eval, gsl_matrix_submatrix(UtXlarge, 0, 0, UtXlarge->size1, l); time_start = clock(); - eigenlib_dgemm("T", "N", 1.0, U, &Xlarge_sub.matrix, 0.0, + fast_dgemm("T", "N", 1.0, U, &Xlarge_sub.matrix, 0.0, &UtXlarge_sub.matrix); time_UtX += (clock() - time_start) / (double(CLOCKS_PER_SEC) * 60.0); diff --git a/src/param.cpp b/src/param.cpp index de0c257..31b7382 100644 --- a/src/param.cpp +++ b/src/param.cpp @@ -39,6 +39,7 @@ #include "gemma_io.h" #include "mathfunc.h" #include "param.h" +#include "fastblas.h" using namespace std; @@ -1412,7 +1413,7 @@ void compKtoV(const gsl_matrix *G, gsl_matrix *V) { gsl_matrix_const_submatrix(G, 0, j * ni_test, ni_test, ni_test); gsl_matrix_view KiKj_sub = gsl_matrix_submatrix(KiKj, 0, t * ni_test, ni_test, ni_test); - eigenlib_dgemm("N", "N", 1.0, &Ki.matrix, &Kj.matrix, 0.0, + fast_dgemm("N", "N", 1.0, &Ki.matrix, &Kj.matrix, 0.0, &KiKj_sub.matrix); t++; } @@ -43,7 +43,6 @@ // #include "Eigen/Dense" -#include "eigenlib.h" #include "gzstream.h" #include "gemma_io.h" #include "lapack.h" @@ -51,6 +50,7 @@ #include "mathfunc.h" #include "param.h" #include "vc.h" +#include "fastblas.h" using namespace std; // using namespace Eigen; @@ -198,16 +198,16 @@ void UpdateParam(const gsl_vector *log_sigma2, VC_PARAM *p) { } // Calculate H^{-1}. - eigenlib_invert(p->P); + fast_inverse(p->P); - eigenlib_dgemm("N", "N", 1.0, p->P, p->W, 0.0, HiW); - eigenlib_dgemm("T", "N", 1.0, p->W, HiW, 0.0, WtHiW); + fast_dgemm("N", "N", 1.0, p->P, p->W, 0.0, HiW); + fast_dgemm("T", "N", 1.0, p->W, HiW, 0.0, WtHiW); - eigenlib_invert(WtHiW); + fast_inverse(WtHiW); gsl_matrix_memcpy(WtHiWi, WtHiW); - eigenlib_dgemm("N", "T", 1.0, WtHiWi, HiW, 0.0, WtHiWiWtHi); - eigenlib_dgemm("N", "N", -1.0, HiW, WtHiWiWtHi, 1.0, p->P); + fast_dgemm("N", "T", 1.0, WtHiWi, HiW, 0.0, WtHiWiWtHi); + fast_dgemm("N", "N", -1.0, HiW, WtHiWiWtHi, 1.0, p->P); // Calculate Py, KPy, PKPy. gsl_blas_dgemv(CblasNoTrans, 1.0, p->P, p->y, 0.0, p->Py); @@ -224,7 +224,7 @@ void UpdateParam(const gsl_vector *log_sigma2, VC_PARAM *p) { gsl_matrix_const_submatrix(p->K, 0, n1 * i, n1, n1); // Seems to be important to use gsl dgemv here instead of - // eigenlib_dgemv; otherwise. + // fast_dgemv; otherwise. gsl_blas_dgemv(CblasNoTrans, 1.0, &K_sub.matrix, p->Py, 0.0, &KPy.vector); } @@ -232,15 +232,15 @@ void UpdateParam(const gsl_vector *log_sigma2, VC_PARAM *p) { // When phenotypes are not normalized well, then some values in // the following matrix maybe NaN; change that to 0; this seems to - // only happen when eigenlib_dgemv was used above. + // only happen when fast_dgemv was used above. for (size_t j = 0; j < p->KPy_mat->size1; j++) { d = gsl_matrix_get(p->KPy_mat, j, i); - if (std::isnan(d)) { + if (isnan(d)) { gsl_matrix_set(p->KPy_mat, j, i, 0); cout << "nan appears in " << i << " " << j << endl; } d = gsl_matrix_get(p->PKPy_mat, j, i); - if (std::isnan(d)) { + if (isnan(d)) { gsl_matrix_set(p->PKPy_mat, j, i, 0); cout << "nan appears in " << i << " " << j << endl; } |