Exemple #1
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            int flag;

            unsafe
            {
                // Wait until the request completes
                int errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }

                if (flag == 0)
                {
                    // This request has not completed
                    return(null);
                }
            }

            Cleanup();

            cachedStatus = new CompletedStatus(status, count);
            return(cachedStatus);
        }
Exemple #2
0
        public override void Cancel()
        {
            if (cachedStatus == null)
            {
                Unsafe.MPI_Status status;
                unsafe
                {
                    int errorCode = Unsafe.MPI_Cancel(ref request);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }

                    int flag;
                    errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }

                    if (flag != 0)
                    {
                        cachedStatus = new CompletedStatus(status, 0);
                    }
                }
            }
            Cleanup();
        }
Exemple #3
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            int flag;

            Unsafe.MPI_Status status;
            unsafe
            {
                // If completed, this will set request to null.
                int errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
            }

            if (flag == 0)
            {
                return(null);
            }

            action?.Invoke((T)value);
            Cleanup();
            cachedStatus = new CompletedStatus(status, 1);
            return(cachedStatus);
        }
Exemple #4
0
        /// <summary>
        /// Copies the results from the received array into the user-provided array
        /// and returns a new status object with the appropriate count.
        /// </summary>
        protected CompletedStatus CopyResults(CompletedStatus status)
        {
            if (status == null)
            {
                return(status);
            }

            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            T[] receivedArray = (T[])request.GetValue();
            if (receivedArray.Length > array.Length)
            {
                throw new AccessViolationException("Non-blocking array received overran receive buffer");
            }

            for (int i = 0; i < receivedArray.Length; ++i)
            {
                array[i] = receivedArray[i];
            }

            cachedStatus = new CompletedStatus(status.status, receivedArray.Length);
            return(cachedStatus);
        }
Exemple #5
0
        public override void Cancel()
        {
            if (cachedStatus != null)
            {
                return;
            }

            unsafe
            {
                Unsafe.MPI_Status status;

                int errorCode = Unsafe.MPI_Cancel(ref request);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }

                errorCode = Unsafe.MPI_Wait(ref request, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }

                cachedStatus = new CompletedStatus(status, 0);
            }

            Cleanup();
        }
Exemple #6
0
        public override CompletedStatus Wait()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            int count;
            int errorCode;

            unsafe
            {
                errorCode = Unsafe.MPI_Wait(ref request, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
                errorCode = Unsafe.MPI_Get_count(ref status, FastDatatypeCache <T> .datatype, out count);
            }

            Cleanup();

            if (errorCode != Unsafe.MPI_SUCCESS)
            {
                throw Environment.TranslateErrorIntoException(errorCode);
            }

            cachedStatus = new CompletedStatus(status, count);
            return(cachedStatus);
        }
        //private object lock_recv = new object();

        void handle_RECEIVE(Tuple <int, int> operation, MPI.CompletedStatus status)
        {
            int conversation_tag = operation.Item2;

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_RECEIVE 1 - source=" + status.Source + ", tag=" + conversation_tag);
            Tuple <int, int, int> operation_info;

            //lock (lock_recv)
            this.RootCommunicator.Receive <Tuple <int, int, int> > (status.Source, conversation_tag, out operation_info);

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_RECEIVE 2");

            int operation_type = operation.Item1;
            int facet_src      = this.ThisFacetInstance;
            int facet_dst      = operation_info.Item1;
            int src            = status.Source;
            int dst            = operation_info.Item2;
            int tag            = operation_info.Item3;

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_RECEIVE 3 --- " + facet_src + "," + facet_dst + "," + src + "," + dst + "," + tag);

            EnvelopType envelop = new EnvelopType(operation_type, facet_src, facet_dst, src, dst, tag);

            byte[] message2 = tag < 0 ? synchronizer_monitor.clientSendRequestAnyTag(envelop, new byte[0], ref tag) :
                              synchronizer_monitor.clientSendRequest(envelop, new byte[0]);

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_RECEIVE 4 " + (message2 == null));

            //lock (lock_recv)
            this.RootCommunicator.Send <byte[]>(message2, src, tag);

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_RECEIVE 5");
        }
Exemple #8
0
        void handle_SEND(Tuple <int, int> operation, MPI.CompletedStatus status)
        {
            Console.WriteLine(status.Source + ": handle_SEND 1");

            Tuple <int, int, int, byte[]> operation_info;
            int conversation_tag = operation.Item2;

            this.RootCommunicator.Receive <Tuple <int, int, int, byte[]> > (status.Source, conversation_tag, out operation_info);

            Console.WriteLine(status.Source + ": handle_SEND 2");

            int operation_type = operation.Item1;
            int facet_src      = this.ThisFacet;
            int facet_dst      = operation_info.Item1;
            int src            = status.Source;
            int dst            = operation_info.Item2;
            int tag            = operation_info.Item3;

            Console.WriteLine(status.Source + ": handle_SEND 3 --- " + facet_src + "," + facet_dst + "," + src + "," + dst + "," + tag);

            EnvelopType envelop = new EnvelopType(operation_type, facet_src, facet_dst, src, dst, tag);

            byte[] message1 = operation_info.Item4;
            Console.WriteLine(status.Source + ": handle_SEND 4");

            synchronizer_monitor.clientSendRequest(envelop, message1);
            Console.WriteLine(status.Source + ": handle_SEND 5");
        }
Exemple #9
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            int flag;

            Unsafe.MPI_Status status;
            unsafe
            {
                int errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
            }

            if (flag == 0)
            {
                return(null);
            }
            else
            {
                Cleanup();
                cachedStatus = new CompletedStatus(status, 1);
                return(cachedStatus);
            }
        }
Exemple #10
0
        /// <summary>
        /// Receive an object with a large serialized representation.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="comm"></param>
        /// <param name="source"></param>
        /// <param name="tag"></param>
        /// <param name="value"></param>
        /// <param name="status"></param>
        public static void ReceiveLarge <T>(Communicator comm, int source, int tag, out T value, out CompletedStatus status)
        {
            CompletedStatus innerStatus = default(CompletedStatus);
            bool            done        = false;

            byte[]             leftoverBytes    = null;
            int                leftoverPosition = 0;
            Func <byte[], int> readAction       = delegate(byte[] bytes)
            {
                if (done)
                {
                    return(0);
                }
                int length;
                if (leftoverBytes != null)
                {
                    length = Math.Min(bytes.Length, checked (leftoverBytes.Length - leftoverPosition));
                }
                else
                {
                    comm.Receive(source, tag, out length, out innerStatus);
                }
                if (length < comm.Serialization.BufferSize)
                {
                    done = true;
                }
                if (length == 0)
                {
                    return(0);
                }
                if (leftoverBytes != null)
                {
                    Array.Copy(leftoverBytes, leftoverPosition, bytes, 0, length);
                    checked { leftoverPosition += length; }
                }
                else
                {
                    byte[] array = new byte[length];
                    comm.Receive(source, tag, ref array);
                    if (length > bytes.Length)
                    {
                        length           = bytes.Length;
                        leftoverBytes    = array;
                        leftoverPosition = length;
                        Array.Copy(array, 0, bytes, 0, length);
                    }
                    else
                    {
                        array.CopyTo(bytes, 0);
                    }
                }
                return(length);
            };

            using (var stream = new BufferedStream(new ActionStream(readAction, null), comm.Serialization.BufferSize))
            {
                value = comm.Serialization.Serializer.Deserialize <T>(stream);
            }
            status = innerStatus;
        }
Exemple #11
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            unsafe
            {
                int flag;
                if (requests.header == Unsafe.MPI_REQUEST_NULL)
                {
                    // Test whether the request has completed
                    int errorCode = Unsafe.MPI_Test(ref requests.body, out flag, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }
                }
                else if (requests.body == Unsafe.MPI_REQUEST_NULL)
                {
                    // Test whether the request has completed
                    int errorCode = Unsafe.MPI_Test(ref requests.header, out flag, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }
                }
                else
                {
                    fixed(MPI_Request *requestPtr = &requests.body)
                    {
                        // Test whether both requests completed
                        Unsafe.MPI_Status[] statuses = new Unsafe.MPI_Status[2];
                        {
                            int errorCode = Unsafe.MPI_Testall(2, &requestPtr[0], out flag, statuses);
                            if (errorCode != Unsafe.MPI_SUCCESS)
                            {
                                throw Environment.TranslateErrorIntoException(errorCode);
                            }
                            status = statuses[0];
                        }
                    }
                }

                if (flag == 0)
                {
                    // The communications have not yet completed. We're done here
                    return(null);
                }
            }

            Cleanup();

            cachedStatus = new CompletedStatus(status, this.count);
            return(cachedStatus);
        }
Exemple #12
0
        public override void Cancel()
        {
            if (cachedStatus != null)
            {
                return;
            }

            int errorCode1 = Unsafe.MPI_SUCCESS;
            int errorCode2 = Unsafe.MPI_SUCCESS;

            Unsafe.MPI_Status status = new Unsafe.MPI_Status();
            int flag = 0;

            unsafe
            {
                // Cancel both MPI requests
                if (requests.body != Unsafe.MPI_REQUEST_NULL)
                {
                    errorCode1 = Unsafe.MPI_Cancel(ref requests.body);

                    if (errorCode1 == Unsafe.MPI_SUCCESS)
                    {
                        errorCode1 = Unsafe.MPI_Test(ref requests.body, out flag, out status);
                    }
                }
                if (requests.header != Unsafe.MPI_REQUEST_NULL)
                {
                    errorCode2 = Unsafe.MPI_Cancel(ref requests.header);

                    if (errorCode2 == Unsafe.MPI_SUCCESS)
                    {
                        int myFlag = 0;
                        errorCode2 = Unsafe.MPI_Test(ref requests.body, out myFlag, out status);
                        if (myFlag != 0 && flag == 0)
                        {
                            flag = myFlag;
                        }
                    }
                }
            }

            Cleanup();

            if (errorCode1 != Unsafe.MPI_SUCCESS)
            {
                throw Environment.TranslateErrorIntoException(errorCode1);
            }
            if (errorCode2 != Unsafe.MPI_SUCCESS)
            {
                throw Environment.TranslateErrorIntoException(errorCode2);
            }
            if (flag != 0)
            {
                cachedStatus = new CompletedStatus(status, 0);
            }
        }
Exemple #13
0
        public override CompletedStatus Wait()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            unsafe
            {
                if (requests.header == Unsafe.MPI_REQUEST_NULL)
                {
                    // Wait until the request completes
                    int errorCode = Unsafe.MPI_Wait(ref requests.body, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }
                }
                else if (requests.body == Unsafe.MPI_REQUEST_NULL)
                {
                    // Wait until the request completes
                    int errorCode = Unsafe.MPI_Wait(ref requests.header, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }
                }
                else
                {
                    // Wait until both requests complete
                    Unsafe.MPI_Status[] statuses = new Unsafe.MPI_Status[2];
                    fixed(MPI_Request *requestsPtr = &requests.body)
                    {
                        int errorCode = Unsafe.MPI_Waitall(2, &requestsPtr[0], statuses);

                        if (errorCode != Unsafe.MPI_SUCCESS)
                        {
                            throw Environment.TranslateErrorIntoException(errorCode);
                        }
                        status = statuses[0];
                    }
                }
            }

            Cleanup();

            cachedStatus = new CompletedStatus(status, this.count);
            return(cachedStatus);
        }
Exemple #14
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            int flag;

            Unsafe.MPI_Status status;
            int count = 0;
            int errorCode;

            unsafe
            {
                errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
                if (flag != 0)
                {
                    errorCode = Unsafe.MPI_Get_count(ref status, FastDatatypeCache <T> .datatype, out count);
                }
            }

            if (flag == 0)
            {
                return(null);
            }
            else
            {
                Cleanup();

                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }

                cachedStatus = new CompletedStatus(status, count);
                return(cachedStatus);
            }
        }
Exemple #15
0
        public override CompletedStatus Wait()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            unsafe
            {
                // On normal completion, this will set request to null.
                int errorCode = Unsafe.MPI_Wait(ref request, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
            }

            action?.Invoke((T)value);
            Cleanup();
            cachedStatus = new CompletedStatus(status, 1);
            return(cachedStatus);
        }
Exemple #16
0
        public override void Cancel()
        {
            if (cachedStatus != null)
            {
                return;
            }

            if (request != Unsafe.MPI_REQUEST_NULL)
            {
                unsafe
                {
                    int errorCode = Unsafe.MPI_Cancel(ref request);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }

                    Unsafe.MPI_Status status;
                    errorCode = Unsafe.MPI_Wait(ref request, out status);
                    if (errorCode != Unsafe.MPI_SUCCESS)
                    {
                        throw Environment.TranslateErrorIntoException(errorCode);
                    }

                    cachedStatus = new CompletedStatus(status, 0);
                }
                if (stream == null)
                {
                    handle.Free();
                }
                else
                {
                    stream.Dispose();
                }
                Cleanup();
            }
        }
        void handle_SEND(Tuple <int, int> operation, MPI.CompletedStatus status)
        {
            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_SEND 1 " + operation);

            Tuple <int, int, int, byte[]> operation_info;
            int conversation_tag = operation.Item2;

            //lock (lock_recv)
            this.RootCommunicator.Receive <Tuple <int, int, int, byte[]> > (status.Source, conversation_tag, out operation_info);

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_SEND 2 --- operation = " + operation);

            int operation_type = operation.Item1;
            int facet_src      = this.ThisFacetInstance;
            int facet_dst      = operation_info.Item1;
            int src            = status.Source;
            int dst            = operation_info.Item2;
            int tag            = operation_info.Item3;

            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_SEND 3 --- " + facet_src + "," + facet_dst + "," + src + "," + dst + "," + tag + ", operation = " + operation);

            EnvelopType envelop = new EnvelopType(operation_type, facet_src, facet_dst, src, dst, tag);

            byte[] message1 = operation_info.Item4;
            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_SEND 4 --- operation = " + operation);

            if (tag >= 0 /* tag */)
            {
                synchronizer_monitor.clientSendRequest(envelop, message1);
            }
            else
            {
                synchronizer_monitor.clientSendRequestAnyTag(envelop, message1, ref tag);
            }
            Trace.WriteLineIf(this.TraceFlag == true, status.Source + ": handle_SEND 5 --- operation = " + operation);
        }
Exemple #18
0
        public override CompletedStatus Test()
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            int flag;

            unsafe
            {
                int errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
            }

            if (flag == 0)
            {
                return(null);
            }

            if (stream == null)
            {
                // We completed the receive of the header message.

                // Cleanup this receive
                request = Unsafe.MPI_REQUEST_NULL;
                handle.Free();

                SerializedMessageHeader header = (SerializedMessageHeader)headerObj;
                if (header.bytes == 0)
                {
                    // If the second message is empty, we're done
                    GC.SuppressFinalize(this);
                    cachedStatus = new CompletedStatus(status, 1);
                    return(cachedStatus);
                }

                // Setup the serialized receive and test again, just in case
                SetupSerializedReceive(status);
                return(Test());
            }

            // We completed the receive of the serialized data.

            // Cleanup
            request = Unsafe.MPI_REQUEST_NULL;
            GC.SuppressFinalize(this);

            // Deserialize the data
            try
            {
                BinaryFormatter formatter = new BinaryFormatter();
                value          = (T)formatter.Deserialize(stream);
                status.MPI_TAG = originalTag;
                cachedStatus   = new CompletedStatus(status, 1);
            }
            finally
            {
                stream.Dispose();
            }

            return(cachedStatus);
        }
 void handle_REDUCE(Tuple <int, int> operation, MPI.CompletedStatus status)
 {
     throw new NotImplementedException();
 }
 void handle_GATHER_FLATTENED(Tuple <int, int> operation, MPI.CompletedStatus status)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 ///   Constructs a <code>Status</code> object from a low-level <see cref="Unsafe.MPI_Status"/> structure
 ///   and a count of the number of elements received.
 /// </summary>
 internal CompletedStatus(MPI.CompletedStatus internal_status, Tuple <int, int> source) : base(internal_status, source)
 {
     this.internal_status = internal_status;
 }
        private void listen_worker()
        {
            Tuple <int, int> operation;

            MPI.CompletedStatus status = null;

            Trace.WriteLineIf(this.TraceFlag == true, "listen_workers - WAITING ... " + MPI.Environment.Threading);

            //lock (lock_recv)
            RootCommunicator.Receive <Tuple <int, int> >
                (MPI.Communicator.anySource,
                TAG_SEND_OPERATION,
                out operation,
                out status);

            Trace.WriteLineIf(this.TraceFlag == true, "listen_workers - RECEIVED FROM WORKER source=" + status.Source + ", tag=" + status.Tag + " / operation = " + operation);

            switch (operation.Item1)
            {
            case AliencommunicatorOperation.SEND:
            case AliencommunicatorOperation.SEND_ARRAY:
                (new Thread(() => handle_SEND(operation, status))).Start();
                break;

            case AliencommunicatorOperation.RECEIVE:
            case AliencommunicatorOperation.RECEIVE_ARRAY:
                (new Thread(() => handle_RECEIVE(operation, status))).Start();
                break;

            case AliencommunicatorOperation.PROBE:
                (new Thread(() => handle_PROBE(operation, status))).Start();
                break;

            case AliencommunicatorOperation.ALL_GATHER:
                (new Thread(() => handle_ALL_GATHER(operation, status))).Start();
                break;

            case AliencommunicatorOperation.ALL_GATHER_FLATTENED:
                (new Thread(() => handle_ALL_GATHER_FLATTENED(operation, status))).Start();
                break;

            case AliencommunicatorOperation.ALL_REDUCE:
                handle_ALL_REDUCE(operation, status);
                break;

            case AliencommunicatorOperation.ALL_REDUCE_ARRAY:
                (new Thread(() => handle_ALL_REDUCE(operation, status))).Start();
                break;

            case AliencommunicatorOperation.ALL_TO_ALL:
                (new Thread(() => handle_ALL_TO_ALL(operation, status))).Start();
                break;

            case AliencommunicatorOperation.ALL_TO_ALL_FLATTENED:
                (new Thread(() => handle_ALL_TO_ALL_FLATTENED(operation, status))).Start();
                break;

            case AliencommunicatorOperation.REDUCE_SCATTER:
                (new Thread(() => handle_REDUCE_SCATTER(operation, status))).Start();
                break;

            case AliencommunicatorOperation.BROADCAST:
                (new Thread(() => handle_BROADCAST(operation, status))).Start();
                break;

            case AliencommunicatorOperation.BROADCAST_ARRAY:
                (new Thread(() => handle_BROADCAST(operation, status))).Start();
                break;

            case AliencommunicatorOperation.SCATTER:
                handle_SCATTER(operation, status);
                break;

            case AliencommunicatorOperation.SCATTER_FROM_FLATTENED:
                (new Thread(() => handle_SCATTER_FROM_FLATTENED(operation, status))).Start();
                break;

            case AliencommunicatorOperation.GATHER:
                (new Thread(() => handle_GATHER(operation, status))).Start();
                break;

            case AliencommunicatorOperation.GATHER_FLATTENED:
                (new Thread(() => handle_GATHER_FLATTENED(operation, status))).Start();
                break;

            case AliencommunicatorOperation.REDUCE:
                (new Thread(() => handle_REDUCE(operation, status))).Start();
                break;

            case AliencommunicatorOperation.REDUCE_ARRAY:
                (new Thread(() => handle_REDUCE(operation, status))).Start();
                break;

            default:
                Trace.WriteLineIf(this.TraceFlag == true, "UNRECOGNIZED OPERATION");
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #23
0
        protected CompletedStatus TestOrWait(bool wait)
        {
            if (cachedStatus != null)
            {
                return(cachedStatus);
            }

            Unsafe.MPI_Status status;
            int flag;

            unsafe
            {
                int errorCode;
                if (wait)
                {
                    errorCode = Unsafe.MPI_Wait(ref request, out status);
                    flag      = 1;
                }
                else
                {
                    errorCode = Unsafe.MPI_Test(ref request, out flag, out status);
                }
                if (errorCode != Unsafe.MPI_SUCCESS)
                {
                    throw Environment.TranslateErrorIntoException(errorCode);
                }
            }

            if (flag == 0)
            {
                return(null);
            }

            if (stream == null)
            {
                // We completed the receive of the header message.

                // Cleanup this receive
                handle.Free();

                int length = (int)headerObj;
                if (length == 0)
                {
                    // If the second message is empty, we're done
                    action?.Invoke(value);
                    Cleanup();
                    cachedStatus = new CompletedStatus(status, 1);
                    return(cachedStatus);
                }

                // Setup the serialized receive and test again
                SetupSerializedReceive(status, length);
                return(TestOrWait(wait));
            }

            // We completed the receive of the serialized data.
            status.MPI_TAG = originalTag;
            cachedStatus   = new CompletedStatus(status, 1);

            // Deserialize the data
            try
            {
                value = comm.Serialization.Serializer.Deserialize <T>(stream);
            }
            finally
            {
                stream.Dispose();
                stream = null;
            }
            action?.Invoke(value);

            Cleanup();
            return(cachedStatus);
        }
 public static CompletedStatus createStatus(MPI.CompletedStatus internal_status, Tuple <int, int> source)
 {
     return(new CompletedStatus(internal_status, source));
 }
 /// <summary>
 /// Wait until this non-blocking operation has completed.
 /// </summary>
 /// <returns>
 ///   Information about the completed communication operation.
 /// </returns>
 public CompletedStatus Wait()
 {
     MPI.CompletedStatus internal_status = internal_request.Wait();
     return(CompletedStatus.createStatus(internal_status, source));
 }
 /// <summary>
 /// Determine whether this non-blocking operation has completed.
 /// </summary>
 /// <returns>
 /// If the non-blocking operation has completed, returns information
 /// about the completed communication operation. Otherwise, returns
 /// <c>null</c> to indicate that the operation has not completed.
 /// </returns>
 public CompletedStatus Test()
 {
     MPI.CompletedStatus internal_status = internal_request.Test();
     return(internal_status != null?CompletedStatus.createStatus(internal_status, source) : null);
 }