/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./tests/debug/Test_mrhs_blockproject_import.cc Copyright (C) 2026 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 */ // // ImportFineGridMrhsVectors / ExportCoarseGridMrhsVectors against the vector // of single RHS routines they replace. The BLAS buffers must come out // identical, so the mrhs path is a pure removal of the unpack and repack. // #include using namespace Grid; const int nbasis = 8; const int nrhs = 4; typedef LatticeFermionD FineField; typedef iVector CoarseSiteObj; // unvectorised coarse space typedef Lattice CoarseField; template RealD BufDiff(deviceVector &a,deviceVector &b) { GRID_ASSERT(a.size()==b.size()); std::vector ha(a.size()),hb(b.size()); acceleratorCopyFromDevice(&a[0],&ha[0],a.size()*sizeof(T)); acceleratorCopyFromDevice(&b[0],&hb[0],b.size()*sizeof(T)); RealD num=0.0; for(int64_t i=0;i RealD BufNorm(deviceVector &a) { std::vector ha(a.size()); acceleratorCopyFromDevice(&a[0],&ha[0],a.size()*sizeof(T)); RealD num=0.0; for(int64_t i=0;iNsimd()<<" coarse Nsimd "<Nsimd()<({1,2,3,4})); MultiRHSBlockProject Projector; Projector.Allocate(nbasis,FineGrid,CoarseGrid); /////////////////////////////////////////////////////// // Same data as nrhs single RHS fields and as one D+1 /////////////////////////////////////////////////////// std::vector vecs(nrhs,FineGrid); FineField mrhs(FineMulti); for(int r=0;rlSites()*Projector.words*nrhs; deviceVector Fa(fsz), Fb(fsz); Projector.ImportFineGridVectors (vecs,Fa); Projector.ImportFineGridMrhsVectors(mrhs,Fb); RealD fn = BufNorm(Fa); RealD fd = BufDiff(Fa,Fb); std::cout << GridLogMessage << "fine import |vector|^2 = " << fn << " |vector - mrhs|^2 = " << fd << std::endl; GRID_ASSERT( fn > 0.0 ); GRID_ASSERT( fd == 0.0 ); /////////////////////////////////////////////////////// // Coarse export: fill the BLAS buffer, read it back // both ways, and compare the resulting fields /////////////////////////////////////////////////////// int64_t csz = CoarseGrid->lSites()*nbasis*nrhs; deviceVector Cbuf(csz); { std::vector host(csz); GridSerialRNG sRNG; sRNG.SeedFixedIntegers(std::vector({9,8,7,6})); for(int64_t i=0;i cvecs(nrhs,CoarseGrid); CoarseField cmrhs(CoarseMulti); Projector.ExportCoarseGridVectors (cvecs,Cbuf); Projector.ExportCoarseGridMrhsVectors(cmrhs,Cbuf); RealD cn=0.0, cd=0.0; for(int r=0;rvec|^2 = " << ref << std::endl; std::cout << GridLogMessage << " mrhs->vec diff " << d_mv << " vec->mrhs diff " << d_vm << " mrhs->mrhs diff " << d_mm << std::endl; GRID_ASSERT( ref > 0.0 ); GRID_ASSERT( d_mv == 0.0 ); GRID_ASSERT( d_vm == 0.0 ); GRID_ASSERT( d_mm == 0.0 ); /////////////////////////////////////////////////////// // Promote must agree across orderings too /////////////////////////////////////////////////////// std::vector fvv(nrhs,FineGrid); FineField fmm(FineMulti); Projector.blockPromote(fvv,cvv); Projector.blockPromote(fmm,cmm); RealD pref=0.0, pdiff=0.0; for(int r=0;r 0.0 ); GRID_ASSERT( pdiff == 0.0 ); } std::cout << GridLogMessage << "Test_mrhs_blockproject_import: ALL PASS" << std::endl; Grid_finalize(); }