/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/communicator/Communicator_base.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 */ #ifndef GRID_COMMUNICATOR_BASE_H #define GRID_COMMUNICATOR_BASE_H /////////////////////////////////// // Processor layout information /////////////////////////////////// #ifdef GRID_COMMS_MPI #include #endif #ifdef GRID_COMMS_SHMEM #include #endif namespace Grid { class CartesianCommunicator { public: // Communicator should know nothing of the physics grid, only processor grid. int _Nprocessors; // How many in all std::vector _processors; // Which dimensions get relayed out over processors lanes. int _processor; // linear processor rank std::vector _processor_coor; // linear processor coordinate unsigned long _ndimension; #ifdef GRID_COMMS_MPI MPI_Comm communicator; typedef MPI_Request CommsRequest_t; #else typedef int CommsRequest_t; #endif static void Init(int *argc, char ***argv); // Constructor CartesianCommunicator(const std::vector &pdimensions_in); // Wraps MPI_Cart routines void ShiftedRanks(int dim,int shift,int & source, int & dest); int RankFromProcessorCoor(std::vector &coor); void ProcessorCoorFromRank(int rank,std::vector &coor); ///////////////////////////////// // Grid information queries ///////////////////////////////// int IsBoss(void) { return _processor==0; }; int BossRank(void) { return 0; }; int ThisRank(void) { return _processor; }; const std::vector & ThisProcessorCoor(void) { return _processor_coor; }; const std::vector & ProcessorGrid(void) { return _processors; }; int ProcessorCount(void) { return _Nprocessors; }; //////////////////////////////////////////////////////////// // Reduction //////////////////////////////////////////////////////////// void GlobalSum(RealF &); void GlobalSumVector(RealF *,int N); void GlobalSum(RealD &); void GlobalSumVector(RealD *,int N); void GlobalSum(uint32_t &); void GlobalSum(uint64_t &); void GlobalSum(ComplexF &c) { GlobalSumVector((float *)&c,2); } void GlobalSumVector(ComplexF *c,int N) { GlobalSumVector((float *)c,2*N); } void GlobalSum(ComplexD &c) { GlobalSumVector((double *)&c,2); } void GlobalSumVector(ComplexD *c,int N) { GlobalSumVector((double *)c,2*N); } template void GlobalSum(obj &o){ typedef typename obj::scalar_type scalar_type; int words = sizeof(obj)/sizeof(scalar_type); scalar_type * ptr = (scalar_type *)& o; GlobalSumVector(ptr,words); } //////////////////////////////////////////////////////////// // Face exchange, buffer swap in translational invariant way //////////////////////////////////////////////////////////// void SendToRecvFrom(void *xmit, int xmit_to_rank, void *recv, int recv_from_rank, int bytes); void SendRecvPacket(void *xmit, void *recv, int xmit_to_rank, int recv_from_rank, int bytes); void SendToRecvFromInit(std::vector &list, void *xmit, int xmit_to_rank, void *recv, int recv_from_rank, int bytes); void SendToRecvFromBegin(std::vector &list, void *xmit, int xmit_to_rank, void *recv, int recv_from_rank, int bytes); void SendToRecvFromBegin(std::vector &list); void SendToRecvFromComplete(std::vector &waitall); //////////////////////////////////////////////////////////// // Barrier //////////////////////////////////////////////////////////// void Barrier(void); //////////////////////////////////////////////////////////// // Broadcast a buffer and composite larger //////////////////////////////////////////////////////////// void Broadcast(int root,void* data, int bytes); template void Broadcast(int root,obj &data) { Broadcast(root,(void *)&data,sizeof(data)); }; static void BroadcastWorld(int root,void* data, int bytes); }; } #endif