mirror of
https://github.com/paboyle/Grid.git
synced 2026-08-24 03:19:35 +01:00
Benchmark comms with the exact sequence in Stencil as it is now.
This commit is contained in:
@@ -252,6 +252,131 @@ int main (int argc, char ** argv)
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Halo exchange through the PRODUCTION stencil path.
|
||||
//
|
||||
// Prepare -> PollDtoH -> CopySynchronise -> Begin -> PollIRecv -> Complete
|
||||
//
|
||||
// verbatim as CartesianStencil::CommunicateBegin/Complete drive it, so this
|
||||
// measures the code that actually runs inside the Dslash rather than a
|
||||
// simplified stand-in built on SendToRecvFrom.
|
||||
//
|
||||
// THREE byte counts are reported, because they differ and conflating them
|
||||
// has already produced an impossible number (272 GB/s/node against a
|
||||
// 200 GB/s wire):
|
||||
//
|
||||
// offered : the whole halo this rank presents, all 8 directions.
|
||||
// off-node : the subset whose partner is on another node, classified
|
||||
// GEOMETRICALLY via IsOffNode() -- independent of --shm-mpi.
|
||||
// to-MPI : what StencilSendToRecvFrom{Prepare,Begin} actually handed to
|
||||
// MPI, i.e. their return value, exactly as the Stencil counts
|
||||
// it. Under --shm-mpi 1 Grid delegates intranode transfers to
|
||||
// MPI as well, so this approaches "offered"; under --shm-mpi 0
|
||||
// Grid moves them itself and this approaches "off-node".
|
||||
//
|
||||
// Only the off-node column may be compared against wire speed.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||
std::cout<<GridLogMessage << "= Benchmarking STENCIL-PATH halo exchange from GPU memory "<<std::endl;
|
||||
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||
std::cout<<GridLogMessage << " L Ls offered off-node to-MPI time off-node to-MPI"<<std::endl;
|
||||
std::cout<<GridLogMessage << " MB/nd MB/nd MB/nd us/call GB/s/nd GB/s/nd"<<std::endl;
|
||||
|
||||
for(int lat=8;lat<=maxlat;lat+=4){
|
||||
for(int Ls=8;Ls<=8;Ls*=2){
|
||||
|
||||
Coordinate latt_size ({lat*mpi_layout[0],
|
||||
lat*mpi_layout[1],
|
||||
lat*mpi_layout[2],
|
||||
lat*mpi_layout[3]});
|
||||
|
||||
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
|
||||
RealD Nrank = Grid._Nprocessors;
|
||||
RealD Nnode = Grid.NodeCount();
|
||||
|
||||
uint64_t bytes = (uint64_t)lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD);
|
||||
|
||||
std::vector<HalfSpinColourVectorD *> xbuf(8), rbuf(8);
|
||||
for(int d=0;d<8;d++){
|
||||
xbuf[d] = (HalfSpinColourVectorD *)acceleratorAllocDevice(bytes);
|
||||
rbuf[d] = (HalfSpinColourVectorD *)acceleratorAllocDevice(bytes);
|
||||
}
|
||||
|
||||
// Packet table in the same shape the Stencil builds: 8 directions,
|
||||
// to/from ranks from ShiftedRanks, participation gated on mpi_layout.
|
||||
// COMPACT packet list, exactly as the Stencil builds it: only the
|
||||
// directions that actually communicate get a packet. Passing a
|
||||
// self-send with do_send=0 is not equivalent -- the assert
|
||||
// "dest != _processor" in StencilSendToRecvFromBegin is unconditional.
|
||||
std::vector<int> to_rank, from_rank, buf_id;
|
||||
double offered = 0.0, offnode = 0.0;
|
||||
for(int mu=0;mu<4;mu++){
|
||||
if ( mpi_layout[mu] > 1 ) {
|
||||
int s,d;
|
||||
Grid.ShiftedRanks(mu,+1,s,d); to_rank.push_back(d); from_rank.push_back(s); buf_id.push_back(mu);
|
||||
Grid.ShiftedRanks(mu,-1,s,d); to_rank.push_back(d); from_rank.push_back(s); buf_id.push_back(mu+4);
|
||||
}
|
||||
}
|
||||
int npkt = to_rank.size();
|
||||
for(int i=0;i<npkt;i++){
|
||||
offered += 2.0*bytes; // send + receive
|
||||
if ( Grid.IsOffNode(to_rank[i]) ) offnode += 2.0*bytes;
|
||||
}
|
||||
|
||||
double mpibytes = 0.0, t = 0.0;
|
||||
std::vector<CommsRequest_t> reqs;
|
||||
|
||||
for(int n=0;n<Nloop;n++){
|
||||
reqs.resize(0);
|
||||
double mb = 0.0;
|
||||
Grid.StencilBarrier();
|
||||
double t0=usecond();
|
||||
for(int i=0;i<npkt;i++){
|
||||
mb += Grid.StencilSendToRecvFromPrepare(reqs,
|
||||
(void *)xbuf[buf_id[i]], to_rank[i], 1,
|
||||
(void *)rbuf[buf_id[i]], from_rank[i], 1,
|
||||
bytes,bytes,i);
|
||||
}
|
||||
Grid.StencilSendToRecvFromPollDtoH(reqs); /* Starts MPI */
|
||||
acceleratorCopySynchronise();
|
||||
for(int i=0;i<npkt;i++){
|
||||
// xmit and xmit_comp identical: no compression in this benchmark
|
||||
mb += Grid.StencilSendToRecvFromBegin(reqs,
|
||||
(void *)xbuf[buf_id[i]],(void *)xbuf[buf_id[i]], to_rank[i], 1,
|
||||
(void *)rbuf[buf_id[i]],(void *)rbuf[buf_id[i]], from_rank[i], 1,
|
||||
bytes,bytes,i);
|
||||
}
|
||||
Grid.StencilSendToRecvFromPollIRecv(reqs);
|
||||
Grid.StencilSendToRecvFromComplete(reqs,0);
|
||||
t += usecond()-t0;
|
||||
mpibytes += mb;
|
||||
}
|
||||
|
||||
// Sum bytes over the machine, average the time over ranks, report per
|
||||
// node. Reduced once, outside the timed region. bytes/us == MB/s.
|
||||
double sumMpi = mpibytes; Grid.GlobalSum(sumMpi);
|
||||
double sumOff = offnode*Nloop; Grid.GlobalSum(sumOff);
|
||||
double sumAll = offered*Nloop; Grid.GlobalSum(sumAll);
|
||||
double sumT = t; Grid.GlobalSum(sumT);
|
||||
double avgT = sumT/Nrank;
|
||||
|
||||
std::cout<<GridLogMessage
|
||||
<< std::setw(4) << lat <<" "<< std::setw(4) << Ls
|
||||
<<" "<< std::setw(9) << sumAll/Nloop/Nnode/1.0e6
|
||||
<<" "<< std::setw(9) << sumOff/Nloop/Nnode/1.0e6
|
||||
<<" "<< std::setw(9) << sumMpi/Nloop/Nnode/1.0e6
|
||||
<<" "<< std::setw(9) << avgT/Nloop
|
||||
<<" "<< std::setw(8) << sumOff/avgT/Nnode/1000.0
|
||||
<<" "<< std::setw(8) << sumMpi/avgT/Nnode/1000.0
|
||||
<<std::endl;
|
||||
|
||||
for(int d=0;d<8;d++){
|
||||
acceleratorFreeDevice(xbuf[d]);
|
||||
acceleratorFreeDevice(rbuf[d]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||
std::cout<<GridLogMessage << "= All done; Bye Bye"<<std::endl;
|
||||
std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
|
||||
|
||||
Reference in New Issue
Block a user