public void WorkerLoop() { var deepLog = Math.Log(communicator.Size, 2); deep = (int)Math.Floor(deepLog); if (communicator.Rank >= Math.Pow(2, deep)) { return; } var parentRank = GetParentRank(); Console.WriteLine($"Worker {communicator.Rank} processing requests from {parentRank}"); var jobRequest = communicator.ImmediateReceive <DataPackage>(parentRank, doWorkTag); jobRequest.Wait(); var package = jobRequest.GetValue() as DataPackage; var arrayAsList = package.Array.ToList(); deep = package.Deep; ParallelQuickSort(arrayAsList, 0, arrayAsList.Count - 1); CollectPackagesFromChilds(arrayAsList); var responsePackage = new DataPackage(arrayAsList.ToArray(), package.Low, package.High, deep); communicator.ImmediateSend(responsePackage, parentRank, receiveResultTag); }
static void Main(string[] args) { using (new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; //root if (Communicator.world.Rank == 0) { Console.WriteLine("Root sent a message to Rank 1"); comm.Send("blah", 1, 0); //nonblocking receive Request receive = comm.ImmediateReceive <string>(1, 0); Console.WriteLine("We are performing a nonblocking receive, so we can print instantly."); receive.Wait(); } //not the root else { comm.Receive <string>(0, 0); //Rank 1 will wait half a second before sending response System.Threading.Thread.Sleep(5000); Console.WriteLine("We waited half a second before sending something to the root."); comm.Send("blah", 0, 0); Console.WriteLine("If root was blocking, he wouldn't have been able to print until now!"); } } }
static List <Timetable> generateTimetable(Intracommunicator comm) { RequestList requestList = new RequestList(); List <ReceiveRequest> reqs = new List <ReceiveRequest>(); var classes = System.IO.File.ReadAllLines("input.txt").OfType <string>().Select(line => { var l = line.Trim().Split(';'); return(new Class(l[1], l[0])); }).ToList(); int id = 1; foreach (Class c in classes) { if (id == comm.Size) { id = 1; } Timetable t = new Timetable(); t.Table[Day.MONDAY][8].Add(c); var clone = copy(classes); clone.Remove(c); comm.Send(false, id, 1); comm.Send(new Payload { timetable = t.toList(), classes = clone, day = Day.MONDAY, hour = 8 }, id, 0); reqs.Add(comm.ImmediateReceive <List <Pair <Day, List <Pair <int, List <Class> > > > > >(id++, 0)); requestList.Add(reqs.Last()); } requestList.WaitAll(); for (int i = 1; i < comm.Size; i++) { comm.Send(true, i, 1); } return(reqs.Select(r => { r.Wait(); return new Timetable((List <Pair <Day, List <Pair <int, List <Class> > > > >)r.GetValue()); }).Where(t => t.Table.Count != 0).ToList()); }
public static void MPIWorker(Intracommunicator communicator) { Jacoby jacoby = null; ReceiveRequest request; using (var perf = new PerformanceCounter($"Comm {communicator.Rank} waiting for Jacoby duration: ")) { communicator.Broadcast <Jacoby>(ref jacoby, 0); } bool inProcess = true; using (var totalPerformance = new PerformanceCounter($"Comm {communicator.Rank} total work duration: ")) { int cycleIndex = 0; while (inProcess) { using (var perf = new PerformanceCounter($"Comm {communicator.Rank} cycle {cycleIndex} duration: ")) { JobToDo jobToDo = null; using (var perfRecv = new PerformanceCounter($"Comm {communicator.Rank} waiting for job-to-do (cycle {cycleIndex}): ")) { request = communicator.ImmediateReceive <JobToDo>(0, (int)JacobyMessageType.CalculatePart); request.Wait(); jobToDo = request.GetValue() as JobToDo; if (jobToDo.finish) { Console.WriteLine($"Comm {communicator.Rank} receive FINISH signal"); return; } } using (var perfWork = new PerformanceCounter($"Comm {communicator.Rank} work duration (cycle {cycleIndex}): ")) { Console.WriteLine($"Comm {communicator.Rank} start={jobToDo.start} end={jobToDo.end}"); var result = jacoby.PartialCalculation(jobToDo.start, jobToDo.end, jobToDo.initial); var srequest = communicator.ImmediateSend <JobDone>(new JobDone(result), 0, (int)JacobyMessageType.JobDone); } } cycleIndex++; } } }
/// <summary> /// Method that receives messages /// </summary> private void ReceiveMessages() { while (ContinueExecution) { // Receive next message and handle it ReceiveRequest asyncReceive = null; lock (comm) { // starts an asynchronous receive of the next message // Note: Must be asynchronous otherwise the lock of the comm object may cause a dead lock (unable to send message because we are waiting for one) asyncReceive = comm.ImmediateReceive <Message>(Communicator.anySource, 0); } // Creates a task that waits for the result to arrive. // Note : We must use a task because the Wait function of a task allows for a timeout parameter which we need to validate if the execution is still ongoing Task waitForMessage = new Task(() => { asyncReceive.Wait(); }); waitForMessage.Start(); // waits for a message to be received, stops (within 200ms) if the execution stops while (ContinueExecution && !waitForMessage.Wait(200)) { ; } if (!ContinueExecution) { asyncReceive.Cancel(); // We need to wait for the asyncReceive cancellation because the completion of this thread will close MPI but we need to make sure the cancel is over by then. asyncReceive.Wait(); break; // if the execution is over, the message may not be valid and should be ignored. } messageQueue.Add((Message)asyncReceive.GetValue()); } // Signal the main MapManager thread that this thread is correctly closed and we won't receive any other messages messageQueue.CompleteAdding(); }
static void TestRequests(Intracommunicator comm, RequestList requestList) { int datum = comm.Rank; int expectedDatum = (comm.Rank + comm.Size - 1) % comm.Size; int[] intArraySendBuffer = new int[comm.Rank + 1]; string[] strArraySendBuffer = new string[comm.Rank + 1]; for (int i = 0; i <= comm.Rank; ++i) { intArraySendBuffer[i] = i; strArraySendBuffer[i] = i.ToString(); } int[] intArrayRecvBuffer = new int[expectedDatum + 1]; string[] strArrayRecvBuffer = new string[expectedDatum + 1]; Request[] requests = new Request[8]; requests[0] = comm.ImmediateReceive<int>(Communicator.anySource, 0); requests[1] = comm.ImmediateReceive<string>(Communicator.anySource, 1); requests[2] = comm.ImmediateReceive(Communicator.anySource, 2, intArrayRecvBuffer); requests[3] = comm.ImmediateReceive(Communicator.anySource, 3, strArrayRecvBuffer); requests[4] = comm.ImmediateSend(datum, (comm.Rank + 1) % comm.Size, 0); requests[5] = comm.ImmediateSend(datum.ToString(), (comm.Rank + 1) % comm.Size, 1); requests[6] = comm.ImmediateSend(intArraySendBuffer, (comm.Rank + 1) % comm.Size, 2); requests[7] = comm.ImmediateSend(strArraySendBuffer, (comm.Rank + 1) % comm.Size, 3); if (requestList == null) { // Complete all communications manually bool allDone = false; while (!allDone) { allDone = true; for (int i = 0; i < requests.Length; ++i) allDone = allDone && requests[i].Test() != null; } } else { // Use the request list to complete all communications for (int i = 0; i < requests.Length; ++i) requestList.Add(requests[i]); requestList.WaitAll(); } ReceiveRequest intRecv = (ReceiveRequest)requests[0]; CompletedStatus intStatus = intRecv.Wait(); if ((int)intRecv.GetValue() != expectedDatum || intStatus.Source != expectedDatum || intStatus.Tag != 0) { System.Console.Error.WriteLine("error in non-blocking receive of integer: got " + (int)intRecv.GetValue() + " from " + intStatus.Source + " on tag " + intStatus.Tag + ", expected " + expectedDatum); MPI.Environment.Abort(-1); } ReceiveRequest strRecv = (ReceiveRequest)requests[1]; CompletedStatus strStatus = strRecv.Wait(); if ((string)strRecv.GetValue() != expectedDatum.ToString() || strStatus.Source != expectedDatum || strStatus.Tag != 1) { System.Console.Error.WriteLine("error in non-blocking receive of string: got " + strRecv.GetValue() + " from " + strStatus.Source + " on tag " + strStatus.Tag + ", expected " + expectedDatum); MPI.Environment.Abort(-1); } ReceiveRequest intArrayRecv = (ReceiveRequest)requests[2]; CompletedStatus intArrayStatus = intArrayRecv.Wait(); if (intArrayRecv.GetValue() != intArrayRecvBuffer || intArrayStatus.Source != expectedDatum || intArrayStatus.Tag != 2 ) { System.Console.WriteLine("error: received into the wrong integer array"); MPI.Environment.Abort(-1); } for (int i = 0; i <= expectedDatum; ++i) { if (intArrayRecvBuffer[i] != i) { System.Console.WriteLine("error: intArrayRecv[" + i + "] is " + intArrayRecvBuffer[i] + ", expected " + i); MPI.Environment.Abort(-1); } } ReceiveRequest strArrayRecv = (ReceiveRequest)requests[3]; CompletedStatus strArrayStatus = strArrayRecv.Wait(); if (strArrayRecv.GetValue() != strArrayRecvBuffer || strArrayStatus.Source != expectedDatum || strArrayStatus.Tag != 3) { System.Console.WriteLine("error: received into the wrong string array"); MPI.Environment.Abort(-1); } for (int i = 0; i <= expectedDatum; ++i) { if (strArrayRecvBuffer[i] != i.ToString()) { System.Console.WriteLine("error: strArrayRecv[" + i + "] is " + strArrayRecvBuffer[i] + ", expected " + i.ToString()); MPI.Environment.Abort(-1); } } }
static void TestRequests(Intracommunicator comm, RequestList requestList) { int datum = comm.Rank; int expectedDatum = (comm.Rank + comm.Size - 1) % comm.Size; int[] intArraySendBuffer = new int[comm.Rank + 1]; string[] strArraySendBuffer = new string[comm.Rank + 1]; for (int i = 0; i <= comm.Rank; ++i) { intArraySendBuffer[i] = i; strArraySendBuffer[i] = i.ToString(); } int[] intArrayRecvBuffer = new int[expectedDatum + 1]; string[] strArrayRecvBuffer = new string[expectedDatum + 1]; Request[] requests = new Request[8]; requests[0] = comm.ImmediateReceive <int>(Communicator.anySource, 0); requests[1] = comm.ImmediateReceive <string>(Communicator.anySource, 1); requests[2] = comm.ImmediateReceive(Communicator.anySource, 2, intArrayRecvBuffer); requests[3] = comm.ImmediateReceive(Communicator.anySource, 3, strArrayRecvBuffer); requests[4] = comm.ImmediateSend(datum, (comm.Rank + 1) % comm.Size, 0); requests[5] = comm.ImmediateSend(datum.ToString(), (comm.Rank + 1) % comm.Size, 1); requests[6] = comm.ImmediateSend(intArraySendBuffer, (comm.Rank + 1) % comm.Size, 2); requests[7] = comm.ImmediateSend(strArraySendBuffer, (comm.Rank + 1) % comm.Size, 3); if (requestList == null) { // Complete all communications manually bool allDone = false; while (!allDone) { allDone = true; for (int i = 0; i < requests.Length; ++i) { allDone = allDone && requests[i].Test() != null; } } } else { // Use the request list to complete all communications for (int i = 0; i < requests.Length; ++i) { requestList.Add(requests[i]); } requestList.WaitAll(); } ReceiveRequest intRecv = (ReceiveRequest)requests[0]; CompletedStatus intStatus = intRecv.Wait(); if ((int)intRecv.GetValue() != expectedDatum || intStatus.Source != expectedDatum || intStatus.Tag != 0) { System.Console.Error.WriteLine("error in non-blocking receive of integer: got " + (int)intRecv.GetValue() + " from " + intStatus.Source + " on tag " + intStatus.Tag + ", expected " + expectedDatum); MPI.Environment.Abort(-1); } ReceiveRequest strRecv = (ReceiveRequest)requests[1]; CompletedStatus strStatus = strRecv.Wait(); if ((string)strRecv.GetValue() != expectedDatum.ToString() || strStatus.Source != expectedDatum || strStatus.Tag != 1) { System.Console.Error.WriteLine("error in non-blocking receive of string: got " + strRecv.GetValue() + " from " + strStatus.Source + " on tag " + strStatus.Tag + ", expected " + expectedDatum); MPI.Environment.Abort(-1); } ReceiveRequest intArrayRecv = (ReceiveRequest)requests[2]; CompletedStatus intArrayStatus = intArrayRecv.Wait(); if (intArrayRecv.GetValue() != intArrayRecvBuffer || intArrayStatus.Source != expectedDatum || intArrayStatus.Tag != 2) { System.Console.WriteLine("error: received into the wrong integer array"); MPI.Environment.Abort(-1); } for (int i = 0; i <= expectedDatum; ++i) { if (intArrayRecvBuffer[i] != i) { System.Console.WriteLine("error: intArrayRecv[" + i + "] is " + intArrayRecvBuffer[i] + ", expected " + i); MPI.Environment.Abort(-1); } } ReceiveRequest strArrayRecv = (ReceiveRequest)requests[3]; CompletedStatus strArrayStatus = strArrayRecv.Wait(); if (strArrayRecv.GetValue() != strArrayRecvBuffer || strArrayStatus.Source != expectedDatum || strArrayStatus.Tag != 3) { System.Console.WriteLine("error: received into the wrong string array"); MPI.Environment.Abort(-1); } for (int i = 0; i <= expectedDatum; ++i) { if (strArrayRecvBuffer[i] != i.ToString()) { System.Console.WriteLine("error: strArrayRecv[" + i + "] is " + strArrayRecvBuffer[i] + ", expected " + i.ToString()); MPI.Environment.Abort(-1); } } }
static void Main(string[] args) { double msg3to5 = 7.875; int msg5to2first = 87, msg5to3 = 5; string msg5to2second = "Каждой принцессе положен палач."; using (new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; /* * if (!(comm.Rank == 2) || !(comm.Rank == 3) || !(comm.Rank == 5)) * { * //принимаем в 5 процессе сообщение с 3 процесса 5 * double[] receiveFor3 = new double[3]; * comm.ImmediateReceive(3, 42, receiveFor3); * foreach (var i in receiveFor3) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 3 процессе сообщение с 5 процесса 5 * int[] receive = new int[3]; * comm.ImmediateReceive(5, 42, receive); * foreach (var i in receive) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 2 процессе сообщение с 5 процесса 85 * int[] receiveFor2first = new int[3]; * comm.ImmediateReceive(5, 42, receiveFor2first); * foreach (var i in receiveFor2first) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 2 процессе сообщение с 5 процесса "Каждой принцессе положен палач." * string[] receiveFor2second = new string[3]; * comm.ImmediateReceive(5, 42, receiveFor2second); * foreach (var i in receiveFor2second) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * } * * else * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: false"); * * //Сообщения для 2 процесса * * //отправляем сообщение с 5 процесса к 2 процессу 87 * comm.ImmediateSend(msg5to2first, 2, 42); * Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 2 сообщение: " + * msg5to2first); * //отправляем сообщение с 5 процесса к 2 процессу "Каждой принцессе положен палач." * comm.ImmediateSend(msg5to2second, 2, 42); * Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 2 сообщение: " + * msg5to2second); * * //сообщения для 3 процесса * * //отправляем сообщение с 5 процесса к 3 процессу 5 * comm.ImmediateSend(msg5to3, 3, 42); * Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 3 сообщение: " + * msg5to3); * * * //отправляем сообщение с 3 процесса к 5 процессу 7.875 * comm.ImmediateSend(msg3to5, 5, 42); * * Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 5, сообщение: " + * msg3to5); * * * if ((comm.Rank == 2) || (comm.Rank == 3) || (comm.Rank == 5)) * { * //принимаем в 5 процессе сообщение с 3 процесса 5 * double[] receiveFor3 = new double[3]; * comm.ImmediateReceive(3, 42, receiveFor3); * foreach (var i in receiveFor3) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 3 процессе сообщение с 5 процесса 5 * int[] receive = new int[3]; * comm.ImmediateReceive(5, 42, receive); * foreach (var i in receive) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 2 процессе сообщение с 5 процесса 85 * int[] receiveFor2first = new int[3]; * comm.ImmediateReceive(5, 42, receiveFor2first); * foreach (var i in receiveFor2first) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * * //принимаем в 2 процессе сообщение с 5 процесса "Каждой принцессе положен палач." * string[] receiveFor2second = new string[3]; * comm.ImmediateReceive(5, 42, receiveFor2second); * foreach (var i in receiveFor2second) * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); * } * * else * Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: false"); */ if ((comm.Rank == 2) || (comm.Rank == 3) || (comm.Rank == 5)) { //если попали на 5-й процесс if (comm.Rank == 5) { //принимаем в 5 процессе сообщение с 3 процесса 5 double[] receiveFor3 = new double[3]; comm.ImmediateReceive(3, 42, receiveFor3); foreach (var i in receiveFor3) { Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); } //Сообщения для 2 процесса //отправляем сообщение с 5 процесса к 2 процессу 87 comm.Send(msg5to2first, 2, 42); Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 2 сообщение: " + msg5to2first); //отправляем сообщение с 5 процесса к 2 процессу "Каждой принцессе положен палач." comm.Send(msg5to2second, 2, 42); Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 2 сообщение: " + msg5to2second); //сообщения для 3 процесса //отправляем сообщение с 5 процесса к 3 процессу 5 comm.Send(msg5to3, 3, 42); Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 3 сообщение: " + msg5to3); } //если попали на 3-й процесс if (comm.Rank == 3) { //принимаем в 3 процессе сообщение с 5 процесса 5 int[] receive = new int[3]; comm.ImmediateReceive(5, 42, receive); foreach (var i in receive) { Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); } //отправляем сообщение с 3 процесса к 5 процессу 7.875 comm.Send(msg3to5, 5, 42); Console.WriteLine("<-- Процесс " + comm.Rank + " отправляет процессу 5, сообщение: " + msg3to5); } //если попали на 2-й процесс if (comm.Rank == 2) { //принимаем в 2 процессе сообщение с 5 процесса 85 int[] receiveFor2first = new int[3]; comm.ImmediateReceive(5, 42, receiveFor2first); foreach (var i in receiveFor2first) { Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); } //принимаем в 2 процессе сообщение с 5 процесса "Каждой принцессе положен палач." string[] receiveFor2second = new string[3]; comm.ImmediateReceive(5, 42, receiveFor2second); foreach (var i in receiveFor2second) { Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: " + i); } } } else { Console.WriteLine("--> Процесс " + comm.Rank + " получает сообщение: false"); } } }
static void Main(string[] args) { using (new MPI.Environment(ref args)) { if (args.Length != 1) { return; } const int matrixSize = 50; Intracommunicator comm = Communicator.world; int groupCount = int.Parse(args[0]); if (comm.Rank == 0) { DateTime startTime = DateTime.Now; MatrixMultiply testMultiply = new MatrixMultiply(comm.Size, matrixSize); Matrix result = testMultiply.MultiplyForRank(0); for (int i = 1; i < comm.Size; i++) { result.Append(testMultiply.MultiplyForRank(i)); } DateTime endTime = DateTime.Now; Console.WriteLine("Test multiply" + (startTime - endTime).ToString()); int workers = comm.Size - groupCount - 1; Console.WriteLine("All process count: " + (comm.Size).ToString()); Console.WriteLine("Workers count: " + (workers + groupCount).ToString()); Console.WriteLine("Group count" + (groupCount).ToString()); int workerIndex = groupCount + 1; int managersWithoutWorkers = groupCount; Request[] sendRequest = new Request[groupCount]; for (int i = 0; i < groupCount; i++) { int workersIntheGroup = (int)Math.Floor((double)(workers / managersWithoutWorkers)); MatrixMultiply mp = new MatrixMultiply(workersIntheGroup + 1, matrixSize) { WorkersList = new List <int>(), IsAManager = true }; for (int j = 0; j < workersIntheGroup; j++) { mp.WorkersList.Add(workerIndex); // Console.WriteLine("WorkerID " + workerIndex); workerIndex++; workers--; } managersWithoutWorkers--; Console.WriteLine("Group " + i.ToString() + " has " + (workersIntheGroup + 1).ToString() + "members"); sendRequest[i] = comm.ImmediateSend(mp, i + 1, 0); } Console.WriteLine("Sending the job"); for (int i = 0; i < groupCount; i++) { sendRequest[i].Wait(); } ReceiveRequest[] recieveRequest = new ReceiveRequest[groupCount]; for (int i = 0; i < groupCount; i++) { recieveRequest[i] = comm.ImmediateReceive <Matrix>(i + 1, 0); } Console.WriteLine("Recieve results"); for (int i = 0; i < groupCount; i++) { recieveRequest[i].Wait(); } //for (int i = 0; i < groupCount; i++) // { // var result = recieveRequest[i].GetValue(); // if(result == null) // { // Console.WriteLine("Null get"); // } // Console.WriteLine("Group " + i + " has finished in " + ((TimeSpan)recieveRequest[i].GetValue()).ToString()); //} } else { ReceiveRequest receiveRequest = comm.ImmediateReceive <MatrixMultiply>(Communicator.anySource, 0); receiveRequest.Wait(); MatrixMultiply mp = (MatrixMultiply)receiveRequest.GetValue(); if (mp.IsAManager) { DateTime startTime = DateTime.Now; mp.IsAManager = false; mp.Chef = comm.Rank; Request[] sendRequestToWorker = new Request[mp.WorkersList.Count]; int index = 0; //Console.WriteLine("MAnager " + mp.WorkersList.Count); foreach (int workerId in mp.WorkersList) { mp.workerId = index + 1; sendRequestToWorker[index] = comm.ImmediateSend(mp, workerId, 0); // Console.WriteLine("Worker " + mp.WorkersList.Count + " " + index); index++; } for (int i = 0; i < mp.WorkersList.Count; i++) { sendRequestToWorker[i].Wait(); } var result = mp.MultiplyForRank(0); ReceiveRequest[] receiveRequestFromWorkers = new ReceiveRequest[mp.WorkersList.Count]; for (int i = 0; i < mp.WorkersList.Count; i++) { receiveRequestFromWorkers[i] = comm.ImmediateReceive <Matrix>(mp.WorkersList.ToArray()[i], 0); } for (int i = 0; i < mp.WorkersList.Count; i++) { // Console.WriteLine("Waiting for " + mp.WorkersList.ToArray()[i]); receiveRequestFromWorkers[i].Wait(); } for (int i = 0; i < mp.WorkersList.Count; i++) { result.Append((Matrix)receiveRequestFromWorkers[i].GetValue()); } DateTime finishTime = DateTime.Now; TimeSpan resultTime = (finishTime - startTime); Request sendRequest = comm.ImmediateSend(resultTime, 0, 0); sendRequest.Wait(); Console.WriteLine("Group " + comm.Rank + " has done in " + resultTime); } else { //Console.WriteLine("Worker " + comm.Rank + "manager" + mp.Chef); mp.MultiplyForRank(mp.workerId); Request sendRequest = comm.ImmediateSend(mp.MultiplyForRank(mp.workerId), mp.Chef, 0); sendRequest.Wait(); } } } }
public static void CommunicatorThread() { while (true) { waitForCommunicationHandle.WaitOne(); int[] msgArray = new int[4 + journal.processesNumber]; var request = comm.ImmediateReceive(Communicator.anySource, Communicator.anyTag, msgArray); waitForCommunicationHandle.Set(); CompletedStatus probeResult = null; while (probeResult == null) { waitForCommunicationHandle.WaitOne(); probeResult = request.Test(); waitForCommunicationHandle.Set(); Thread.Sleep(20); } waitForCommunicationHandle.WaitOne(); //Obsłużenie otrzymania zgody if (probeResult.Tag == MSG_ACCEPT) { AcceptMessage msg = MessageArrays.AcceptArrayToMsg(msgArray); journal.CompareTimestampsAndUpdate(msg.Timestamp); journal.IncrementTimestamp(); //Console.WriteLine($"Proces {journal.shipRank}: dostałem ACCEPT od procesu {msg.SenderRank}."); journal.Accepts.Add(msg); if (journal.RememberedClock < msg.LogicalClock) //sprawdzenie zegara i zapamiętanie danych z wiadomości, jeśli nowszy { journal.RememberedClock = msg.LogicalClock; journal.RememberedOccupancy = msg.CurrentOccupancy; journal.RememberedLeavingCounters = msg.LeavingCounters; //Console.WriteLine($"Proces {journal.shipRank}: Dostałem zgodę ze świeższym statusem, od procesu {msg.SenderRank}, według niego zajętość to {msg.CurrentOccupancy}."); } if (journal.Accepts.Count == journal.processesNumber - 1) //wszystkie zgody otrzymane { journal.CanalOfInterest.CompareClocksAndUpdate(journal.RememberedClock); journal.CanalOfInterest.CurrentOccupancy = journal.RememberedOccupancy; journal.CanalOfInterest.CurrentOccupancy++; //oznaczamy miejsca zwolnione przez procesy, o których wiemy, że wyszły z kanału, a wysyłający nam najświeższą zgodę nie zdążył się o tym dowiedzieć przed wysłaniem for (int i = 0; i < msg.LeavingCounters.Count; i++) { if (journal.CanalOfInterest.LeavingCounters[i] > journal.RememberedLeavingCounters[i]) { //Console.WriteLine($"Proces {journal.shipRank}: MUSZĘ ZAKTUALIZOWAĆ CURRENT OCCUPANCY! Według mnie leaving counter dla procesu {i} wynosi {journal.CanalOfInterest.LeavingCounters[i]}, a według drugiego procesu {journal.RememberedLeavingCounters[i]}."); journal.CanalOfInterest.CurrentOccupancy -= journal.CanalOfInterest.LeavingCounters[i] - journal.RememberedLeavingCounters[i]; } if (journal.CanalOfInterest.LeavingCounters[i] < journal.RememberedLeavingCounters[i]) { journal.CanalOfInterest.LeavingCounters[i] = journal.RememberedLeavingCounters[i]; } } journal.IsDemandingEntry = false; journal.CanalOfInterest.IncrementClock(); if (journal.CanalOfInterest.CurrentOccupancy == journal.CanalOfInterest.maxOccupancy) //jeśli jesteśmy ostatnim mieszczącym się w kanale procesem { //Console.WriteLine($"Proces {journal.shipRank}: kanał {journal.CanalOfInterest.ID} jest teraz pełny."); journal.IsBlockingCanalEntry = true; } else //jeśli uważamy, że jest jeszcze miejsce (nie jesteśmy ostatnim mieszczącym się procesem), wysyłamy zgody wszystkim, którzy czekają { int currentOccupancy = journal.CanalOfInterest.CurrentOccupancy; int logicalClock = journal.CanalOfInterest.LogicalClock; List <int> leavingCounters = journal.CanalOfInterest.LeavingCounters; journal.IncrementTimestamp(); AcceptMessage accept = new AcceptMessage(journal.shipRank, journal.Timestamp, currentOccupancy, logicalClock, leavingCounters); int[] acceptArray = MessageArrays.AcceptMsgToArray(accept); foreach (DemandMessage demand in journal.DemandsForSameDirection) { comm.Send(acceptArray, demand.SenderRank, MSG_ACCEPT); //Console.WriteLine($"Proces {journal.shipRank}: po moim wejściu kanał ma jeszcze miejsce, więc wysyłam ACCEPT do procesu {demand.SenderRank} do kanału {demand.Canal}."); } journal.DemandsForSameDirection.Clear(); } journal.Accepts.Clear(); waitForAcceptsHandle.Set(); //zwolnienie blokady } } //Obsłużenie otrzymania żądania if (probeResult.Tag == MSG_DEMAND) { DemandMessage msg = MessageArrays.DemandArrayToMsg(msgArray); journal.CompareTimestampsAndUpdate(msg.Timestamp); journal.IncrementTimestamp(); //Console.WriteLine($"Proces {journal.shipRank}: dostałem DEMAND od procesu {msg.SenderRank}."); bool accept = false; if (msg.Direction != journal.DirectionOfInterest) //jeśli żądany jest przeciwny kierunek do naszego { if (journal.CanalOfInterest == null || msg.Canal != journal.CanalOfInterest.ID) //jeśli żądany jest kanał, który nas nie obchodzi { accept = true; } else if (journal.IsDemandingEntry && (msg.Timestamp < journal.MyDemandTimestamp || (msg.Timestamp == journal.MyDemandTimestamp && msg.SenderRank > journal.shipRank))) //jeśli nie jesteśmy jeszcze w kanale, a konkurujący ma starsze żądanie (niższy timestamp) lub tak samo stare żądanie, lecz wyższą rangę { accept = true; } } else //jeśli żądany jest ten sam kierunek { if (journal.CanalOfInterest == null || msg.Canal != journal.CanalOfInterest.ID) //jeśli żądany jest kanał, który nas nie obchodzi { accept = true; } else if (journal.IsDemandingEntry && (msg.Timestamp < journal.MyDemandTimestamp || (msg.Timestamp == journal.MyDemandTimestamp && msg.SenderRank > journal.shipRank))) //jeśli nie jesteśmy jeszcze w kanale, a konkurujący ma starsze żądanie (niższy timestamp) lub tak samo stare żądanie, lecz wyższą rangę { accept = true; } else if (!journal.IsDemandingEntry && !journal.IsBlockingCanalEntry) //jeśli jesteśmy w kanale (nie ubiegamy się o dostęp), ale nie blokujemy dostępu do kanału { accept = true; } } if (accept) { Canal desiredCanal = journal.ExistingCanals[msg.Canal]; int currentOccupancy = desiredCanal.CurrentOccupancy; int logicalClock = desiredCanal.LogicalClock; List <int> leavingCounters = desiredCanal.LeavingCounters; journal.IncrementTimestamp(); //Console.WriteLine($"Proces {journal.shipRank}: Wysyłam zgodę procesowi {msg.SenderRank} do kanału {msg.Canal}, według mnie leaving counter żądającego w żądanym kanale to {leavingCounters[msg.SenderRank]}."); AcceptMessage acceptMessage = new AcceptMessage(journal.shipRank, journal.Timestamp, currentOccupancy, logicalClock, leavingCounters); int[] acceptArray = MessageArrays.AcceptMsgToArray(acceptMessage); string logString = $"Proces {journal.shipRank}: wysyłana zgoda ma następujące wartości pól - Ranga: {acceptMessage.SenderRank}, Zajętość: {acceptMessage.CurrentOccupancy}, Zegar: {acceptMessage.LogicalClock}, Leaving counters: "; foreach (int process in acceptMessage.LeavingCounters) { logString += $"{process} "; } //Console.WriteLine(logString); comm.Send(acceptArray, msg.SenderRank, MSG_ACCEPT); } else { if (msg.Direction == journal.DirectionOfInterest) { journal.DemandsForSameDirection.Add(msg); } else { journal.DemandsForOppositeDirection.Add(msg); } } } //Obsłużenie otrzymania wiadomości o wyjściu z kanału if (probeResult.Tag == MSG_LEAVE) { LeaveMessage msg = MessageArrays.LeaveArrayToMsg(msgArray); journal.CompareTimestampsAndUpdate(msg.Timestamp); journal.IncrementTimestamp(); Canal canal = journal.ExistingCanals[msg.Canal]; //Jeżeli jeszcze nie wiemy o tym wyjściu if (canal.LeavingCounters[msg.SenderRank] < msg.LeavingCounter) { //Console.WriteLine($"Proces {journal.shipRank}: dostałem LEAVE od procesu {msg.SenderRank} z kanału {msg.Canal}, jego leaving counter to {msg.LeavingCounter}, a mój {canal.LeavingCounters[msg.SenderRank]}."); //Aktualizacja licznika wyjść procesu z kanału canal.LeavingCounters[msg.SenderRank] = msg.LeavingCounter; //Jeśli jesteśmy blokującym procesem w tym kanale, zwalniamy miejsce i wysyłamy zgodę wszystkim na naszej liście oczekujących w tym samym kierunku canal.CurrentOccupancy--; if (journal.CanalOfInterest != null && journal.CanalOfInterest.ID == msg.Canal && journal.IsBlockingCanalEntry) { int currentOccupancy = canal.CurrentOccupancy; int logicalClock = canal.LogicalClock; List <int> leavingCounters = canal.LeavingCounters; journal.IncrementTimestamp(); AcceptMessage accept = new AcceptMessage(journal.shipRank, journal.Timestamp, currentOccupancy, logicalClock, leavingCounters); int[] acceptArray = MessageArrays.AcceptMsgToArray(accept); foreach (DemandMessage demand in journal.DemandsForSameDirection) { comm.Send(acceptArray, demand.SenderRank, MSG_ACCEPT); } journal.IsBlockingCanalEntry = false; journal.DemandsForSameDirection.Clear(); } } } waitForCommunicationHandle.Set(); } }
static void Main(string[] args) { //using (new MPI.Environment(ref args)) //{ // Intracommunicator comm = Communicator.world; // if (comm.Rank == 0) // { // MatrixMultiply mp = new MatrixMultiply(comm.Size, 2); // mp.Show(); // Request sendRequest = comm.ImmediateSend(mp, 1, 0); // Console.WriteLine("Sending MatrixMyltiply"); // Matrix res = mp.MultiplyForRank(comm.Rank); // sendRequest.Wait(); // ReceiveRequest recieveRequest = comm.ImmediateReceive<MatrixMultiply>(Communicator.anySource, 0); // recieveRequest.Wait(); // Console.WriteLine("Recieve MatrixMultiply"); // sendRequest = comm.ImmediateSend(res, 1, 1); // Console.WriteLine("Sending Matrix result"); // sendRequest.Wait(); // recieveRequest = comm.ImmediateReceive<Matrix>(Communicator.anySource, 1); // recieveRequest.Wait(); // res = (Matrix)recieveRequest.GetValue(); // Console.WriteLine("Recieve Matrix result"); // res.Show(); // } // else // { // ReceiveRequest receiveRequest = comm.ImmediateReceive<MatrixMultiply>(comm.Rank - 1, 0); // receiveRequest.Wait(); // MatrixMultiply mp = (MatrixMultiply)receiveRequest.GetValue(); // Request sendRequest = comm.ImmediateSend(mp, (comm.Rank + 1) % comm.Size, 0); // Matrix res = mp.MultiplyForRank(comm.Rank); // sendRequest.Wait(); // receiveRequest = comm.ImmediateReceive<Matrix>(comm.Rank - 1, 1); // receiveRequest.Wait(); // receiveRequest.GetValue(); // sendRequest = comm.ImmediateSend<Matrix>(((Matrix)receiveRequest.GetValue()).Append(res), (comm.Rank + 1) % comm.Size, 1); // sendRequest.Wait(); // } //} using (new MPI.Environment(ref args)) { const int matrixSize = 50; Intracommunicator comm = Communicator.world; if (comm.Rank == 0) { DateTime startTime = DateTime.Now; MatrixMultiply testMultiply = new MatrixMultiply(comm.Size, matrixSize); Matrix result = testMultiply.MultiplyForRank(0); for (int i = 1; i < comm.Size; i++) { result.Append(testMultiply.MultiplyForRank(i)); } DateTime endTime = DateTime.Now; Console.WriteLine("Test multiply" + (startTime - endTime).ToString()); startTime = DateTime.Now; MatrixMultiply mp = new MatrixMultiply(comm.Size, matrixSize); // mp.Show(); Request[] sendRequest = new Request[comm.Size]; for (int i = 1; i < comm.Size; i++) { sendRequest[i] = comm.ImmediateSend(mp, i, 0); } Console.WriteLine("Sending partly MatrixMyltiply"); Matrix res = mp.MultiplyForRank(comm.Rank); for (int i = 1; i < comm.Size; i++) { sendRequest[i].Wait(); } ReceiveRequest[] recieveRequest = new ReceiveRequest[comm.Size]; for (int i = 1; i < comm.Size; i++) { recieveRequest[i] = comm.ImmediateReceive <Matrix>(i, 1); } Console.WriteLine("Recieve partly MatrixMultiply"); for (int i = 1; i < comm.Size; i++) { recieveRequest[i].Wait(); } for (int i = 1; i < comm.Size; i++) { res.Append((Matrix)recieveRequest[i].GetValue()); } //Console.WriteLine("Result is"); // res.Show(); endTime = DateTime.Now; Console.WriteLine("Parallel multiply" + (startTime - endTime).ToString()); } else { ReceiveRequest receiveRequest = comm.ImmediateReceive <MatrixMultiply>(0, 0); receiveRequest.Wait(); MatrixMultiply mp = (MatrixMultiply)receiveRequest.GetValue(); Request sendRequest = comm.ImmediateSend(mp.MultiplyForRank(comm.Rank), 0, 1); sendRequest.Wait(); } } }
public double[] MPIHead(Intracommunicator communicator) { SendMatrixToWorkers(communicator); int parts = communicator.Size - 1; int matrixSize = coefficients.Height; double[] initial = initialStep.GetColumn(0); double currentAccuracy; var portion = matrixSize / parts; int cycleIndex = 0; do { using (var perfCycle = new PerformanceCounter($"Master. Cycle {cycleIndex} work duration: ")) { List <double[]> calculations = new List <double[]>(); for (int part = 0; part < parts; part++) { var start = part * portion; var end = (part + 1) * portion; if (start >= matrixSize) { break; } if (part == parts - 1) { end = matrixSize; } Console.WriteLine($"Part {part} size: {end - start}"); var jobToDo = new JobToDo(start, end, initial); var request = communicator.ImmediateSend(jobToDo, part + 1, (int)JacobyMessageType.CalculatePart); } ReceiveRequest[] requests = new ReceiveRequest[parts]; for (int part = 0; part < parts; part++) { requests[part] = communicator.ImmediateReceive <JobDone>(part + 1, (int)JacobyMessageType.JobDone); } using (var perf = new PerformanceCounter($"Master. Wait for sync (cycle {cycleIndex}): ")) { for (int part = 0; part < parts; part++) { requests[part].Wait(); calculations.Add((requests[part].GetValue() as JobDone).array); } } double[] currentStepXs = Merge(calculations); currentAccuracy = Math.Abs(initial[0] - currentStepXs[0]); for (int row = 0; row < matrixSize; row++) { if (Math.Abs(initialStep[row, 0] - currentStepXs[row]) > currentAccuracy) { currentAccuracy = Math.Abs(initial[row] - currentStepXs[row]); } initial[row] = currentStepXs[row]; } } }while (currentAccuracy > precision); Request[] srequests = new Request[parts]; for (int i = 0; i < parts; i++) { srequests[i] = communicator.ImmediateSend <JobToDo>(new JobToDo(true), i + 1, (int)JacobyMessageType.CalculatePart); } return(initial); }