Esempio n. 1
0
        /// <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];
            }
        }
Esempio n. 2
0
        /// <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
        }