int productQ(char side, char trans, ScalarArray<T>* qr, T* tau, ScalarArray<T>* c) { DECLARE_CONTEXT; int m = c->rows; int n = c->cols; int k = qr->cols; T* a = qr->m; assert((side == 'L') ? qr->rows == m : qr->rows == n); int ldq = qr->lda; int ldc = c->lda; int info; int workSize; T workSize_req; { size_t _m = m, _n = n, _k = k; size_t muls = 2 * _m * _n * _k - _n * _k * _k + 2 * _n * _k; size_t adds = 2 * _m * _n * _k - _n * _k * _k + _n * _k; increment_flops(Multipliers<T>::mul * muls + Multipliers<T>::add * adds); } info = proxy_lapack_convenience::or_un_mqr(side, trans, m, n, k, a, ldq, tau, c->m, ldc, &workSize_req, -1); HMAT_ASSERT(!info); workSize = (int) hmat::real(workSize_req) + 1; T* work = new T[workSize]; HMAT_ASSERT(work); info = proxy_lapack_convenience::or_un_mqr(side, trans, m, n, k, a, ldq, tau, c->m, ldc, work, workSize); HMAT_ASSERT(!info); delete[] work; return 0; }
template<> int sddCall<hmat::C_t>(char jobz, int m, int n, hmat::C_t* a, int lda, double* sigma, hmat::C_t* u, int ldu, hmat::C_t* vt, int ldvt) { int result; int workSize; hmat::C_t workSize_C; int p = min(m, n); float* sigmaFloat = new float[p]; int* iwork = new int[8*p]; // We request the right size for WORK result = proxy_lapack::gesdd(jobz, m, n, a, lda, sigmaFloat, u, ldu, vt, ldvt, &workSize_C, -1, iwork); HMAT_ASSERT(!result); workSize = (int) workSize_C.real() + 1; hmat::C_t* work = new hmat::C_t[workSize]; HMAT_ASSERT(work) ; result = proxy_lapack::gesdd(jobz, m, n, a, lda, sigmaFloat, u, ldu, vt, ldvt, work, workSize, iwork); HMAT_ASSERT(!result); delete[] work; delete[] iwork; for (int i = 0; i < p; i++) { sigma[i] = sigmaFloat[i]; } delete[] sigmaFloat; return result; }
template<typename T> T* qrDecomposition(ScalarArray<T>* m) { DECLARE_CONTEXT; // SUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO ) int rows = m->rows; int cols = m->cols; T* tau = (T*) calloc(min(rows, cols), sizeof(T)); { size_t mm = max(rows, cols); size_t n = min(rows, cols); size_t multiplications = mm * n * n - (n * n * n) / 3 + mm * n + (n * n) / 2 + (29 * n) / 6; size_t additions = mm * n * n + (n * n * n) / 3 + 2 * mm * n - (n * n) / 2 + (5 * n) / 6; increment_flops(Multipliers<T>::mul * multiplications + Multipliers<T>::add * additions); } int info; int workSize; T workSize_S; // int info = LAPACKE_sgeqrf(LAPACK_COL_MAJOR, rows, cols, m->m, rows, *tau); info = proxy_lapack::geqrf(rows, cols, m->m, rows, tau, &workSize_S, -1); HMAT_ASSERT(!info); workSize = (int) hmat::real(workSize_S) + 1; T* work = new T[workSize];// TODO Mettre dans la pile ?? HMAT_ASSERT(work) ; info = proxy_lapack::geqrf(rows, cols, m->m, rows, tau, work, workSize); delete[] work; HMAT_ASSERT(!info); return tau; }
void ClusterData::moveDoF(int index, ClusterData* right) { HMAT_ASSERT(offset_ + size_ == right->offset_ ); HMAT_ASSERT(index >= offset_); HMAT_ASSERT(index < offset_ + size_); // Swap degree of freedom and the last element of this bucket std::swap(indices()[index], indices()[offset_ + size_ - 1]); // Make current index set smaller ... size_ -= 1; // ... and expand right sibling right->offset_ -= 1; right->size_ += 1; }
template<> int svdCall<hmat::C_t>(char jobu, char jobv, int m, int n, hmat::C_t* a, int lda, double* sigma, hmat::C_t* u, int ldu, hmat::C_t* vt, int ldvt) { int result; int workSize; hmat::C_t workSize_C; int p = min(m, n); float* sigmaFloat = new float[p]; // We request the right size for WORK result = proxy_lapack::gesvd(jobu, jobv, m, n, a, lda, sigmaFloat, u, ldu, vt, ldvt, &workSize_C, -1); if(result != 0) throw hmat::LapackException("gesvd", result); workSize = (int) workSize_C.real() + 1; hmat::C_t* work = new hmat::C_t[workSize]; HMAT_ASSERT(work) ; result = proxy_lapack::gesvd(jobu, jobv, m, n, a, lda, sigmaFloat, u, ldu, vt, ldvt, work, workSize); if(result != 0) throw hmat::LapackException("gesvd", result); delete[] work; for (int i = 0; i < p; i++) { sigma[i] = sigmaFloat[i]; } delete[] sigmaFloat; return result; }
template<> int sddCall<hmat::Z_t>(char jobz, int m, int n, hmat::Z_t* a, int lda, double* sigma, hmat::Z_t* u, int ldu, hmat::Z_t* vt, int ldvt) { int result; int workSize; hmat::Z_t workSize_Z; int* iwork = new int[8*min(m,n)]; // We request the right size for WORK result = proxy_lapack::gesdd(jobz, m, n, a, lda, sigma, u, ldu, vt, ldvt, &workSize_Z, -1, iwork); HMAT_ASSERT(!result); workSize = (int) workSize_Z.real() + 1; hmat::Z_t* work = new hmat::Z_t[workSize]; HMAT_ASSERT(work) ; result = proxy_lapack::gesdd(jobz, m, n, a, lda, sigma, u, ldu, vt, ldvt, work, workSize, iwork); HMAT_ASSERT(!result); delete[] work; delete[] iwork; return result; }
template<typename T> int truncatedSvd(ScalarArray<T>* m, ScalarArray<T>** u, Vector<double>** sigma, ScalarArray<T>** vt) { DECLARE_CONTEXT; static char * useGESSD = getenv("HMAT_GESSD"); if(useGESSD) return truncatedSdd(m, u, sigma, vt); // Allocate free space for U, S, V int rows = m->rows; int cols = m->cols; int p = min(rows, cols); *u = new ScalarArray<T>(rows, p); *sigma = new Vector<double>(p); *vt = new ScalarArray<T>(p, cols); assert(m->lda >= m->rows); char jobz = 'S'; int mm = rows; int n = cols; T* a = m->m; int lda = rows; int info; { const size_t _m = mm, _n = n; // Warning: These quantities are a rough approximation. // What's wrong with these estimates: // - Golub only gives 14 * M*N*N + 8 N*N*N // - This is for real numbers // - We assume the same number of * and + size_t adds = 7 * _m * _n * _n + 4 * _n * _n * _n; size_t muls = 7 * _m * _n * _n + 4 * _n * _n * _n; increment_flops(Multipliers<T>::add * adds + Multipliers<T>::mul * muls); } info = svdCall<T>(jobz, jobz, mm, n, a, lda, (*sigma)->m, (*u)->m, (*u)->lda, (*vt)->m, (*vt)->lda); if (info) { cerr << "Erreur dans xGESVD: " << info << endl; } HMAT_ASSERT(!info); return info; }
template<> int svdCall<hmat::D_t>(char jobu, char jobv, int m, int n, hmat::D_t* a, int lda, double* sigma, hmat::D_t* u, int ldu, hmat::D_t* vt, int ldvt) { int workSize; hmat::D_t workSize_D; int result; // We request the right size for WORK result = proxy_lapack::gesvd(jobu, jobv, m, n, a, lda, sigma, u, ldu, vt, ldvt, &workSize_D, -1); if(result != 0) throw hmat::LapackException("gesvd", result); workSize = (int) workSize_D + 1; hmat::D_t* work = new hmat::D_t[workSize]; HMAT_ASSERT(work) ; result = proxy_lapack::gesvd(jobu, jobv, m, n, a, lda, sigma, u, ldu, vt, ldvt, work, workSize); if(result != 0) throw hmat::LapackException("gesvd", result); delete[] work; return result; }