/// <summary> /// ctor. /// </summary> public MPIexchange(MultigridMapping map, T vector) { // misc init // ========= IGridData master = map.AggGrid; int J = master.iLogicalCells.Count; if (vector.Count != map.LocalLength) { throw new ArgumentException("wrong length of input vector."); } m_vector = vector; m_master = master; m_map = map; var Para = m_master.iParallel; var rvcProc = Para.ProcessesToReceiveFrom; var sndProc = Para.ProcessesToSendTo; rqst = new MPI_Request[sndProc.Length + rvcProc.Length]; // allocate send buffers // ===================== { SendBuffers = new double[sndProc.Length][]; for (int i = 0; i < SendBuffers.Length; i++) { int p = sndProc[i]; // compute length of send list int L = 0; foreach (int jCell in Para.SendCommLists[p]) { Debug.Assert(map.IsLocalBlock(jCell + map.FirstBlock)); Debug.Assert(map.GetLength(jCell) == map.GetBlockLen(jCell + map.FirstBlock)); L += map.GetLength(jCell); } // alloc send buffer SendBuffers[i] = new double[L]; } SendBufferPin = new GCHandle[sndProc.Length]; } // allocate receive buffers // ======================== { int totL = 0; RcvBuffer = new double[rvcProc.Length][]; for (int i = 0; i < RcvBuffer.Length; i++) { int p = rvcProc[i]; // compute length of receive list int L = 0; int J0 = Para.RcvCommListsInsertIndex[p]; int JE = Para.RcvCommListsNoOfItems[p] + J0; for (int jCell = J0; jCell < JE; jCell++) { Debug.Assert(jCell >= map.LocalNoOfBlocks); L += map.GetLength(jCell); } totL += L; // alloc internal receive buffer RcvBuffer[i] = new double[L]; } RcvBufferPin = new GCHandle[RcvBuffer.Length]; m_Vector_Ext = new double[totL]; } }
/// <summary> /// ctor. /// </summary> public MPIexchange(MultigridMapping map, T vector) { // misc init // ========= IGridData master = map.AggGrid; int J = master.iLogicalCells.Count; if (vector.Count != map.LocalLength) { throw new ArgumentException("wrong length of input vector."); } m_vector = vector; m_master = master; m_map = map; var Para = m_master.iParallel; var rvcProc = Para.ProcessesToReceiveFrom; var sndProc = Para.ProcessesToSendTo; rqst = new MPI_Request[sndProc.Length + rvcProc.Length]; // allocate send buffers // ===================== { SendBuffers = new double[sndProc.Length][]; for (int i = 0; i < SendBuffers.Length; i++) { int p = sndProc[i]; // compute length of send list int L = 0; foreach (int jCell in Para.SendCommLists[p]) { Debug.Assert(map.IsLocalBlock(jCell + map.FirstBlock)); Debug.Assert(map.GetLength(jCell) == map.GetBlockLen(jCell + map.FirstBlock)); L += map.GetLength(jCell); } // alloc send buffer SendBuffers[i] = new double[L]; } SendBufferPin = new GCHandle[sndProc.Length]; } // allocate receive buffers // ======================== { int totL = 0; RcvBuffer = new double[rvcProc.Length][]; for (int i = 0; i < RcvBuffer.Length; i++) { int p = rvcProc[i]; // compute length of receive list int L = 0; int J0 = Para.RcvCommListsInsertIndex[p]; int JE = Para.RcvCommListsNoOfItems[p] + J0; for (int jCell = J0; jCell < JE; jCell++) { Debug.Assert(jCell >= map.LocalNoOfBlocks); L += map.GetLength(jCell); } totL += L; // alloc internal receive buffer RcvBuffer[i] = new double[L]; } RcvBufferPin = new GCHandle[RcvBuffer.Length]; m_Vector_Ext = new double[totL]; } #if DEBUG // verify send and receive lengths // =============================== { var RcvSizes = new Dictionary <int, int[]>(); for (int i = 0; i < SendBuffers.Length; i++) { //Console.WriteLine("P{0}: to proc {1}: {2} items ", map.MpiRank, sndProc[i], SendBuffers[i].Length); int source = map.MpiRank; int target = sndProc[i]; int L = SendBuffers[i].Length; RcvSizes.Add(target, new[] { source, L }); } var _RcvSizes = ilPSP.Utils.SerialisationMessenger.ExchangeData(RcvSizes); foreach (var kv in _RcvSizes) { int source = kv.Key; int sourceR = kv.Value[0]; int L = kv.Value[1]; int idxSrs = Array.IndexOf(rvcProc, source); Debug.Assert(idxSrs >= 0); int _L = RcvBuffer[idxSrs].Length; Debug.Assert(source == sourceR); Debug.Assert(L == _L, "mismatch in receive buffer size on multigrid level" + map.AggGrid.MgLevel); } csMPI.Raw.Barrier(map.MPI_Comm); } #endif }