mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Overlap comms compute changes
This commit is contained in:
		
							
								
								
									
										274
									
								
								lib/Stencil.h
									
									
									
									
									
								
							
							
						
						
									
										274
									
								
								lib/Stencil.h
									
									
									
									
									
								
							@@ -7,8 +7,6 @@
 | 
				
			|||||||
    Copyright (C) 2015
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
					 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					    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
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
@@ -88,11 +86,78 @@ namespace Grid {
 | 
				
			|||||||
      typedef typename cobj::scalar_type scalar_type;
 | 
					      typedef typename cobj::scalar_type scalar_type;
 | 
				
			||||||
      typedef typename cobj::scalar_object scalar_object;
 | 
					      typedef typename cobj::scalar_object scalar_object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      //////////////////////////////////////////
 | 
				
			||||||
 | 
					      // Comms packet queue for asynch thread
 | 
				
			||||||
 | 
					      //////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      struct Packet {
 | 
				
			||||||
 | 
						void * send_buf;
 | 
				
			||||||
 | 
						void * recv_buf;
 | 
				
			||||||
 | 
						Integer to_rank;
 | 
				
			||||||
 | 
						Integer from_rank;
 | 
				
			||||||
 | 
						Integer bytes;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::vector<Packet> Packets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void AddPacket(void *xmit,void * rcv, Integer to,Integer from,Integer bytes){
 | 
				
			||||||
 | 
						Packet p;
 | 
				
			||||||
 | 
						p.send_buf = xmit;
 | 
				
			||||||
 | 
						p.recv_buf = rcv;
 | 
				
			||||||
 | 
						p.to_rank  = to;
 | 
				
			||||||
 | 
						p.from_rank= from;
 | 
				
			||||||
 | 
						p.bytes    = bytes;
 | 
				
			||||||
 | 
						Packets.push_back(p);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void Communicate(void ) { 
 | 
				
			||||||
 | 
						for(int i=0;i<Packets.size();i++){
 | 
				
			||||||
 | 
						  _grid->SendToRecvFrom(Packets[i].send_buf,
 | 
				
			||||||
 | 
									Packets[i].to_rank,
 | 
				
			||||||
 | 
									Packets[i].recv_buf,
 | 
				
			||||||
 | 
									Packets[i].from_rank,
 | 
				
			||||||
 | 
									Packets[i].bytes);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ///////////////////////////////////////////
 | 
				
			||||||
 | 
					      // Simd merge queue for asynch comms
 | 
				
			||||||
 | 
					      ///////////////////////////////////////////
 | 
				
			||||||
 | 
					      struct Merge {
 | 
				
			||||||
 | 
					        cobj * mpointer;
 | 
				
			||||||
 | 
						std::vector<scalar_object *> rpointers;
 | 
				
			||||||
 | 
						Integer buffer_size;
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::vector<Merge> Mergers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void AddMerge(cobj *merge_p,std::vector<scalar_object *> &rpointers,Integer buffer_size) {
 | 
				
			||||||
 | 
						Merge m;
 | 
				
			||||||
 | 
						m.mpointer = merge_p;
 | 
				
			||||||
 | 
						m.rpointers= rpointers;
 | 
				
			||||||
 | 
						m.buffer_size = buffer_size;
 | 
				
			||||||
 | 
						Mergers.push_back(m);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      void CommsMerge(void ) { 
 | 
				
			||||||
 | 
						mergetime-=usecond();
 | 
				
			||||||
 | 
						for(int i=0;i<Mergers.size();i++){	
 | 
				
			||||||
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
						  for(int o=0;o<Mergers[i].buffer_size;o++){
 | 
				
			||||||
 | 
						    merge(Mergers[i].mpointer[o],Mergers[i].rpointers,o);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mergetime+=usecond();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ////////////////////////////////////////
 | 
				
			||||||
 | 
					      // Basic Grid and stencil info
 | 
				
			||||||
 | 
					      ////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      int                               _checkerboard;
 | 
					      int                               _checkerboard;
 | 
				
			||||||
      int                               _npoints; // Move to template param?
 | 
					      int                               _npoints; // Move to template param?
 | 
				
			||||||
      GridBase *                        _grid;
 | 
					      GridBase *                        _grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
      // npoints of these
 | 
					      // npoints of these
 | 
				
			||||||
      std::vector<int>                  _directions;
 | 
					      std::vector<int>                  _directions;
 | 
				
			||||||
      std::vector<int>                  _distances;
 | 
					      std::vector<int>                  _distances;
 | 
				
			||||||
@@ -101,19 +166,21 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      // npoints x Osites() of these
 | 
					      // npoints x Osites() of these
 | 
				
			||||||
      std::vector<std::vector<StencilEntry> > _entries;
 | 
					      std::vector<std::vector<StencilEntry> > _entries;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Comms buffers
 | 
					 | 
				
			||||||
      std::vector<std::vector<scalar_object> > send_buf_extract;
 | 
					 | 
				
			||||||
      std::vector<std::vector<scalar_object> > recv_buf_extract;
 | 
					 | 
				
			||||||
      std::vector<scalar_object *> pointers;
 | 
					 | 
				
			||||||
      std::vector<scalar_object *> rpointers;
 | 
					 | 
				
			||||||
      Vector<cobj> send_buf;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      inline StencilEntry * GetEntry(int &ptype,int point,int osite) { ptype = _permute_type[point]; return & _entries[point][osite]; }
 | 
					      inline StencilEntry * GetEntry(int &ptype,int point,int osite) { ptype = _permute_type[point]; return & _entries[point][osite]; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Comms buffers
 | 
				
			||||||
 | 
					      std::vector<Vector<scalar_object> > u_simd_send_buf;
 | 
				
			||||||
 | 
					      std::vector<Vector<scalar_object> > u_simd_recv_buf;
 | 
				
			||||||
 | 
					      Vector<cobj>          u_send_buf;
 | 
				
			||||||
 | 
					      Vector<cobj>          comm_buf;
 | 
				
			||||||
 | 
					      int u_comm_offset;
 | 
				
			||||||
      int _unified_buffer_size;
 | 
					      int _unified_buffer_size;
 | 
				
			||||||
      int _request_count;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /////////////////////////////////////////
 | 
				
			||||||
 | 
					      // Timing info; ugly; possibly temporary
 | 
				
			||||||
 | 
					      /////////////////////////////////////////
 | 
				
			||||||
 | 
					#define TIMING_HACK
 | 
				
			||||||
 | 
					#ifdef TIMING_HACK
 | 
				
			||||||
      double buftime;
 | 
					      double buftime;
 | 
				
			||||||
      double gathertime;
 | 
					      double gathertime;
 | 
				
			||||||
      double commtime;
 | 
					      double commtime;
 | 
				
			||||||
@@ -124,9 +191,7 @@ namespace Grid {
 | 
				
			|||||||
      double gathermtime;
 | 
					      double gathermtime;
 | 
				
			||||||
      double splicetime;
 | 
					      double splicetime;
 | 
				
			||||||
      double nosplicetime;
 | 
					      double nosplicetime;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CartesianStencil(GridBase *grid,
 | 
					  CartesianStencil(GridBase *grid,
 | 
				
			||||||
				     int npoints,
 | 
									     int npoints,
 | 
				
			||||||
@@ -135,6 +200,7 @@ namespace Grid {
 | 
				
			|||||||
				     const std::vector<int> &distances) 
 | 
									     const std::vector<int> &distances) 
 | 
				
			||||||
    :   _entries(npoints), _permute_type(npoints), _comm_buf_size(npoints)
 | 
					    :   _entries(npoints), _permute_type(npoints), _comm_buf_size(npoints)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef TIMING_HACK
 | 
				
			||||||
      gathertime=0;
 | 
					      gathertime=0;
 | 
				
			||||||
      commtime=0;
 | 
					      commtime=0;
 | 
				
			||||||
      commstime=0;
 | 
					      commstime=0;
 | 
				
			||||||
@@ -145,13 +211,12 @@ namespace Grid {
 | 
				
			|||||||
      buftime=0;
 | 
					      buftime=0;
 | 
				
			||||||
      splicetime=0;
 | 
					      splicetime=0;
 | 
				
			||||||
      nosplicetime=0;
 | 
					      nosplicetime=0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
      _npoints = npoints;
 | 
					      _npoints = npoints;
 | 
				
			||||||
      _grid    = grid;
 | 
					      _grid    = grid;
 | 
				
			||||||
      _directions = directions;
 | 
					      _directions = directions;
 | 
				
			||||||
      _distances  = distances;
 | 
					      _distances  = distances;
 | 
				
			||||||
      _unified_buffer_size=0;
 | 
					      _unified_buffer_size=0;
 | 
				
			||||||
      _request_count =0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      int osites  = _grid->oSites();
 | 
					      int osites  = _grid->oSites();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,22 +262,25 @@ namespace Grid {
 | 
				
			|||||||
	  sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd);
 | 
						  sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  if ( sshift[0] == sshift[1] ) {
 | 
						  if ( sshift[0] == sshift[1] ) {
 | 
				
			||||||
	    //	    std::cout<<"Comms 0x3"<<std::endl;
 | 
					 | 
				
			||||||
	    Comms(point,dimension,shift,0x3);
 | 
						    Comms(point,dimension,shift,0x3);
 | 
				
			||||||
	  } else {
 | 
						  } else {
 | 
				
			||||||
	    //	    std::cout<<"Comms 0x1 ; 0x2"<<std::endl;
 | 
					 | 
				
			||||||
	    Comms(point,dimension,shift,0x1);// if checkerboard is unfavourable take two passes
 | 
						    Comms(point,dimension,shift,0x1);// if checkerboard is unfavourable take two passes
 | 
				
			||||||
	    Comms(point,dimension,shift,0x2);// both with block stride loop iteration
 | 
						    Comms(point,dimension,shift,0x2);// both with block stride loop iteration
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//	for(int ss=0;ss<osites;ss++){
 | 
					      }
 | 
				
			||||||
	//	  std::cout << "point["<<i<<"] "<<ss<<"-> o"<<_entries[i][ss]._offset<<"; l"<<
 | 
					      u_send_buf.resize(_unified_buffer_size);
 | 
				
			||||||
	//	    _entries[i][ss]._is_local<<"; p"<<_entries[i][ss]._permute<<std::endl;
 | 
					      comm_buf.resize(_unified_buffer_size);
 | 
				
			||||||
	//	}
 | 
					      
 | 
				
			||||||
 | 
					      const int Nsimd = grid->Nsimd();
 | 
				
			||||||
 | 
					      u_simd_send_buf.resize(Nsimd);
 | 
				
			||||||
 | 
					      u_simd_recv_buf.resize(Nsimd);
 | 
				
			||||||
 | 
					      for(int l=0;l<Nsimd;l++){
 | 
				
			||||||
 | 
						u_simd_send_buf[l].resize(_unified_buffer_size);
 | 
				
			||||||
 | 
						u_simd_recv_buf[l].resize(_unified_buffer_size);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Local     (int point, int dimension,int shiftpm,int cbmask)
 | 
					    void Local     (int point, int dimension,int shiftpm,int cbmask)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      int fd = _grid->_fdimensions[dimension];
 | 
					      int fd = _grid->_fdimensions[dimension];
 | 
				
			||||||
@@ -276,17 +344,15 @@ namespace Grid {
 | 
				
			|||||||
      assert(shift<fd);
 | 
					      assert(shift<fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension]; // done in reduced dims, so SIMD factored
 | 
					      int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension]; // done in reduced dims, so SIMD factored
 | 
				
			||||||
      //      std::cout << " dim " <<dimension<<" buffersize "<<buffer_size<<std::endl;
 | 
					
 | 
				
			||||||
      _comm_buf_size[point] = buffer_size; // Size of _one_ plane. Multiple planes may be gathered and
 | 
					      _comm_buf_size[point] = buffer_size; // Size of _one_ plane. Multiple planes may be gathered and
 | 
				
			||||||
                                           // send to one or more remote nodes.
 | 
					                                           // send to one or more remote nodes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      int cb= (cbmask==0x2)? Odd : Even;
 | 
					      int cb= (cbmask==0x2)? Odd : Even;
 | 
				
			||||||
      int sshift= _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,cb);
 | 
					      int sshift= _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,cb);
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for(int x=0;x<rd;x++){       
 | 
					      for(int x=0;x<rd;x++){       
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	int permute_type=grid->PermuteType(dimension);
 | 
						int permute_type=grid->PermuteType(dimension);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int sx        =  (x+sshift)%rd;
 | 
						int sx        =  (x+sshift)%rd;
 | 
				
			||||||
@@ -310,16 +376,9 @@ namespace Grid {
 | 
				
			|||||||
	} else { 
 | 
						} else { 
 | 
				
			||||||
	  int comm_proc = ((x+sshift)/rd)%pd;
 | 
						  int comm_proc = ((x+sshift)/rd)%pd;
 | 
				
			||||||
	  offnode = (comm_proc!= 0);
 | 
						  offnode = (comm_proc!= 0);
 | 
				
			||||||
	  //	  std::cout << "Stencil x "<<x<<" shift "<<shift<<" sshift "<<sshift<<" fd "<<fd<<" rd " <<rd<<" offnode "<<offnode<<" sx "<<sx<< " comm_proc "<<comm_proc<<" pd "<< pd <<std::endl;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Stencil x 1 shift 3 sshift 3 fd 8 rd 2 offnode 0 sx 0 comm_proc 0 pd 2
 | 
					 | 
				
			||||||
	// x+sshift = 4
 | 
					 | 
				
			||||||
	// x+sshift/2 = 2
 | 
					 | 
				
			||||||
	// 2%2 == 0
 | 
					 | 
				
			||||||
	// Problem: sshift is wrong in "rd" for SIMD directions. The complex logic in Cshift_mpi is needed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int wraparound=0;
 | 
						int wraparound=0;
 | 
				
			||||||
	if ( (shiftpm==-1) && (sx>x) && (grid->_processor_coor[dimension]==0) ) {
 | 
						if ( (shiftpm==-1) && (sx>x) && (grid->_processor_coor[dimension]==0) ) {
 | 
				
			||||||
	  wraparound = 1;
 | 
						  wraparound = 1;
 | 
				
			||||||
@@ -337,15 +396,13 @@ namespace Grid {
 | 
				
			|||||||
	  int words = buffer_size;
 | 
						  int words = buffer_size;
 | 
				
			||||||
	  if (cbmask != 0x3) words=words>>1;
 | 
						  if (cbmask != 0x3) words=words>>1;
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  //	  GatherPlaneSimple (point,dimension,sx,cbmask);
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  int rank           = grid->_processor;
 | 
						  int rank           = grid->_processor;
 | 
				
			||||||
	  int recv_from_rank;
 | 
						  int recv_from_rank;
 | 
				
			||||||
	  int xmit_to_rank;
 | 
						  int xmit_to_rank;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  int unified_buffer_offset = _unified_buffer_size;
 | 
						  int unified_buffer_offset = _unified_buffer_size;
 | 
				
			||||||
	  _unified_buffer_size    += words;
 | 
						  _unified_buffer_size    += words;
 | 
				
			||||||
	  //	  std::cout<< "Comms dim "<<dimension<<" offset "<<unified_buffer_offset<<" size "<<" " << _unified_buffer_size<<std::endl;
 | 
					
 | 
				
			||||||
	  ScatterPlane(point,dimension,x,cbmask,unified_buffer_offset,wraparound); // permute/extract/merge is done in comms phase
 | 
						  ScatterPlane(point,dimension,x,cbmask,unified_buffer_offset,wraparound); // permute/extract/merge is done in comms phase
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -441,39 +498,34 @@ namespace Grid {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//      CartesianStencil(GridBase *grid,
 | 
					 | 
				
			||||||
//		       int npoints,
 | 
					 | 
				
			||||||
//		       int checkerboard,
 | 
					 | 
				
			||||||
//		       const std::vector<int> &directions,
 | 
					 | 
				
			||||||
//		       const std::vector<int> &distances);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::thread HaloExchangeBegin(const Lattice<vobj> &source,compressor &compress) {
 | 
				
			||||||
 | 
						Mergers.resize(0); 
 | 
				
			||||||
 | 
						Packets.resize(0);
 | 
				
			||||||
 | 
						HaloGather(source,compress);
 | 
				
			||||||
 | 
					        return std::thread([&] { this->Communicate(); });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Add to tables for various cases;  is this mistaken. only local if 1 proc in dim
 | 
					      void HaloExchange(const Lattice<vobj> &source,compressor &compress) 
 | 
				
			||||||
      // Can this be avoided with simpler coding of comms?
 | 
					      {
 | 
				
			||||||
   //      void Local     (int point, int dimension,int shift,int cbmask);
 | 
						auto thr = HaloExchangeBegin(source,compress);
 | 
				
			||||||
   //      void Comms     (int point, int dimension,int shift,int cbmask);
 | 
					        HaloExchangeComplete(thr);
 | 
				
			||||||
   //      void CopyPlane(int point, int dimension,int lplane,int rplane,int cbmask,int permute,int wrap);
 | 
					      }
 | 
				
			||||||
   //      void ScatterPlane (int point,int dimension,int plane,int cbmask,int offset,int wrap);
 | 
					
 | 
				
			||||||
 | 
					      void HaloExchangeComplete(std::thread &thr) 
 | 
				
			||||||
      // Could allow a functional munging of the halo to another type during the comms.
 | 
					 | 
				
			||||||
      // this could implement the 16bit/32bit/64bit compression.
 | 
					 | 
				
			||||||
      void HaloExchange(const Lattice<vobj> &source,std::vector<cobj,alignedAllocator<cobj> > &u_comm_buf,compressor &compress) 
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
	std::thread thr = HaloExchangeBegin(source,u_comm_buf,compress);
 | 
					 | 
				
			||||||
	thr.join();
 | 
						thr.join();
 | 
				
			||||||
 | 
						CommsMerge();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      std::thread HaloExchangeBegin(const Lattice<vobj> &source,std::vector<cobj,alignedAllocator<cobj> > & u_comm_buf,compressor &compress) {
 | 
					      void HaloGather(const Lattice<vobj> &source,compressor &compress)
 | 
				
			||||||
	return std::thread([&] { this->HaloExchangeBlocking(source,u_comm_buf,compress); });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      void HaloExchangeBlocking(const Lattice<vobj> &source,std::vector<cobj,alignedAllocator<cobj> > &u_comm_buf,compressor &compress)
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
	// conformable(source._grid,_grid);
 | 
						// conformable(source._grid,_grid);
 | 
				
			||||||
	assert(source._grid==_grid);
 | 
						assert(source._grid==_grid);
 | 
				
			||||||
	halotime-=usecond();
 | 
						halotime-=usecond();
 | 
				
			||||||
	if (u_comm_buf.size() != _unified_buffer_size ) u_comm_buf.resize(_unified_buffer_size);
 | 
					
 | 
				
			||||||
	int u_comm_offset=0;
 | 
						assert (comm_buf.size() == _unified_buffer_size );
 | 
				
			||||||
 | 
						u_comm_offset=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Gather all comms buffers
 | 
						// Gather all comms buffers
 | 
				
			||||||
	for(int point = 0 ; point < _npoints; point++) {
 | 
						for(int point = 0 ; point < _npoints; point++) {
 | 
				
			||||||
@@ -506,35 +558,34 @@ namespace Grid {
 | 
				
			|||||||
	    if ( sshift[0] == sshift[1] ) {
 | 
						    if ( sshift[0] == sshift[1] ) {
 | 
				
			||||||
	      if (splice_dim) {
 | 
						      if (splice_dim) {
 | 
				
			||||||
		splicetime-=usecond();
 | 
							splicetime-=usecond();
 | 
				
			||||||
		GatherStartCommsSimd(source,dimension,shift,0x3,u_comm_buf,u_comm_offset,compress);
 | 
							GatherSimd(source,dimension,shift,0x3,compress);
 | 
				
			||||||
		splicetime+=usecond();
 | 
							splicetime+=usecond();
 | 
				
			||||||
	      } else { 
 | 
						      } else { 
 | 
				
			||||||
		nosplicetime-=usecond();
 | 
							nosplicetime-=usecond();
 | 
				
			||||||
		GatherStartComms(source,dimension,shift,0x3,u_comm_buf,u_comm_offset,compress);
 | 
							Gather(source,dimension,shift,0x3,compress);
 | 
				
			||||||
		nosplicetime+=usecond();
 | 
							nosplicetime+=usecond();
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
	    } else {
 | 
						    } else {
 | 
				
			||||||
	      //	      std::cout << "dim "<<dimension<<"cb "<<_checkerboard<<"shift "<<shift<<" sshift " << sshift[0]<<" "<<sshift[1]<<std::endl;
 | 
					 | 
				
			||||||
	      if(splice_dim){
 | 
						      if(splice_dim){
 | 
				
			||||||
		splicetime-=usecond();
 | 
							splicetime-=usecond();
 | 
				
			||||||
		GatherStartCommsSimd(source,dimension,shift,0x1,u_comm_buf,u_comm_offset,compress);// if checkerboard is unfavourable take two passes
 | 
							GatherSimd(source,dimension,shift,0x1,compress);// if checkerboard is unfavourable take two passes
 | 
				
			||||||
		GatherStartCommsSimd(source,dimension,shift,0x2,u_comm_buf,u_comm_offset,compress);// both with block stride loop iteration
 | 
							GatherSimd(source,dimension,shift,0x2,compress);// both with block stride loop iteration
 | 
				
			||||||
		splicetime+=usecond();
 | 
							splicetime+=usecond();
 | 
				
			||||||
	      } else {
 | 
						      } else {
 | 
				
			||||||
		nosplicetime-=usecond();
 | 
							nosplicetime-=usecond();
 | 
				
			||||||
		GatherStartComms(source,dimension,shift,0x1,u_comm_buf,u_comm_offset,compress);
 | 
							Gather(source,dimension,shift,0x1,compress);
 | 
				
			||||||
		GatherStartComms(source,dimension,shift,0x2,u_comm_buf,u_comm_offset,compress);
 | 
							Gather(source,dimension,shift,0x2,compress);
 | 
				
			||||||
		nosplicetime+=usecond();
 | 
							nosplicetime+=usecond();
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(u_comm_offset==_unified_buffer_size);
 | 
				
			||||||
	halotime+=usecond();
 | 
						halotime+=usecond();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void GatherStartComms(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,
 | 
					        void Gather(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,compressor & compress)
 | 
				
			||||||
			      std::vector<cobj,alignedAllocator<cobj> > &u_comm_buf,
 | 
					 | 
				
			||||||
			      int &u_comm_offset,compressor & compress)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	  typedef typename cobj::vector_type vector_type;
 | 
						  typedef typename cobj::vector_type vector_type;
 | 
				
			||||||
	  typedef typename cobj::scalar_type scalar_type;
 | 
						  typedef typename cobj::scalar_type scalar_type;
 | 
				
			||||||
@@ -555,8 +606,6 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	  int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension];
 | 
						  int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  if(send_buf.size()<buffer_size) send_buf.resize(buffer_size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  int cb= (cbmask==0x2)? Odd : Even;
 | 
						  int cb= (cbmask==0x2)? Odd : Even;
 | 
				
			||||||
	  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
						  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -573,7 +622,7 @@ namespace Grid {
 | 
				
			|||||||
	      int bytes = words * sizeof(cobj);
 | 
						      int bytes = words * sizeof(cobj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      gathertime-=usecond();
 | 
						      gathertime-=usecond();
 | 
				
			||||||
	      Gather_plane_simple (rhs,send_buf,dimension,sx,cbmask,compress);
 | 
						      Gather_plane_simple (rhs,u_send_buf,dimension,sx,cbmask,compress,u_comm_offset);
 | 
				
			||||||
	      gathertime+=usecond();
 | 
						      gathertime+=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      int rank           = _grid->_processor;
 | 
						      int rank           = _grid->_processor;
 | 
				
			||||||
@@ -585,11 +634,19 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	      //      FIXME Implement asynchronous send & also avoid buffer copy
 | 
						      //      FIXME Implement asynchronous send & also avoid buffer copy
 | 
				
			||||||
	      commtime-=usecond();
 | 
						      commtime-=usecond();
 | 
				
			||||||
 | 
						      /*
 | 
				
			||||||
	      _grid->SendToRecvFrom((void *)&send_buf[0],
 | 
						      _grid->SendToRecvFrom((void *)&send_buf[0],
 | 
				
			||||||
				   xmit_to_rank,
 | 
									   xmit_to_rank,
 | 
				
			||||||
				    (void *)&u_comm_buf[u_comm_offset],
 | 
									    (void *)&comm_buf[u_comm_offset],
 | 
				
			||||||
				   recv_from_rank,
 | 
									   recv_from_rank,
 | 
				
			||||||
				   bytes);
 | 
									   bytes);
 | 
				
			||||||
 | 
						      */ 
 | 
				
			||||||
 | 
						      AddPacket((void *)&u_send_buf[u_comm_offset],
 | 
				
			||||||
 | 
								(void *)&comm_buf[u_comm_offset],
 | 
				
			||||||
 | 
								xmit_to_rank,
 | 
				
			||||||
 | 
								recv_from_rank,
 | 
				
			||||||
 | 
								bytes);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
	      commtime+=usecond();
 | 
						      commtime+=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      u_comm_offset+=words;
 | 
						      u_comm_offset+=words;
 | 
				
			||||||
@@ -598,13 +655,10 @@ namespace Grid {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void  GatherStartCommsSimd(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,
 | 
						void  GatherSimd(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,compressor &compress)
 | 
				
			||||||
				   std::vector<cobj,alignedAllocator<cobj> > &u_comm_buf,
 | 
					 | 
				
			||||||
				   int &u_comm_offset,compressor &compress)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	  buftime-=usecond();
 | 
						  buftime-=usecond();
 | 
				
			||||||
	  const int Nsimd = _grid->Nsimd();
 | 
						  const int Nsimd = _grid->Nsimd();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  int fd = _grid->_fdimensions[dimension];
 | 
						  int fd = _grid->_fdimensions[dimension];
 | 
				
			||||||
	  int rd = _grid->_rdimensions[dimension];
 | 
						  int rd = _grid->_rdimensions[dimension];
 | 
				
			||||||
@@ -628,20 +682,11 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	  assert(cbmask==0x3); // Fixme think there is a latent bug if not true
 | 
						  assert(cbmask==0x3); // Fixme think there is a latent bug if not true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  //	Should grow to max size and then cost very little thereafter
 | 
					 | 
				
			||||||
	  send_buf_extract.resize(Nsimd);
 | 
					 | 
				
			||||||
	  recv_buf_extract.resize(Nsimd);
 | 
					 | 
				
			||||||
	  for(int l=0;l<Nsimd;l++){
 | 
					 | 
				
			||||||
	    if( send_buf_extract[l].size() < buffer_size) {
 | 
					 | 
				
			||||||
	      send_buf_extract[l].resize(buffer_size);
 | 
					 | 
				
			||||||
	      recv_buf_extract[l].resize(buffer_size);
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	  pointers.resize(Nsimd);
 | 
					 | 
				
			||||||
	  rpointers.resize(Nsimd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  int bytes = buffer_size*sizeof(scalar_object);
 | 
						  int bytes = buffer_size*sizeof(scalar_object);
 | 
				
			||||||
	  
 | 
					
 | 
				
			||||||
 | 
						  std::vector<scalar_object *> rpointers(Nsimd);
 | 
				
			||||||
 | 
						  std::vector<scalar_object *> spointers(Nsimd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  buftime+=usecond();
 | 
						  buftime+=usecond();
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  ///////////////////////////////////////////
 | 
						  ///////////////////////////////////////////
 | 
				
			||||||
@@ -659,16 +704,19 @@ namespace Grid {
 | 
				
			|||||||
	    if ( any_offnode ) {
 | 
						    if ( any_offnode ) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      for(int i=0;i<Nsimd;i++){       
 | 
						      for(int i=0;i<Nsimd;i++){       
 | 
				
			||||||
		pointers[i] = &send_buf_extract[i][0];
 | 
							spointers[i] = &u_simd_send_buf[i][u_comm_offset];
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      int sx   = (x+sshift)%rd;
 | 
						      int sx   = (x+sshift)%rd;
 | 
				
			||||||
	      
 | 
						      
 | 
				
			||||||
	      gathermtime-=usecond();
 | 
						      gathermtime-=usecond();
 | 
				
			||||||
	      Gather_plane_extract<cobj>(rhs,pointers,dimension,sx,cbmask,compress);
 | 
						      Gather_plane_extract<cobj>(rhs,spointers,dimension,sx,cbmask,compress);
 | 
				
			||||||
	      gathermtime+=usecond();
 | 
						      gathermtime+=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      for(int i=0;i<Nsimd;i++){
 | 
						      for(int i=0;i<Nsimd;i++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//		std::cout << "GatherSimd : lane 1st elem " << i << u_simd_send_buf[i ][u_comm_offset]<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int inner_bit = (Nsimd>>(permute_type+1));
 | 
							int inner_bit = (Nsimd>>(permute_type+1));
 | 
				
			||||||
		int ic= (i&inner_bit)? 1:0;
 | 
							int ic= (i&inner_bit)? 1:0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -680,45 +728,43 @@ namespace Grid {
 | 
				
			|||||||
		int nbr_ox   = (nbr_lcoor%rd);    // outer coord of peer
 | 
							int nbr_ox   = (nbr_lcoor%rd);    // outer coord of peer
 | 
				
			||||||
		int nbr_lane = (i&(~inner_bit));
 | 
							int nbr_lane = (i&(~inner_bit));
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		int recv_from_rank;
 | 
					 | 
				
			||||||
		int xmit_to_rank;
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if (nbr_ic) nbr_lane|=inner_bit;
 | 
							if (nbr_ic) nbr_lane|=inner_bit;
 | 
				
			||||||
		assert (sx == nbr_ox);
 | 
							assert (sx == nbr_ox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		
 | 
							auto rp = &u_simd_recv_buf[i       ][u_comm_offset];
 | 
				
			||||||
 | 
							auto sp = &u_simd_send_buf[nbr_lane][u_comm_offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void *vrp = (void *)rp;
 | 
				
			||||||
 | 
							void *vsp = (void *)sp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(nbr_proc){
 | 
							if(nbr_proc){
 | 
				
			||||||
		  
 | 
							  
 | 
				
			||||||
 | 
							  int recv_from_rank;
 | 
				
			||||||
 | 
							  int xmit_to_rank;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		  _grid->ShiftedRanks(dimension,nbr_proc,xmit_to_rank,recv_from_rank); 
 | 
							  _grid->ShiftedRanks(dimension,nbr_proc,xmit_to_rank,recv_from_rank); 
 | 
				
			||||||
		  
 | 
							  
 | 
				
			||||||
		  commstime-=usecond();
 | 
							  commstime-=usecond();
 | 
				
			||||||
		  _grid->SendToRecvFrom((void *)&send_buf_extract[nbr_lane][0],
 | 
							  AddPacket( vsp,vrp,xmit_to_rank,recv_from_rank,bytes);
 | 
				
			||||||
					xmit_to_rank,
 | 
					 | 
				
			||||||
					(void *)&recv_buf_extract[i][0],
 | 
					 | 
				
			||||||
					recv_from_rank,
 | 
					 | 
				
			||||||
					bytes);
 | 
					 | 
				
			||||||
		  commstime+=usecond();
 | 
							  commstime+=usecond();
 | 
				
			||||||
		  
 | 
							  
 | 
				
			||||||
		  rpointers[i] = &recv_buf_extract[i][0];
 | 
							  rpointers[i] = rp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else { 
 | 
							} else { 
 | 
				
			||||||
		  rpointers[i] = &send_buf_extract[nbr_lane][0];
 | 
					
 | 
				
			||||||
 | 
							  rpointers[i] = sp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	      }
 | 
						      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	      //	      std::cout << " CommsSimd ["<<dimension<<"] offset "<<u_comm_offset<<" buffsize "<<buffer_size  <<" unified  buffer size "<<_unified_buffer_size<<std::endl;
 | 
						      AddMerge(&comm_buf[u_comm_offset],rpointers,buffer_size);
 | 
				
			||||||
	      mergetime-=usecond();
 | 
					
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						      u_comm_offset     +=buffer_size;
 | 
				
			||||||
	      for(int i=0;i<buffer_size;i++){
 | 
					 | 
				
			||||||
		//		std::cout<<"buffer loop " << i<<" "<<u_comm_offset+i<<" / "<<_unified_buffer_size<<std::endl;
 | 
					 | 
				
			||||||
		//		assert(u_comm_offset+i<_unified_buffer_size);
 | 
					 | 
				
			||||||
		merge(u_comm_buf[u_comm_offset+i],rpointers,i);
 | 
					 | 
				
			||||||
	      }
 | 
					 | 
				
			||||||
	      mergetime+=usecond();
 | 
					 | 
				
			||||||
	      u_comm_offset+=buffer_size;
 | 
					 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -204,7 +204,6 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::vector<CoarseMatrix> A;
 | 
					    std::vector<CoarseMatrix> A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector<siteVector,alignedAllocator<siteVector> >   comm_buf;
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    ///////////////////////
 | 
					    ///////////////////////
 | 
				
			||||||
    // Interface
 | 
					    // Interface
 | 
				
			||||||
@@ -217,7 +216,7 @@ namespace Grid {
 | 
				
			|||||||
      conformable(in._grid,out._grid);
 | 
					      conformable(in._grid,out._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      SimpleCompressor<siteVector> compressor;
 | 
					      SimpleCompressor<siteVector> compressor;
 | 
				
			||||||
      Stencil.HaloExchange(in,comm_buf,compressor);
 | 
					      Stencil.HaloExchange(in,compressor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
      for(int ss=0;ss<Grid()->oSites();ss++){
 | 
					      for(int ss=0;ss<Grid()->oSites();ss++){
 | 
				
			||||||
@@ -234,7 +233,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  } else if(SE->_is_local) { 
 | 
						  } else if(SE->_is_local) { 
 | 
				
			||||||
	    nbr = in._odata[SE->_offset];
 | 
						    nbr = in._odata[SE->_offset];
 | 
				
			||||||
	  } else {
 | 
						  } else {
 | 
				
			||||||
	    nbr = comm_buf[SE->_offset];
 | 
						    nbr = Stencil.comm_buf[SE->_offset];
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	  res = res + A[point]._odata[ss]*nbr;
 | 
						  res = res + A[point]._odata[ss]*nbr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -258,7 +257,6 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
      Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements),
 | 
					      Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements),
 | 
				
			||||||
      A(geom.npoint,&CoarseGrid)
 | 
					      A(geom.npoint,&CoarseGrid)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      comm_buf.resize(Stencil._unified_buffer_size);
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop,
 | 
					    void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@ public:
 | 
				
			|||||||
// Gather for when there is no need to SIMD split with compression
 | 
					// Gather for when there is no need to SIMD split with compression
 | 
				
			||||||
///////////////////////////////////////////////////////////////////
 | 
					///////////////////////////////////////////////////////////////////
 | 
				
			||||||
template<class vobj,class cobj,class compressor> void 
 | 
					template<class vobj,class cobj,class compressor> void 
 | 
				
			||||||
Gather_plane_simple (const Lattice<vobj> &rhs,std::vector<cobj,alignedAllocator<cobj> > &buffer,int dimension,int plane,int cbmask,compressor &compress)
 | 
					Gather_plane_simple (const Lattice<vobj> &rhs,std::vector<cobj,alignedAllocator<cobj> > &buffer,int dimension,int plane,int cbmask,compressor &compress, int off=0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int rd = rhs._grid->_rdimensions[dimension];
 | 
					  int rd = rhs._grid->_rdimensions[dimension];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +63,7 @@ PARALLEL_NESTED_LOOP2
 | 
				
			|||||||
      for(int b=0;b<e2;b++){
 | 
					      for(int b=0;b<e2;b++){
 | 
				
			||||||
	int o  = n*rhs._grid->_slice_stride[dimension];
 | 
						int o  = n*rhs._grid->_slice_stride[dimension];
 | 
				
			||||||
	int bo = n*rhs._grid->_slice_block[dimension];
 | 
						int bo = n*rhs._grid->_slice_block[dimension];
 | 
				
			||||||
	buffer[bo+b]=compress(rhs._odata[so+o+b],dimension,plane,so+o+b,rhs._grid);
 | 
						buffer[off+bo+b]=compress(rhs._odata[so+o+b],dimension,plane,so+o+b,rhs._grid);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
@@ -73,7 +73,7 @@ PARALLEL_NESTED_LOOP2
 | 
				
			|||||||
	 int o  = n*rhs._grid->_slice_stride[dimension];
 | 
						 int o  = n*rhs._grid->_slice_stride[dimension];
 | 
				
			||||||
	 int ocb=1<<rhs._grid->CheckerBoardFromOindex(o+b);// Could easily be a table lookup
 | 
						 int ocb=1<<rhs._grid->CheckerBoardFromOindex(o+b);// Could easily be a table lookup
 | 
				
			||||||
	 if ( ocb &cbmask ) {
 | 
						 if ( ocb &cbmask ) {
 | 
				
			||||||
	   buffer[bo++]=compress(rhs._odata[so+o+b],dimension,plane,so+o+b,rhs._grid);
 | 
						   buffer[off+bo++]=compress(rhs._odata[so+o+b],dimension,plane,so+o+b,rhs._grid);
 | 
				
			||||||
	 }
 | 
						 }
 | 
				
			||||||
       }
 | 
					       }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,6 @@ namespace QCD {
 | 
				
			|||||||
	UmuOdd (&Hgrid) 
 | 
						UmuOdd (&Hgrid) 
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    // Allocate the required comms buffer
 | 
					    // Allocate the required comms buffer
 | 
				
			||||||
    comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
					 | 
				
			||||||
    ImportGauge(_Umu);
 | 
					    ImportGauge(_Umu);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -153,7 +152,7 @@ namespace QCD {
 | 
				
			|||||||
    FermionField Atilde(B._grid);
 | 
					    FermionField Atilde(B._grid);
 | 
				
			||||||
    Atilde = A;
 | 
					    Atilde = A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    st.HaloExchange(B,comm_buf,compressor);
 | 
					    st.HaloExchange(B,compressor);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for(int mu=0;mu<Nd;mu++){
 | 
					    for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
@@ -168,7 +167,7 @@ namespace QCD {
 | 
				
			|||||||
      ////////////////////////
 | 
					      ////////////////////////
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
	for(int sss=0;sss<B._grid->oSites();sss++){
 | 
						for(int sss=0;sss<B._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopDir(st,U,comm_buf,sss,sss,B,Btilde,mu,gamma);
 | 
						  Kernels::DiracOptDhopDir(st,U,st.comm_buf,sss,sss,B,Btilde,mu,gamma);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      //////////////////////////////////////////////////
 | 
					      //////////////////////////////////////////////////
 | 
				
			||||||
@@ -274,11 +273,11 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    Compressor compressor(dag);
 | 
					    Compressor compressor(dag);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Stencil.HaloExchange(in,comm_buf,compressor);
 | 
					    Stencil.HaloExchange(in,compressor);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	Kernels::DiracOptDhopDir(Stencil,Umu,comm_buf,sss,sss,in,out,dirdisp,gamma);
 | 
						Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.comm_buf,sss,sss,in,out,dirdisp,gamma);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -300,30 +299,30 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
					    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Compressor compressor(dag);
 | 
					    Compressor compressor(dag);
 | 
				
			||||||
    st.HaloExchange(in,comm_buf,compressor);
 | 
					    st.HaloExchange(in,compressor);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if ( dag == DaggerYes ) {
 | 
					    if ( dag == DaggerYes ) {
 | 
				
			||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
						  Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sss,sss,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sss,sss,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -338,8 +337,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    Compressor compressor(dag);
 | 
					    Compressor compressor(dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::thread comms_thread = st.HaloExchangeBegin(in,comm_buf,compressor);
 | 
					    auto handle = st.HaloExchangeBegin(in,compressor);
 | 
				
			||||||
    comms_thread.join();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool local    = true;
 | 
					    bool local    = true;
 | 
				
			||||||
    bool nonlocal = false;
 | 
					    bool nonlocal = false;
 | 
				
			||||||
@@ -347,28 +345,29 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st.HaloExchangeComplete(handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local    = false;
 | 
					    local    = false;
 | 
				
			||||||
    nonlocal = true;
 | 
					    nonlocal = true;
 | 
				
			||||||
@@ -376,24 +375,24 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      if( HandOptDslash ) {
 | 
					      if( HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      } else { 
 | 
					      } else { 
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					        for(int sss=0;sss<in._grid->oSites();sss++){
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sss,sss,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sss,sss,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,9 +152,6 @@ namespace Grid {
 | 
				
			|||||||
      DoubledGaugeField Umu;
 | 
					      DoubledGaugeField Umu;
 | 
				
			||||||
      DoubledGaugeField UmuEven;
 | 
					      DoubledGaugeField UmuEven;
 | 
				
			||||||
      DoubledGaugeField UmuOdd;
 | 
					      DoubledGaugeField UmuOdd;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Comms buffer
 | 
					 | 
				
			||||||
      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  comm_buf;
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -98,12 +98,11 @@ WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu,
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Allocate the required comms buffer
 | 
					  // Allocate the required comms buffer
 | 
				
			||||||
  comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ImportGauge(_Umu);
 | 
					  ImportGauge(_Umu);
 | 
				
			||||||
  commtime=0;
 | 
					  commtime=0;
 | 
				
			||||||
  jointime=0;
 | 
					  jointime=0;
 | 
				
			||||||
  dslashtime=0;
 | 
					  dslashtime=0;
 | 
				
			||||||
 | 
					  dslash1time=0;
 | 
				
			||||||
}  
 | 
					}  
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
					void WilsonFermion5D<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
				
			||||||
@@ -121,7 +120,7 @@ void WilsonFermion5D<Impl>::DhopDir(const FermionField &in, FermionField &out,in
 | 
				
			|||||||
  //  assert( (dir>=0)&&(dir<4) ); //must do x,y,z or t;
 | 
					  //  assert( (dir>=0)&&(dir<4) ); //must do x,y,z or t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Compressor compressor(DaggerNo);
 | 
					  Compressor compressor(DaggerNo);
 | 
				
			||||||
  Stencil.HaloExchange(in,comm_buf,compressor);
 | 
					  Stencil.HaloExchange(in,compressor);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  int skip = (disp==1) ? 0 : 1;
 | 
					  int skip = (disp==1) ? 0 : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,7 +135,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
    for(int s=0;s<Ls;s++){
 | 
					    for(int s=0;s<Ls;s++){
 | 
				
			||||||
      int sU=ss;
 | 
					      int sU=ss;
 | 
				
			||||||
      int sF = s+Ls*sU; 
 | 
					      int sF = s+Ls*sU; 
 | 
				
			||||||
      Kernels::DiracOptDhopDir(Stencil,Umu,comm_buf,sF,sU,in,out,dirdisp,gamma);
 | 
					      Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.comm_buf,sF,sU,in,out,dirdisp,gamma);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -159,7 +158,7 @@ void WilsonFermion5D<Impl>::DerivInternal(StencilImpl & st,
 | 
				
			|||||||
  FermionField Btilde(B._grid);
 | 
					  FermionField Btilde(B._grid);
 | 
				
			||||||
  FermionField Atilde(B._grid);
 | 
					  FermionField Atilde(B._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  st.HaloExchange(B,comm_buf,compressor);
 | 
					  st.HaloExchange(B,compressor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Atilde=A;
 | 
					  Atilde=A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,7 +183,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	assert ( sF< B._grid->oSites());
 | 
						assert ( sF< B._grid->oSites());
 | 
				
			||||||
	assert ( sU< U._grid->oSites());
 | 
						assert ( sU< U._grid->oSites());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Kernels::DiracOptDhopDir(st,U,comm_buf,sF,sU,B,Btilde,mu,gamma);
 | 
						Kernels::DiracOptDhopDir(st,U,st.comm_buf,sF,sU,B,Btilde,mu,gamma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////////
 | 
					    ////////////////////////////
 | 
				
			||||||
    // spin trace outer product
 | 
					    // spin trace outer product
 | 
				
			||||||
@@ -236,9 +235,10 @@ template<class Impl>
 | 
				
			|||||||
void WilsonFermion5D<Impl>::Report(void)
 | 
					void WilsonFermion5D<Impl>::Report(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  std::cout<<GridLogMessage << "********************"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "********************"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "Halo   time "<<commtime <<" us"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Halo    time "<<commtime <<" us"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "Dslash time "<<dslashtime<<" us"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Dslash  time "<<dslashtime<<" us"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "join   time "<<jointime<<" us"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Dslash1 time "<<dslash1time<<" us"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "join    time "<<jointime<<" us"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "Stencil All    time "<<Stencil.halotime<<" us"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Stencil All    time "<<Stencil.halotime<<" us"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "********************"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "********************"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "Stencil nosplice time "<<Stencil.nosplicetime<<" us"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Stencil nosplice time "<<Stencil.nosplicetime<<" us"<<std::endl;
 | 
				
			||||||
@@ -299,11 +299,11 @@ void WilsonFermion5D<Impl>::DhopInternalCommsThenCompute(StencilImpl & st, Lebes
 | 
				
			|||||||
  int nwork = U._grid->oSites();
 | 
					  int nwork = U._grid->oSites();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  commtime -=usecond();
 | 
					  commtime -=usecond();
 | 
				
			||||||
  std::thread thr = st.HaloExchangeBegin(in,comm_buf,compressor);
 | 
					  auto handle = st.HaloExchangeBegin(in,compressor);
 | 
				
			||||||
 | 
					  st.HaloExchangeComplete(handle);
 | 
				
			||||||
  commtime +=usecond();
 | 
					  commtime +=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  jointime -=usecond();
 | 
					  jointime -=usecond();
 | 
				
			||||||
  thr.join();
 | 
					 | 
				
			||||||
  jointime +=usecond();
 | 
					  jointime +=usecond();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
					  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
				
			||||||
@@ -319,7 +319,7 @@ void WilsonFermion5D<Impl>::DhopInternalCommsThenCompute(StencilImpl & st, Lebes
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -330,7 +330,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  for(sd=0;sd<Ls;sd++){
 | 
						  for(sd=0;sd<Ls;sd++){
 | 
				
			||||||
	    int sU=ss;
 | 
						    int sU=ss;
 | 
				
			||||||
	    int sF = sd+Ls*sU;
 | 
						    int sF = sd+Ls*sU;
 | 
				
			||||||
	    Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
						    Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -362,7 +362,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	      sU = lo.Reorder(sU);
 | 
						      sU = lo.Reorder(sU);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    sF = s+Ls*sU;
 | 
						    sF = s+Ls*sU;
 | 
				
			||||||
	    Kernels::DiracOptAsmDhopSite(st,U,comm_buf,sF,sU,in,out,(uint64_t *)0);// &buf[0]
 | 
						    Kernels::DiracOptAsmDhopSite(st,U,st.comm_buf,sF,sU,in,out,(uint64_t *)0);// &buf[0]
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -387,7 +387,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  sU=ss+ ssoff;
 | 
						  sU=ss+ ssoff;
 | 
				
			||||||
	  for(int s=soff;s<soff+swork;s++){
 | 
						  for(int s=soff;s<soff+swork;s++){
 | 
				
			||||||
	    sF = s+Ls*sU;
 | 
						    sF = s+Ls*sU;
 | 
				
			||||||
	    Kernels::DiracOptHandDhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
						    Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sF,sU,in,out);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -398,7 +398,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sF,sU,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -407,7 +407,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU; 
 | 
						  int sF = s+Ls*sU; 
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sF,sU,in,out);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -432,7 +432,7 @@ void WilsonFermion5D<Impl>::DhopInternalCommsOverlapCompute(StencilImpl & st, Le
 | 
				
			|||||||
  int nwork = U._grid->oSites();
 | 
					  int nwork = U._grid->oSites();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  commtime -=usecond();
 | 
					  commtime -=usecond();
 | 
				
			||||||
  std::thread thr = st.HaloExchangeBegin(in,comm_buf,compressor);
 | 
					  auto handle = st.HaloExchangeBegin(in,compressor);
 | 
				
			||||||
  commtime +=usecond();
 | 
					  commtime +=usecond();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
					  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
				
			||||||
@@ -450,7 +450,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -461,7 +461,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  for(sd=0;sd<Ls;sd++){
 | 
						  for(sd=0;sd<Ls;sd++){
 | 
				
			||||||
	    int sU=ss;
 | 
						    int sU=ss;
 | 
				
			||||||
	    int sF = sd+Ls*sU;
 | 
						    int sF = sd+Ls*sU;
 | 
				
			||||||
	    Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						    Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -473,7 +473,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -482,7 +482,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU; 
 | 
						  int sF = s+Ls*sU; 
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -490,12 +490,12 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
  dslashtime +=usecond();
 | 
					  dslashtime +=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  jointime -=usecond();
 | 
					  jointime -=usecond();
 | 
				
			||||||
  thr.join();
 | 
					  st.HaloExchangeComplete(handle);
 | 
				
			||||||
  jointime +=usecond();
 | 
					  jointime +=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  local    = false;
 | 
					  local    = false;
 | 
				
			||||||
  nonlocal = true;
 | 
					  nonlocal = true;
 | 
				
			||||||
  dslashtime -=usecond();
 | 
					  dslash1time -=usecond();
 | 
				
			||||||
  if ( dag == DaggerYes ) {
 | 
					  if ( dag == DaggerYes ) {
 | 
				
			||||||
    if( this->HandOptDslash ) {
 | 
					    if( this->HandOptDslash ) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
@@ -503,7 +503,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSiteDag(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -514,7 +514,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  for(sd=0;sd<Ls;sd++){
 | 
						  for(sd=0;sd<Ls;sd++){
 | 
				
			||||||
	    int sU=ss;
 | 
						    int sU=ss;
 | 
				
			||||||
	    int sF = sd+Ls*sU;
 | 
						    int sF = sd+Ls*sU;
 | 
				
			||||||
	    Kernels::DiracOptDhopSiteDag(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						    Kernels::DiracOptDhopSiteDag(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -526,7 +526,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU;
 | 
						  int sF = s+Ls*sU;
 | 
				
			||||||
	  Kernels::DiracOptHandDhopSite(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptHandDhopSite(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else { 
 | 
					    } else { 
 | 
				
			||||||
@@ -535,13 +535,12 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	int sU=ss;
 | 
						int sU=ss;
 | 
				
			||||||
	for(int s=0;s<Ls;s++){
 | 
						for(int s=0;s<Ls;s++){
 | 
				
			||||||
	  int sF = s+Ls*sU; 
 | 
						  int sF = s+Ls*sU; 
 | 
				
			||||||
	  Kernels::DiracOptDhopSite(st,U,comm_buf,sF,sU,in,out,local,nonlocal);
 | 
						  Kernels::DiracOptDhopSite(st,U,st.comm_buf,sF,sU,in,out,local,nonlocal);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  dslashtime +=usecond();
 | 
					  dslash1time +=usecond();
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,6 +64,7 @@ namespace Grid {
 | 
				
			|||||||
     double jointime;
 | 
					     double jointime;
 | 
				
			||||||
     double commtime;
 | 
					     double commtime;
 | 
				
			||||||
     double dslashtime;
 | 
					     double dslashtime;
 | 
				
			||||||
 | 
					     double dslash1time;
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					      ///////////////////////////////////////////////////////////////
 | 
				
			||||||
      // Implement the abstract base
 | 
					      // Implement the abstract base
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					      ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,9 +99,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
	  ocoor[dir]=(ocoor[dir]+disp)%Fine._rdimensions[dir];
 | 
						  ocoor[dir]=(ocoor[dir]+disp)%Fine._rdimensions[dir];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	std::vector<vobj,alignedAllocator<vobj> >  comm_buf(myStencil._unified_buffer_size);
 | 
					 | 
				
			||||||
	SimpleCompressor<vobj> compress;
 | 
						SimpleCompressor<vobj> compress;
 | 
				
			||||||
	myStencil.HaloExchange(Foo,comm_buf,compress);
 | 
						myStencil.HaloExchange(Foo,compress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Bar = Cshift(Foo,dir,disp);
 | 
						Bar = Cshift(Foo,dir,disp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -117,7 +116,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
	  else if (SE->_is_local)
 | 
						  else if (SE->_is_local)
 | 
				
			||||||
	    Check._odata[i] = Foo._odata[SE->_offset];
 | 
						    Check._odata[i] = Foo._odata[SE->_offset];
 | 
				
			||||||
	  else 
 | 
						  else 
 | 
				
			||||||
	    Check._odata[i] = comm_buf[SE->_offset];
 | 
						    Check._odata[i] = myStencil.comm_buf[SE->_offset];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Real nrmC = norm2(Check);
 | 
						Real nrmC = norm2(Check);
 | 
				
			||||||
@@ -181,13 +180,10 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
	  ocoor[dir]=(ocoor[dir]+disp)%Fine._rdimensions[dir];
 | 
						  ocoor[dir]=(ocoor[dir]+disp)%Fine._rdimensions[dir];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	std::vector<vobj,alignedAllocator<vobj> >  Ecomm_buf(EStencil._unified_buffer_size);
 | 
					 | 
				
			||||||
	std::vector<vobj,alignedAllocator<vobj> >  Ocomm_buf(OStencil._unified_buffer_size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SimpleCompressor<vobj> compress;
 | 
						SimpleCompressor<vobj> compress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EStencil.HaloExchange(EFoo,Ecomm_buf,compress);
 | 
						EStencil.HaloExchange(EFoo,compress);
 | 
				
			||||||
	OStencil.HaloExchange(OFoo,Ocomm_buf,compress);
 | 
						OStencil.HaloExchange(OFoo,compress);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	Bar = Cshift(Foo,dir,disp);
 | 
						Bar = Cshift(Foo,dir,disp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -211,7 +207,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
	  else if (SE->_is_local)
 | 
						  else if (SE->_is_local)
 | 
				
			||||||
	    OCheck._odata[i] = EFoo._odata[SE->_offset];
 | 
						    OCheck._odata[i] = EFoo._odata[SE->_offset];
 | 
				
			||||||
	  else 
 | 
						  else 
 | 
				
			||||||
	    OCheck._odata[i] = Ecomm_buf[SE->_offset];
 | 
						    OCheck._odata[i] = EStencil.comm_buf[SE->_offset];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for(int i=0;i<ECheck._grid->oSites();i++){
 | 
						for(int i=0;i<ECheck._grid->oSites();i++){
 | 
				
			||||||
	  int permute_type;
 | 
						  int permute_type;
 | 
				
			||||||
@@ -224,7 +220,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
	  else if (SE->_is_local)
 | 
						  else if (SE->_is_local)
 | 
				
			||||||
	    ECheck._odata[i] = OFoo._odata[SE->_offset];
 | 
						    ECheck._odata[i] = OFoo._odata[SE->_offset];
 | 
				
			||||||
	  else 
 | 
						  else 
 | 
				
			||||||
	    ECheck._odata[i] = Ocomm_buf[SE->_offset];
 | 
						    ECheck._odata[i] = OStencil.comm_buf[SE->_offset];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	setCheckerboard(Check,ECheck);
 | 
						setCheckerboard(Check,ECheck);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user