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);
        }
 private static void MpiTest(string[] args)
 {
     using (new MPI.Environment(ref args))
     {
         Console.WriteLine("Rank: " +
                           Communicator.world.Rank + "(running on " + MPI.Environment.ProcessorName + ")");
         Intracommunicator comm = Communicator.world;
         if (comm.Rank == 0)
         {
             Request req = comm.ImmediateSend("Rosie", 1, 0);
             Console.WriteLine(req.Test() != null ? "COMPL" : "NOT COMPL");
             string msg = comm.Receive <string>(Communicator.anySource, Communicator.anyTag);
             Console.WriteLine(string.Format("#{0} received message [{1}]", comm.Rank, msg));
             req = comm.ImmediateSend("Rosie", 1, 0);
             Console.WriteLine(req.Test() != null ? "COMPL" : "NOT COMPL");
             msg = comm.Receive <string>(Communicator.anySource, Communicator.anyTag);
             Console.WriteLine(string.Format("#{0} received message [{1}]", comm.Rank, msg));
         }
         else
         {
             string msg = comm.Receive <string>(comm.Rank - 1, 0);
             Console.WriteLine(string.Format("#{0} received message [{1}]", comm.Rank, msg));
             Request req = comm.ImmediateSend(msg + "," + comm.Rank, (comm.Rank + 1) % comm.Size, 0);
             Console.WriteLine(req.Test() != null ? "COMPL" : "NOT COMPL");
             msg = comm.Receive <string>(comm.Rank - 1, 0);
             Console.WriteLine(string.Format("#{0} received message [{1}]", comm.Rank, msg));
             req = comm.ImmediateSend(msg + "," + comm.Rank, (comm.Rank + 1) % comm.Size, 0);
             Console.WriteLine(req.Test() != null ? "COMPL" : "NOT COMPL");
         }
     }
 }
Beispiel #3
0
        public long Send <T> (T message, int to, int tag) where T : IMessage
        {
            Clock++;
            message.Clock = Clock;
            Request sent = _comm.ImmediateSend(message, to, tag);

            sent.Test();
            Logger.LogSent(MyRank, to, tag, Clock);
            return(Clock);
        }
        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++;
                }
            }
        }
        private static void SerializationTest2(string[] args)
        {
            using (new MPI.Environment(ref args))
            {
                Intracommunicator comm = Communicator.world;
                if (comm.Rank == 0)
                {
                    var test = new MonitorMessage <ProdConsInternals <int> >()
                    {
                        InternalState = new ProdConsInternals <int>()
                        {
                            N    = 100,
                            Full = new ConditionalVar()
                            {
                                WaitingQueue = new List <int>()
                                {
                                    1
                                }
                            },
                            Empty = new ConditionalVar()
                            {
                                WaitingQueue = new List <int>()
                                {
                                    2
                                }
                            }
                        },
                        LastCsEntrySyncNumber = 0,
                    };


                    Request req = comm.ImmediateSend(test, 1, 0);
                    req.Test();
                }
                else
                {
                    MonitorMessage <ProdConsInternals <int> > msg = comm.Receive <MonitorMessage <ProdConsInternals <int> > >
                                                                        (Communicator.anySource, Communicator.anyTag);
                    Console.WriteLine(string.Format("#{0} received message [{1}]",
                                                    comm.Rank, msg.InternalState.Full.WaitingQueue.First()));
                }
            }
        }
        public override void synchronize()
        {
            Intracommunicator localComm = mpi.localComm(this);

            int[] ranks_of_collector = mpi.ranksOf(this, "collect");
            int   root_collect       = ranks_of_collector[0];

            double result = data.Value; // mudará para "double[] result".

            int     size = 0;           // result.Length;
            Request req  = localComm.ImmediateSend <int>(size, root_collect, 0);

            localComm.Reduce <double>(result, Operation <double> .Add, root_collect);

            if (/*!req.Test()*/ true)
            {
                req.Cancel();
            }
        } // end activate method
 private static void SerializationTest(string[] args)
 {
     using (new MPI.Environment(ref args))
     {
         Intracommunicator comm = Communicator.world;
         if (comm.Rank == 0)
         {
             ConditionalVar testCon = new ConditionalVar
             {
                 WaitingQueue = new List <int> {
                     1, 2, 3, 4, 5
                 }
             };
             Request req = comm.ImmediateSend(testCon, 1, 0);
             req.Test();
         }
         else
         {
             ConditionalVar msg = comm.Receive <ConditionalVar>(Communicator.anySource, Communicator.anyTag);
             Console.WriteLine(string.Format("#{0} received message [{1}]", comm.Rank, msg.WaitingQueue[0]));
         }
     }
 }
Beispiel #8
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 #9
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 #10
0
        public void go_parallel()
        {
            breaking();

            string input = readInput(TEMP_FILE_PATH + Rank);            //(PATH);

            bool sair = false;

            while (!sair)
            {
                splitMap(input);
                input  = "";
                saidas = new Dictionary <int, string> ();
                sair   = true;
                IEnumerator <string> I = KVPair_OMK_OMV.getIteratorKeys();
                while (I.MoveNext())
                {
                    string key = I.Current;
                    reduce(key, KVPair_OMK_OMV.getList(key));
                    string[] words = valorORV.Split(' ');

                    int task_id = Math.Abs((words[0]).GetHashCode()) % Size;
                    if (task_id == Rank)
                    {
                        input = input + valorORV;
                    }
                    else
                    {
                        if (!saidas.ContainsKey(task_id))
                        {
                            saidas [task_id] = "";
                        }
                        saidas [task_id] = saidas [task_id] + valorORV;
                    }
                    if (sair && chaveORV.Equals("0"))
                    {
                        sair = false;
                    }
                }
                for (int i = 0; i < Size; i++)
                {
                    if (i != Rank)
                    {
                        if (!saidas.ContainsKey(i))
                        {
                            saidas [i] = "";
                        }
                        rlist.Add(worldcomm.ImmediateSend <string> (saidas [i], i, 0));
                    }
                }
                for (int i = 0; i < Size; i++)
                {
                    if (i != Rank)
                    {
                        input = input + worldcomm.Receive <string> (i, 0);
                    }
                }
                rlist.WaitAll();
                int exit = worldcomm.Allreduce <int> (sair ? 1 : 0, MPI.Operation <int> .Min);
                sair = exit == 1;
            }
            Randomize.clearFile(OUTPUT_FILE_PATH + Rank);
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(@OUTPUT_FILE_PATH + Rank, true)){
                file.WriteLine(input);
            }
        }
Beispiel #11
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();
                    }
                }
            }
        }
Beispiel #12
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);
        }