diff --git a/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrix.h b/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrix.h new file mode 100644 index 000000000..2b988b64c --- /dev/null +++ b/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrix.h @@ -0,0 +1,704 @@ +/************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/algorithms/GeneralCoarsenedMatrix.h + + Copyright (C) 2015 + +Author: Peter Boyle + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ +#pragma once + +#include // needed for Dagger(Yes|No), Inverse(Yes|No) + +#include +#include +#include + +NAMESPACE_BEGIN(Grid); + +// Fine Object == (per site) type of fine field +// nbasis == number of deflation vectors +template +class GeneralCoarsenedMatrix : public SparseMatrixBase > > { +public: + + typedef GeneralCoarsenedMatrix GeneralCoarseOp; + typedef iVector siteVector; + typedef iMatrix siteMatrix; + typedef Lattice > CoarseComplexField; + typedef Lattice CoarseVector; + typedef Lattice > CoarseMatrix; + typedef iMatrix Cobj; + typedef iVector Cvec; + typedef Lattice< CComplex > CoarseScalar; // used for inner products on fine field + typedef Lattice FineField; + typedef Lattice FineComplexField; + typedef CoarseVector Field; + //////////////////// + // Data members + //////////////////// + int hermitian; + GridBase * _FineGrid; + GridCartesian * _CoarseGrid; + NonLocalStencilGeometry &geom; + PaddedCell Cell; + GeneralLocalStencil Stencil; + + std::vector _A; + std::vector _Adag; + std::vector MultTemporaries; + + int64_t MultCalls; + double MultFlopsAccum; + double MultUsecAccum; + + /////////////////////// + // Interface + /////////////////////// + ////////////////////////////////////////////////////////////////////////// + // Bilingual accessors: everything a consumer needs to read the operator + // without knowing which of the three coarse classes it holds. The D + // dimensional grid the elements live on, the geometry they are indexed by, + // and one unpadded point at a time (a whole npoint vector is too much + // memory at production nbasis). + ////////////////////////////////////////////////////////////////////////// + GridCartesian * CoarseGridD(void) { return _CoarseGrid; }; + NonLocalStencilGeometry & Geometry(void) { return geom; }; + void ExtractMatrix(int p,CoarseMatrix &A) { A = Cell.Extract(_A[p]); }; + + GridBase * Grid(void) { return _CoarseGrid; }; // this is all the linalg routines need to know + GridBase * FineGrid(void) { return _FineGrid; }; // this is all the linalg routines need to know + GridCartesian * CoarseGrid(void) { return _CoarseGrid; }; // this is all the linalg routines need to know + + /* void ShiftMatrix(RealD shift) + { + int Nd=_FineGrid->Nd(); + Coordinate zero_shift(Nd,0); + for(int p=0;p &A,const CoarseVector &in, CoarseVector &out) + { + RealD tviews=0; RealD ttot=0; RealD tmult=0; RealD texch=0; RealD text=0; RealD ttemps=0; RealD tcopy=0; + RealD tmult2=0; + + ttot=-usecond(); + conformable(CoarseGrid(),in.Grid()); + conformable(in.Grid(),out.Grid()); + out.Checkerboard() = in.Checkerboard(); + CoarseVector tin=in; + + texch-=usecond(); + CoarseVector pin = Cell.ExchangePeriodic(tin); + texch+=usecond(); + + CoarseVector pout(pin.Grid()); + + int npoint = geom.npoint; + typedef LatticeView Aview; + typedef LatticeView Vview; + + const int Nsimd = CComplex::Nsimd(); + + int64_t osites=pin.Grid()->oSites(); + + RealD flops = 1.0* npoint * nbasis * nbasis * 8.0 * osites * CComplex::Nsimd(); + RealD bytes = 1.0*osites*sizeof(siteMatrix)*npoint + + 2.0*osites*sizeof(siteVector)*npoint; + + { + tviews-=usecond(); + autoView( in_v , pin, AcceleratorRead); + autoView( out_v , pout, AcceleratorWriteDiscard); + autoView( Stencil_v , Stencil, AcceleratorRead); + tviews+=usecond(); + + // Static and prereserve to keep UVM region live and not resized across multiple calls + ttemps-=usecond(); + MultTemporaries.resize(npoint,pin.Grid()); + ttemps+=usecond(); + std::vector AcceleratorViewContainer_h; + std::vector AcceleratorVecViewContainer_h; + + tviews-=usecond(); + for(int p=0;p AcceleratorViewContainer; AcceleratorViewContainer.resize(npoint); + static deviceVector AcceleratorVecViewContainer; AcceleratorVecViewContainer.resize(npoint); + + auto Aview_p = &AcceleratorViewContainer[0]; + auto Vview_p = &AcceleratorVecViewContainer[0]; + tcopy-=usecond(); + acceleratorCopyToDevice(&AcceleratorViewContainer_h[0],&AcceleratorViewContainer[0],npoint *sizeof(Aview)); + acceleratorCopyToDevice(&AcceleratorVecViewContainer_h[0],&AcceleratorVecViewContainer[0],npoint *sizeof(Vview)); + tcopy+=usecond(); + + tmult-=usecond(); + accelerator_for(spb, osites*nbasis*npoint, Nsimd, { + typedef decltype(coalescedRead(in_v[0](0))) calcComplex; + int32_t ss = spb/(nbasis*npoint); + int32_t bp = spb%(nbasis*npoint); + int32_t point= bp/nbasis; + int32_t b = bp%nbasis; + auto SE = Stencil_v.GetEntry(point,ss); + auto nbr = coalescedReadGeneralPermute(in_v[SE->_offset],SE->_permute,Nd); + auto res = coalescedRead(Aview_p[point][ss](0,b))*nbr(0); + for(int bb=1;bbgSites() ;bidx++){ + Coordinate bcoor; + CoarseGrid()->GlobalIndexToGlobalCoor(bidx,bcoor); + + for(int p=0;pGlobalDimensions()[mu]; + scoor[mu] = (bcoor[mu] - geom.shifts[p][mu] + L) % L; // Modulo arithmetic + } + // Flip to poke/peekLocalSite and not too bad + auto link = peekSite(_A[p],scoor); + int pp = geom.Reverse(p); + pokeSite(adj(link),_Adag[pp],bcoor); + } + } +#else + // Parallel: _Adag[pp](x) = adj( _A[p](x + s_pp) ), pp = Reverse(p), s_pp = -s_p. + // The neighbour fetch reuses the same padded-cell + stencil machinery as Mult, + // reading one matrix element per coalesced access so no whole site matrix + // (230KB at nbasis=60) ever lands on a GPU thread stack (HIP limit 128KB). + // Halo sites compute garbage neighbours; Cell.Extract discards them. + // Must run on the unpadded _A, i.e. before ExchangeCoarseLinks. + const int Nsimd = CComplex::Nsimd(); + for(int p=0;poSites(); + { + autoView( Apad_v , Apad, AcceleratorRead); + autoView( Dpad_v , Dpad, AcceleratorWriteDiscard); + autoView( Stencil_v, Stencil, AcceleratorRead); + accelerator_for(sj, osites*nbasis, Nsimd, { + int32_t ss = sj/nbasis; + int32_t j = sj%nbasis; + auto SE = Stencil_v.GetEntry(pp,ss); + for(int i=0;i_offset](i,j),SE->_permute,Nd); + coalescedWrite(Dpad_v[ss](j,i),conjugate(z)); + } + }); + } + _Adag[pp] = Cell.Extract(Dpad); + } +#endif + } + ///////////////////////////////////////////////////////////// + // + // A) Only reduced flops option is to use a padded cell of depth 4 + // and apply MpcDagMpc in the padded cell. + // + // Makes for ONE application of MpcDagMpc per vector instead of 30 or 80. + // With the effective cell size around (B+8)^4 perhaps 12^4/4^4 ratio + // Cost is 81x more, same as stencil size. + // + // But: can eliminate comms and do as local dirichlet. + // + // Local exchange gauge field once. + // Apply to all vectors, local only computation. + // Must exchange ghost subcells in reverse process of PaddedCell to take inner products + // + // B) Can reduce cost: pad by 1, apply Deo (4^4+6^4+8^4+8^4 )/ (4x 4^4) + // pad by 2, apply Doe + // pad by 3, apply Deo + // then break out 8x directions; cost is ~10x MpcDagMpc per vector + // + // => almost factor of 10 in setup cost, excluding data rearrangement + // + // Intermediates -- ignore the corner terms, leave approximate and force Hermitian + // Intermediates -- pad by 2 and apply 1+8+24 = 33 times. + ///////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////// + // BFM HDCG style approach: Solve a system of equations to get Aij + ////////////////////////////////////////////////////////// + /* + * Here, k,l index which possible shift within the 3^Nd "ball" connected by MdagM. + * + * conj(phases[block]) proj[k][ block*Nvec+j ] = \sum_ball e^{i q_k . delta} < phi_{block,j} | MdagM | phi_{(block+delta),i} > + * = \sum_ball e^{iqk.delta} A_ji + * + * Must invert matrix M_k,l = e^[i q_k . delta_l] + * + * Where q_k = delta_k . (2*M_PI/global_nb[mu]) + */ +#if 0 + void CoarsenOperator(LinearOperatorBase > &linop, + Aggregation & Subspace) + { + std::cout << GridLogMessage<< "GeneralCoarsenMatrix "<< std::endl; + GridBase *grid = FineGrid(); + + RealD tproj=0.0; + RealD teigen=0.0; + RealD tmat=0.0; + RealD tphase=0.0; + RealD tinv=0.0; + + ///////////////////////////////////////////////////////////// + // Orthogonalise the subblocks over the basis + ///////////////////////////////////////////////////////////// + CoarseScalar InnerProd(CoarseGrid()); + blockOrthogonalise(InnerProd,Subspace.subspace); + + const int npoint = geom.npoint; + + Coordinate clatt = CoarseGrid()->GlobalDimensions(); + int Nd = CoarseGrid()->Nd(); + + /* + * Here, k,l index which possible momentum/shift within the N-points connected by MdagM. + * Matrix index i is mapped to this shift via + * geom.shifts[i] + * + * conj(pha[block]) proj[k (which mom)][j (basis vec cpt)][block] + * = \sum_{l in ball} e^{i q_k . delta_l} < phi_{block,j} | MdagM | phi_{(block+delta_l),i} > + * = \sum_{l in ball} e^{iqk.delta_l} A_ji^{b.b+l} + * = M_{kl} A_ji^{b.b+l} + * + * Must assemble and invert matrix M_k,l = e^[i q_k . delta_l] + * + * Where q_k = delta_k . (2*M_PI/global_nb[mu]) + * + * Then A{ji}^{b,b+l} = M^{-1}_{lm} ComputeProj_{m,b,i,j} + */ + teigen-=usecond(); + Eigen::MatrixXcd Mkl = Eigen::MatrixXcd::Zero(npoint,npoint); + Eigen::MatrixXcd invMkl = Eigen::MatrixXcd::Zero(npoint,npoint); + ComplexD ci(0.0,1.0); + for(int k=0;k ComputeProj(npoint,CoarseGrid()); + std::vector FT(npoint,CoarseGrid()); + for(int i=0;ioSites(); + autoView( A_v , _A[k], AcceleratorWrite); + autoView( FT_v , FT[k], AcceleratorRead); + accelerator_for(sss, osites, nbasis, { +#ifdef GRID_SIMT + int j = acceleratorSIMTlane(nbasis); + A_v[sss](i,j) = FT_v[sss](j); +#else + // CPU build: acceleratorSIMTlane()==0 -- an un-looped SIMT tensor + // index writes ONLY j=0 and silently drops the other nbasis-1 + // columns (caught by Test_schur_dense_coarse import certificate, + // 2026-08-14). Loop explicitly. + for(int j=0;j > &linop, + Aggregation & Subspace) + { + CoarsenOperator(linop,Subspace,Subspace); + } + ////////////////////////////////////////////////////////////////////// + // Petrov - Galerkin projection of matrix + ////////////////////////////////////////////////////////////////////// + void CoarsenOperator(LinearOperatorBase > &linop, + Aggregation & U, + Aggregation & V) + { + std::cout << GridLogMessage<< "GeneralCoarsenMatrix "<< std::endl; + GridBase *grid = FineGrid(); + + RealD tproj=0.0; + RealD teigen=0.0; + RealD tmat=0.0; + RealD tphase=0.0; + RealD tphaseBZ=0.0; + RealD tinv=0.0; + + ///////////////////////////////////////////////////////////// + // Orthogonalise the subblocks over the basis + ///////////////////////////////////////////////////////////// + CoarseScalar InnerProd(CoarseGrid()); + blockOrthogonalise(InnerProd,V.subspace); + blockOrthogonalise(InnerProd,U.subspace); + + const int npoint = geom.npoint; + + Coordinate clatt = CoarseGrid()->GlobalDimensions(); + int Nd = CoarseGrid()->Nd(); + + /* + * Here, k,l index which possible momentum/shift within the N-points connected by MdagM. + * Matrix index i is mapped to this shift via + * geom.shifts[i] + * + * conj(pha[block]) proj[k (which mom)][j (basis vec cpt)][block] + * = \sum_{l in ball} e^{i q_k . delta_l} < phi_{block,j} | MdagM | phi_{(block+delta_l),i} > + * = \sum_{l in ball} e^{iqk.delta_l} A_ji^{b.b+l} + * = M_{kl} A_ji^{b.b+l} + * + * Must assemble and invert matrix M_k,l = e^[i q_k . delta_l] + * + * Where q_k = delta_k . (2*M_PI/global_nb[mu]) + * + * Then A{ji}^{b,b+l} = M^{-1}_{lm} ComputeProj_{m,b,i,j} + */ + teigen-=usecond(); + Eigen::MatrixXcd Mkl = Eigen::MatrixXcd::Zero(npoint,npoint); + Eigen::MatrixXcd invMkl = Eigen::MatrixXcd::Zero(npoint,npoint); + ComplexD ci(0.0,1.0); + for(int k=0;k phaF(npoint,grid); + std::vector pha(npoint,CoarseGrid()); + + typedef typename CComplex::scalar_type SComplex; + FineComplexField one(grid); one=SComplex(1.0); + FineComplexField zz(grid); zz = Zero(); + tphase=-usecond(); + for(int p=0;p Projector; + Projector.Allocate(nbasis, grid, CoarseGrid()); + Projector.ImportBasis(U.subspace); + + std::vector phaV_batch(npoint, grid); + std::vector MphaV_batch(npoint, grid); + std::vector proj_batch(npoint, CoarseGrid()); + std::vector ComputeProj(npoint, CoarseGrid()); + std::vector FT(npoint, CoarseGrid()); + + // Pre-allocate BLAS_F and BLAS_C to avoid repeated hipMalloc/hipFree of + // ~5.6 GB per blockProject call, which hangs on ROCm for large allocations. + Projector.BLAS_F.resize(Projector.fine_vol * Projector.words * npoint); + Projector.BLAS_C.resize(Projector.coarse_vol * nbasis * npoint); + + for(int i=0;ioSites(); + autoView( A_v , _A[k], AcceleratorWrite); + autoView( FT_v , FT[k], AcceleratorRead); + accelerator_for(sss, osites, nbasis, { +#ifdef GRID_SIMT + int j = acceleratorSIMTlane(nbasis); + A_v[sss](i,j) = FT_v[sss](j); +#else + // CPU build: acceleratorSIMTlane()==0 -- an un-looped SIMT tensor + // index writes ONLY j=0 and silently drops the other nbasis-1 + // columns (caught by Test_schur_dense_coarse import certificate, + // 2026-08-14). Loop explicitly. + for(int j=0;j &out){assert(0);}; +}; + + + +NAMESPACE_END(Grid); diff --git a/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrixMultiRHS.h b/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrixMultiRHS.h new file mode 100644 index 000000000..292f6f035 --- /dev/null +++ b/Grid/algorithms/multigrid/deprecated/GeneralCoarsenedMatrixMultiRHS.h @@ -0,0 +1,738 @@ +/************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/algorithms/GeneralCoarsenedMatrixMultiRHS.h + + Copyright (C) 2015 + +Author: Peter Boyle + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory +*************************************************************************************/ +/* END LEGAL */ +#pragma once + + +NAMESPACE_BEGIN(Grid); + + +// Fine Object == (per site) type of fine field +// nbasis == number of deflation vectors +template +class MultiGeneralCoarsenedMatrix : public SparseMatrixBase > > { +public: + typedef typename CComplex::scalar_object SComplex; + typedef GeneralCoarsenedMatrix GeneralCoarseOp; + typedef MultiGeneralCoarsenedMatrix MultiGeneralCoarseOp; + + typedef iVector siteVector; + typedef iMatrix siteMatrix; + typedef iVector calcVector; + typedef iMatrix calcMatrix; + typedef Lattice > CoarseComplexField; + typedef Lattice CoarseVector; + typedef Lattice > CoarseMatrix; + typedef iMatrix Cobj; + typedef iVector Cvec; + typedef Lattice< CComplex > CoarseScalar; // used for inner products on fine field + typedef Lattice FineField; + typedef Lattice FineComplexField; + typedef CoarseVector Field; + + //////////////////// + // Data members + //////////////////// + GridCartesian * _CoarseGridMulti; + NonLocalStencilGeometry geom; + NonLocalStencilGeometry geom_srhs; + PaddedCell Cell; + GeneralLocalStencil Stencil; + + deviceVector BLAS_B; + deviceVector BLAS_C; + std::vector > BLAS_A; + + std::vector > BLAS_AP; + std::vector > BLAS_BP; + deviceVector BLAS_CP; + + /////////////////////// + // Interface + /////////////////////// + GridBase * Grid(void) { return _CoarseGridMulti; }; // this is all the linalg routines need to know + GridCartesian * CoarseGrid(void) { return _CoarseGridMulti; }; // this is all the linalg routines need to know + + ////////////////////////////////////////////////////////////////////////// + // Bilingual accessors, matching GeneralCoarsenedMatrix. Grid() here is the + // D+1 multiRHS grid and this class never holds the D dimensional one, so + // ExtractMatrix writes into whatever grid the caller's lattice is on. + ////////////////////////////////////////////////////////////////////////// + NonLocalStencilGeometry & Geometry(void) { return geom_srhs; }; + void ExtractMatrix(int p,CoarseMatrix &A) { BLAStoGrid(A,BLAS_A[p]); }; + + // I/O on the operator matrices, via the BLAS layout array. The parameter is + // a vector over the geometry points; the body indexes A[p]. + void SetMatrix (int p,std::vector & A) + { + GRID_ASSERT(A.size()==geom_srhs.npoint); + GridtoBLAS(A[p],BLAS_A[p]); + } + void GetMatrix (int p,std::vector & A) + { + GRID_ASSERT(A.size()==geom_srhs.npoint); + BLAStoGrid(A[p],BLAS_A[p]); + } + void CopyMatrix (GeneralCoarseOp &_Op) + { + for(int p=0;plSites(); + int32_t unpadded_sites = CoarseGridMulti->lSites(); + + int32_t nrhs = CoarseGridMulti->FullDimensions()[0]; // # RHS + int32_t orhs = nrhs/CComplex::Nsimd(); + + padded_sites = padded_sites/nrhs; + unpadded_sites = unpadded_sites/nrhs; + + ///////////////////////////////////////////////// + // Device data vector storage + ///////////////////////////////////////////////// + BLAS_A.resize(geom.npoint); + for(int p=0;p lSite + GRID_ASSERT(nbr void GridtoBLAS(const Lattice &from,deviceVector &to) + { + typedef typename vobj::scalar_object sobj; + typedef typename vobj::scalar_type scalar_type; + typedef typename vobj::vector_type vector_type; + + GridBase *Fg = from.Grid(); + GRID_ASSERT(!Fg->_isCheckerBoarded); + int nd = Fg->_ndimension; + + to.resize(Fg->lSites()); + + Coordinate LocalLatt = Fg->LocalDimensions(); + size_t nsite = 1; + for(int i=0;i_ostride; + Coordinate f_istride = Fg->_istride; + Coordinate f_rdimensions = Fg->_rdimensions; + + autoView(from_v,from,AcceleratorRead); + auto to_v = &to[0]; + + const int words=sizeof(vobj)/sizeof(vector_type); + accelerator_for(idx,nsite,1,{ + + Coordinate from_coor, base; + Lexicographic::CoorFromIndex(base,idx,LocalLatt); + for(int i=0;i void BLAStoGrid(Lattice &grid,deviceVector &in) + { + typedef typename vobj::scalar_object sobj; + typedef typename vobj::scalar_type scalar_type; + typedef typename vobj::vector_type vector_type; + + GridBase *Tg = grid.Grid(); + GRID_ASSERT(!Tg->_isCheckerBoarded); + int nd = Tg->_ndimension; + + GRID_ASSERT(in.size()==Tg->lSites()); + + Coordinate LocalLatt = Tg->LocalDimensions(); + size_t nsite = 1; + for(int i=0;i_ostride; + Coordinate t_istride = Tg->_istride; + Coordinate t_rdimensions = Tg->_rdimensions; + + autoView(to_v,grid,AcceleratorWrite); + auto from_v = &in[0]; + + const int words=sizeof(vobj)/sizeof(vector_type); + accelerator_for(idx,nsite,1,{ + + Coordinate to_coor, base; + Lexicographic::CoorFromIndex(base,idx,LocalLatt); + for(int i=0;i > &linop, + Aggregation & Subspace, + GridBase *CoarseGrid) + { +#if 0 + std::cout << GridLogMessage<< "GeneralCoarsenMatrixMrhs "<< std::endl; + + GridBase *grid = Subspace.FineGrid; + + ///////////////////////////////////////////////////////////// + // Orthogonalise the subblocks over the basis + ///////////////////////////////////////////////////////////// + CoarseScalar InnerProd(CoarseGrid); + blockOrthogonalise(InnerProd,Subspace.subspace); + + const int npoint = geom_srhs.npoint; + + Coordinate clatt = CoarseGrid->GlobalDimensions(); + int Nd = CoarseGrid->Nd(); + /* + * Here, k,l index which possible momentum/shift within the N-points connected by MdagM. + * Matrix index i is mapped to this shift via + * geom.shifts[i] + * + * conj(pha[block]) proj[k (which mom)][j (basis vec cpt)][block] + * = \sum_{l in ball} e^{i q_k . delta_l} < phi_{block,j} | MdagM | phi_{(block+delta_l),i} > + * = \sum_{l in ball} e^{iqk.delta_l} A_ji^{b.b+l} + * = M_{kl} A_ji^{b.b+l} + * + * Must assemble and invert matrix M_k,l = e^[i q_k . delta_l] + * + * Where q_k = delta_k . (2*M_PI/global_nb[mu]) + * + * Then A{ji}^{b,b+l} = M^{-1}_{lm} ComputeProj_{m,b,i,j} + */ + Eigen::MatrixXcd Mkl = Eigen::MatrixXcd::Zero(npoint,npoint); + Eigen::MatrixXcd invMkl = Eigen::MatrixXcd::Zero(npoint,npoint); + ComplexD ci(0.0,1.0); + for(int k=0;k phaF(npoint,grid); + std::vector pha(npoint,CoarseGrid); + + CoarseVector coarseInner(CoarseGrid); + + typedef typename CComplex::scalar_type SComplex; + FineComplexField one(grid); one=SComplex(1.0); + FineComplexField zz(grid); zz = Zero(); + for(int p=0;p _A; + _A.resize(geom_srhs.npoint,CoarseGrid); + + std::vector ComputeProj(npoint,CoarseGrid); + CoarseVector FT(CoarseGrid); + for(int i=0;ioSites(); + autoView( A_v , _A[k], AcceleratorWrite); + autoView( FT_v , FT, AcceleratorRead); + accelerator_for(sss, osites, 1, { + for(int j=0;j > Projector; + Projector.Allocate(nbasis,grid,CoarseGrid); + Projector.ImportBasis(Subspace.subspace); + + const int npoint = geom_srhs.npoint; + + Coordinate clatt = CoarseGrid->GlobalDimensions(); + int Nd = CoarseGrid->Nd(); + /* + * Here, k,l index which possible momentum/shift within the N-points connected by MdagM. + * Matrix index i is mapped to this shift via + * geom.shifts[i] + * + * conj(pha[block]) proj[k (which mom)][j (basis vec cpt)][block] + * = \sum_{l in ball} e^{i q_k . delta_l} < phi_{block,j} | MdagM | phi_{(block+delta_l),i} > + * = \sum_{l in ball} e^{iqk.delta_l} A_ji^{b.b+l} + * = M_{kl} A_ji^{b.b+l} + * + * Must assemble and invert matrix M_k,l = e^[i q_k . delta_l] + * + * Where q_k = delta_k . (2*M_PI/global_nb[mu]) + * + * Then A{ji}^{b,b+l} = M^{-1}_{lm} ComputeProj_{m,b,i,j} + */ + Eigen::MatrixXcd Mkl = Eigen::MatrixXcd::Zero(npoint,npoint); + Eigen::MatrixXcd invMkl = Eigen::MatrixXcd::Zero(npoint,npoint); + ComplexD ci(0.0,1.0); + for(int k=0;k phaF(npoint,grid); + std::vector pha(npoint,CoarseGrid); + + CoarseVector coarseInner(CoarseGrid); + + tphase=-usecond(); + typedef typename CComplex::scalar_type SComplex; + FineComplexField one(grid); one=SComplex(1.0); + FineComplexField zz(grid); zz = Zero(); + for(int p=0;p _A; + _A.resize(geom_srhs.npoint,CoarseGrid); + + // Count use small chunks than npoint == 81 and save memory + int batch = 9; + std::vector _MphaV(batch,grid); + std::vector TmpProj(batch,CoarseGrid); + + std::vector ComputeProj(npoint,CoarseGrid); + CoarseVector FT(CoarseGrid); + for(int i=0;ioSites(); + autoView( A_v , _A[k], AcceleratorWrite); + autoView( FT_v , FT, AcceleratorRead); + accelerator_for(sss, osites, 1, { + for(int j=0;jM(in,out); + } + void M (const CoarseVector &in, CoarseVector &out) + { + // std::cout << GridLogMessage << "New Mrhs coarse"< Vview; + + const int Nsimd = CComplex::Nsimd(); + + int64_t nrhs =pin.Grid()->GlobalDimensions()[0]; + GRID_ASSERT(nrhs>=1); + + RealD flops,bytes; + int64_t osites=in.Grid()->oSites(); // unpadded + int64_t unpadded_vol = CoarseGrid()->lSites()/nrhs; + + flops = 1.0* npoint * nbasis * nbasis * 8.0 * osites * CComplex::Nsimd(); + bytes = 1.0*osites*sizeof(siteMatrix)*npoint/pin.Grid()->GlobalDimensions()[0] + + 2.0*osites*sizeof(siteVector)*npoint; + + + t_GtoB=-usecond(); + GridtoBLAS(pin,BLAS_B); + t_GtoB+=usecond(); + + GridBLAS BLAS; + + t_mult=-usecond(); + for(int p=0;p &out){assert(0);}; +}; + +NAMESPACE_END(Grid); diff --git a/Grid/algorithms/multigrid/deprecated/TwoLevelADEF2.h b/Grid/algorithms/multigrid/deprecated/TwoLevelADEF2.h new file mode 100644 index 000000000..52ff3e851 --- /dev/null +++ b/Grid/algorithms/multigrid/deprecated/TwoLevelADEF2.h @@ -0,0 +1,136 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./Grid/algorithms/multigrid/deprecated/TwoLevelADEF2.h + + Copyright (C) 2015 + +Author: Peter Boyle + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + See the full license in the file "LICENSE" in the top level distribution directory + *************************************************************************************/ + /* END LEGAL */ +#pragma once + +// DEPRECATED with the V1 coarse operators: the single-RHS ADEF-2 on an +// Aggregation (ProjectToSubspace/PromoteFromSubspace) and a D-dimensional +// coarse operator. The mrhs solver in AdefMrhs.h covers one right-hand +// side through its LinearFunction interface, on the V2 coarse operator. + +NAMESPACE_BEGIN(Grid); + +template +class TwoLevelADEF2 : public TwoLevelCG +{ + public: + /////////////////////////////////////////////////////////////////////////////////// + // Need something that knows how to get from Coarse to fine and back again + // void ProjectToSubspace(CoarseVector &CoarseVec,const FineField &FineVec){ + // void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){ + /////////////////////////////////////////////////////////////////////////////////// + GridBase *coarsegrid; + Aggregation &_Aggregates; + LinearFunction &_CoarseSolver; + LinearFunction &_CoarseSolverPrecise; + /////////////////////////////////////////////////////////////////////////////////// + + // more most opertor functions + TwoLevelADEF2(RealD tol, + Integer maxit, + LinearOperatorBase &FineLinop, + LinearFunction &Smoother, + LinearFunction &CoarseSolver, + LinearFunction &CoarseSolverPrecise, + Aggregation &Aggregates + ) : + TwoLevelCG(tol,maxit,FineLinop,Smoother,Aggregates.FineGrid), + _CoarseSolver(CoarseSolver), + _CoarseSolverPrecise(CoarseSolverPrecise), + _Aggregates(Aggregates) + { + coarsegrid = Aggregates.CoarseGrid; + }; + + virtual void PcgM1(Field & in, Field & out) + { + GRID_TRACE("MultiGridPreconditioner "); + // [PTM+Q] in = [1 - Q A] M in + Q in = Min + Q [ in -A Min] + + Field tmp(this->grid); + Field Min(this->grid); + CoarseField PleftProj(this->coarsegrid); + CoarseField PleftMss_proj(this->coarsegrid); + + this->SmoothTimer.Start(); + this->_Smoother(in,Min); + this->SmoothTimer.Stop(); + this->SmoothCalls++; + + this->MatrixTimer.Start(); + this->_FineLinop.HermOp(Min,out); + this->MatrixTimer.Stop(); + this->MatrixCalls++; + axpy(tmp,-1.0,out,in); // tmp = in - A Min + + this->ProjectTimer.Start(); + this->_Aggregates.ProjectToSubspace(PleftProj,tmp); + this->ProjectTimer.Stop(); + this->ProjectCalls++; + this->CoarseTimer.Start(); + this->_CoarseSolver(PleftProj,PleftMss_proj); // Ass^{-1} [in - A Min]_s + this->CoarseTimer.Stop(); + this->CoarseCalls++; + this->PromoteTimer.Start(); + this->_Aggregates.PromoteFromSubspace(PleftMss_proj,tmp);// tmp = Q[in - A Min] + this->PromoteTimer.Stop(); + this->PromoteCalls++; + + axpy(out,1.0,Min,tmp); // Min+tmp + } + + virtual void Vstart(Field & x,const Field & src) + { + std::cout << GridLogMessage<<"HDCG: fPcg Vstart "<grid); + Field mmp(this->grid); + CoarseField PleftProj(this->coarsegrid); + CoarseField PleftMss_proj(this->coarsegrid); + + std::cout << GridLogMessage<<"HDCG: fPcg Vstart projecting "<_Aggregates.ProjectToSubspace(PleftProj,src); + std::cout << GridLogMessage<<"HDCG: fPcg Vstart coarse solve "<_CoarseSolverPrecise(PleftProj,PleftMss_proj); // Ass^{-1} r_s + std::cout << GridLogMessage<<"HDCG: fPcg Vstart promote "<_Aggregates.PromoteFromSubspace(PleftMss_proj,x); + + } + +}; + +NAMESPACE_END(Grid);