Beispiel #1
0
        /// <summary>
        /// Exchanges serialize-able data objects in between all MPI processes.
        /// </summary>
        /// <param name="objects_to_send">
        /// Data to send.<br/>
        /// keys: MPI rank of the process to which <em>o</em> should be send to<br/>
        /// values: some object <em>o</em>
        /// </param>
        /// <param name="comm"></param>
        /// <returns>
        /// Received data.<br/>
        /// keys: MPI rank of the process from which <em>q</em> has been received.<br/>
        /// values: some object <em>q</em>
        /// </returns>
        public static IDictionary <int, T> ExchangeData <T>(IDictionary <int, T> objects_to_send, MPI_Comm comm)
        {
            using (var sms = new SerialisationMessenger(comm)) {
                //if (PoorManDebugger != null) {
                //    PoorManDebugger.WriteLine("tag offset is " + sms.m_MyTagOffset);
                //    PoorManDebugger.Flush();
                //}
                sms.SetCommPathsAndCommit(objects_to_send.Keys);

                foreach (var kv in objects_to_send)
                {
                    sms.Transmit(kv.Key, kv.Value);
                }

                var R = new Dictionary <int, T>();
                T   obj;
                int rcv_rank;
                while (sms.GetNext(out rcv_rank, out obj))
                {
                    R.Add(rcv_rank, obj);
                }

                //if(PoorManDebugger != null)
                //{
                //    PoorManDebugger.WriteLine(" leaving ExchangeData");
                //    PoorManDebugger.Flush();
                //}

                return(R);
            }
        }
        /// <summary>
        /// Exchanges serializeable data objects in between all MPI processes.
        /// </summary>
        /// <param name="objects_to_send">
        /// Data to send.<br/>
        /// keys: MPI rank of the process to which <em>o</em> should be send to<br/>
        /// values: some object <em>o</em>
        /// </param>
        /// <param name="comm"></param>
        /// <returns>
        /// Received data.<br/>
        /// keys: MPI rank of the process from which <em>q</em> has been received.<br/>
        /// values: some object <em>q</em>
        /// </returns>
        public static IDictionary <int, T> ExchangeData <T>(IDictionary <int, T> objects_to_send, MPI_Comm comm)
        {
            using (var sms = new SerialisationMessenger(comm)) {
                sms.SetCommPathsAndCommit(objects_to_send.Keys);

                foreach (var kv in objects_to_send)
                {
                    sms.Transmitt(kv.Key, kv.Value);
                }


                var R = new Dictionary <int, T>();
                T   obj;
                int rcv_rank;
                while (sms.GetNext(out rcv_rank, out obj))
                {
                    R.Add(rcv_rank, obj);
                }

                return(R);
            }
        }
Beispiel #3
0
        ///// <summary>
        ///// saves a vector (distributed over various MPI processes) into a binary file
        ///// </summary>
        ///// <param name="list"></param>
        ///// <param name="filename"></param>
        //public static void SaveToFile<T>(this IEnumerable<T> list, string filename) {
        //    SaveToFile(list, filename, csMPI.Raw._COMM.WORLD);
        //}

        ///// <summary>
        ///// saves a vector (distributed over various MPI processes) into a binary file
        ///// </summary>
        ///// <param name="list"></param>
        ///// <param name="filename"></param>
        ///// <param name="comm"></param>
        //public static void SaveToFile<T>(this IEnumerable<T> list, string filename, MPI_Comm comm) {
        //    int Rank, Size;
        //    csMPI.Raw.Comm_Rank(comm, out Rank);
        //    csMPI.Raw.Comm_Size(comm, out Size);


        //    var sms = new SerialisationMessenger(comm);

        //    if (Rank == 0) {
        //        sms.CommitCommPaths();

        //        SortedDictionary<int, T[]> packets = new SortedDictionary<int, T[]>();
        //        packets.Add(0, list.ToArray());


        //        T[] rcvdata;
        //        int rcvRank;
        //        while (sms.GetNext(out rcvRank, out rcvdata)) {
        //            packets.Add(rcvRank, rcvdata);
        //        }

        //        int TotLen = packets.Values.Sum(p => p.Length);
        //        T[] allData = new T[TotLen];


        //        // write
        //        int offset = 0;
        //        for (int r = 0; r < Size; r++) {
        //            var lr = packets[r];
        //            Array.Copy(lr, 0, allData, offset, lr.Length);
        //            offset += lr.Length;
        //        }

        //        using (var file = new FileStream(filename, FileMode.Create, FileAccess.Write)) {
        //            Serializer.Serialize(file, allData);
        //            file.Close();
        //        }
        //    } else {
        //        sms.SetCommPath(0);
        //        sms.CommitCommPaths();

        //        T[] send = list as T[];
        //        if (send == null)
        //            send = list.ToArray();

        //        sms.Transmitt(0, send);


        //        T[] dummy;
        //        int dummy_;
        //        if (sms.GetNext<T[]>(out dummy_, out dummy))
        //            throw new ApplicationException("error in app");
        //    }
        //}

        ///// <summary>
        ///// Loads a vector from a binary file
        ///// </summary>
        ///// <param name="filename"></param>
        ///// <param name="comm"></param>
        ///// <param name="p">
        ///// optional partition, its MPI communicator must match <paramref name="comm"/>
        ///// </param>
        ///// <returns></returns>
        //public static T[] LoadFromFile<T>(string filename, MPI_Comm comm, Partitioning p = null) {
        //    if (p != null && (comm != p.MPI_Comm))
        //        throw new ArgumentException();
        //    int Rank, Size;
        //    csMPI.Raw.Comm_Rank(comm, out Rank);
        //    csMPI.Raw.Comm_Size(comm, out Size);



        //    T[] vec = null;
        //    int GlobalLen = 0;
        //    if (Rank == 0) {
        //        using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
        //            vec = Serializer.Deserialize<T[]>(file);
        //            file.Close();
        //        }

        //        GlobalLen = vec.Length;
        //    }

        //    unsafe {
        //        csMPI.Raw.Bcast((IntPtr)(&GlobalLen), 1, csMPI.Raw._DATATYPE.INT, 0, comm);
        //    }

        //    if (p == null) {
        //        int i0 = (GlobalLen * Rank) / Size;
        //        int iE = (GlobalLen * (Rank + 1)) / Size;
        //        p = new Partitioning(iE - i0, 1, comm);
        //    } else {
        //        if (p.TotalLength != GlobalLen)
        //            throw new ArgumentException("Mismatch between partition length and number of elements in file.");
        //    }

        //    Dictionary<int, T[]> SendDataPackets = new Dictionary<int, T[]>();
        //    if (Rank != 0) {
        //        for (int prc = 1; prc < Size; prc++) {
        //            T[] vec_prc = vec.GetSubVector((int)p.GetI0Offest(prc), p.GetLocalLength(prc));
        //            SendDataPackets.Add(prc, vec_prc);
        //        }
        //    }
        //    var RcvdDataPackets = SerialisationMessenger.ExchangeData(SendDataPackets, comm);

        //    if (Rank == 0) {
        //        return vec.GetSubVector((int)p.GetI0Offest(0), p.GetLocalLength(0));
        //    } else {
        //        Debug.Assert(RcvdDataPackets.Count == 1);
        //        Debug.Assert(RcvdDataPackets.ContainsKey(0));
        //        return RcvdDataPackets[0];
        //    }
        //}


        /// <summary>
        /// Loads a vector from a text file
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="Parse">Parsing function, converts a string into <typeparamref name="T"/>.</param>
        /// <param name="comm"></param>
        /// <param name="p">
        /// optional partition, its MPI communicator must match <paramref name="comm"/>
        /// </param>
        /// <returns></returns>
        public static T[] LoadFromTextFile <T>(string filename, Func <string, T> Parse, MPI_Comm comm, Partitioning p = null)
        {
            if (p != null && (comm != p.MPI_Comm))
            {
                throw new ArgumentException();
            }
            int Rank, Size;

            csMPI.Raw.Comm_Rank(comm, out Rank);
            csMPI.Raw.Comm_Size(comm, out Size);



            List <T> vec       = null;
            int      GlobalLen = 0;

            if (Rank == 0)
            {
                StreamReader rd = null;
                vec = new List <T>();
                try {
                    rd = new StreamReader(filename);

                    string line = rd.ReadLine();
                    while (line != null)
                    {
                        T entry = Parse(line);
                        vec.Add(entry);
                        line = rd.ReadLine();
                    }
                } finally {
                    if (rd != null)
                    {
                        rd.Close();
                    }
                }
                GlobalLen = vec.Count;
            }

            unsafe {
                csMPI.Raw.Bcast((IntPtr)(&GlobalLen), 1, csMPI.Raw._DATATYPE.INT, 0, comm);
            }

            if (p == null)
            {
                int i0 = (GlobalLen * Rank) / Size;
                int iE = (GlobalLen * (Rank + 1)) / Size;
                p = new Partitioning(iE - i0, comm);
            }
            else
            {
                if (p.TotalLength != GlobalLen)
                {
                    throw new ArgumentException("Mismatch between partition length and number of elements in file.");
                }
            }

            Dictionary <int, T[]> SendDataPackets = new Dictionary <int, T[]>();

            if (Rank != 0)
            {
                for (int prc = 1; prc < Size; prc++)
                {
                    T[] vec_prc = vec.GetSubVector((int)p.GetI0Offest(prc), p.GetLocalLength(prc));
                    SendDataPackets.Add(prc, vec_prc);
                }
            }
            var RcvdDataPackets = SerialisationMessenger.ExchangeData(SendDataPackets, comm);

            if (Rank == 0)
            {
                return(vec.GetSubVector((int)p.GetI0Offest(0), p.GetLocalLength(0)));
            }
            else
            {
                Debug.Assert(RcvdDataPackets.Count == 1);
                Debug.Assert(RcvdDataPackets.ContainsKey(0));
                return(RcvdDataPackets[0]);
            }
        }
Beispiel #4
0
        /// <summary>
        /// saves a vector (distributed over various MPI processes) into one text file
        /// </summary>
        /// <param name="list"></param>
        /// <param name="stw">text writer on output stream</param>
        /// <param name="comm"></param>
        /// <param name="ToString">
        /// Optional customization of the way how the entries of <paramref name="list"/> should be transformed into strings.
        /// </param>
        public static void SaveToStream <T>(this IEnumerable <T> list, TextWriter stw, MPI_Comm comm, Func <T, string> ToString = null)
        {
            int Rank, Size;

            csMPI.Raw.Comm_Rank(comm, out Rank);
            csMPI.Raw.Comm_Size(comm, out Size);

            if (ToString == null)
            {
                ToString = delegate(T obj) {
                    return(obj.ToString());
                }
            }
            ;

            var sms = new SerialisationMessenger(comm);

            if (Rank == 0)
            {
                sms.CommitCommPaths();

                SortedDictionary <int, T[]> packets = new SortedDictionary <int, T[]>();
                packets.Add(0, list.ToArray());


                T[] rcvdata;
                int rcvRank;
                while (sms.GetNext(out rcvRank, out rcvdata))
                {
                    packets.Add(rcvRank, rcvdata);
                }



                // write

                for (int r = 0; r < Size; r++)
                {
                    IList <T> lr = packets[r];

                    for (int n = 0; n < lr.Count; n++)
                    {
                        stw.Write(ToString(lr[n]));
                        stw.WriteLine();
                    }
                }
            }
            else
            {
                sms.SetCommPath(0);
                sms.CommitCommPaths();

                T[] send = list as T[];
                if (send == null)
                {
                    send = list.ToArray();
                }

                sms.Transmitt(0, send);


                T[] dummy;
                int dummy_;
                if (sms.GetNext <T[]>(out dummy_, out dummy))
                {
                    throw new ApplicationException("error in app");
                }
            }
        }