/// <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); } }
///// <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]); } }
/// <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"); } } }