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);
        }
Beispiel #2
0
        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!");
                }
            }
        }
Beispiel #3
0
        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++;
                }
            }
        }
Beispiel #5
0
        /// <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();
        }
Beispiel #6
0
    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);
            }
        }    
    }
Beispiel #7
0
    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);
            }
        }
    }
Beispiel #8
0
        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");
                }
            }
        }
Beispiel #9
0
        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();
            }
        }
Beispiel #11
0
        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);
        }