From f18320a152b54482e1a31b1a56e26f9a6e821c0a Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Tue, 11 Aug 2026 16:30:16 -0400 Subject: [PATCH] GeneralCoarsenedMatrix speed up -- same optimisations for fast calculation used by GeneralCoarsenedMatrixMultiRHS --- .../multigrid/GeneralCoarsenedMatrix.h | 182 +++++++++++------- 1 file changed, 113 insertions(+), 69 deletions(-) diff --git a/Grid/algorithms/multigrid/GeneralCoarsenedMatrix.h b/Grid/algorithms/multigrid/GeneralCoarsenedMatrix.h index 3ba145db4..002b220d3 100644 --- a/Grid/algorithms/multigrid/GeneralCoarsenedMatrix.h +++ b/Grid/algorithms/multigrid/GeneralCoarsenedMatrix.h @@ -31,6 +31,7 @@ Author: Peter Boyle #include #include +#include NAMESPACE_BEGIN(Grid); @@ -66,6 +67,10 @@ public: std::vector _Adag; std::vector MultTemporaries; + int64_t MultCalls; + double MultFlopsAccum; + double MultUsecAccum; + /////////////////////// // Interface /////////////////////// @@ -104,19 +109,20 @@ public: } */ - GeneralCoarsenedMatrix(NonLocalStencilGeometry &_geom,GridBase *FineGrid, GridCartesian * CoarseGrid) + GeneralCoarsenedMatrix(NonLocalStencilGeometry &_geom,GridBase *FineGrid, GridCartesian * CoarseGrid,int _herm=1) : geom(_geom), _FineGrid(FineGrid), _CoarseGrid(CoarseGrid), - hermitian(1), + hermitian(_herm), Cell(_geom.Depth(),_CoarseGrid), - Stencil(Cell.grids.back(),geom.shifts) + Stencil(Cell.grids.back(),geom.shifts), + MultCalls(0), MultFlopsAccum(0.0), MultUsecAccum(0.0) { { int npoint = _geom.npoint; } _A.resize(geom.npoint,CoarseGrid); - // _Adag.resize(geom.npoint,CoarseGrid); + if ( !hermitian ) _Adag.resize(geom.npoint,CoarseGrid); } void M (const CoarseVector &in, CoarseVector &out) { @@ -124,10 +130,10 @@ public: } void Mdag (const CoarseVector &in, CoarseVector &out) { - GRID_ASSERT(hermitian); - Mult(_A,in,out); - // if ( hermitian ) M(in,out); - // else Mult(_Adag,in,out); + if(hermitian) + Mult(_A,in,out); + else + Mult(_Adag,in,out); } void Mult (std::vector &A,const CoarseVector &in, CoarseVector &out) { @@ -227,29 +233,28 @@ public: text+=usecond(); ttot+=usecond(); - std::cout << GridLogPerformance<<"Coarse 1rhs Mult Aviews "<gSites() ;bidx++){ Coordinate bcoor; CoarseGrid()->GlobalIndexToGlobalCoor(bidx,bcoor); - + 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 } ///////////////////////////////////////////////////////////// // @@ -417,10 +452,9 @@ public: int osites=CoarseGrid()->oSites(); autoView( A_v , _A[k], AcceleratorWrite); autoView( FT_v , FT[k], AcceleratorRead); - accelerator_for(sss, osites, 1, { - for(int j=0;j 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(); @@ -542,37 +572,52 @@ public: pha[p] =exp(pha[p]*ci); blockZAXPY(phaF[p],pha[p],one,zz); - + } tphase+=usecond(); - - std::vector ComputeProj(npoint,CoarseGrid()); - std::vector FT(npoint,CoarseGrid()); + + // Import basis into BLAS layout once; blockProject then reads it once per + // basis vector rather than once per (i,p) as in scalar blockProject. + // Process all npoint in a single batch. + MultiRHSBlockProject 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, 1, { - for(int j=0;j