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); }
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); } }
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); }
/// <summary> /// Given the header data, this routine will set up the receive of the /// serialized data. /// </summary> /// <param name="status"> /// The status message returned from the completion of the first /// receive (of the header data). /// </param> /// <param name="length">Number of bytes to receive.</param> protected void SetupSerializedReceive(Unsafe.MPI_Status status, int length) { // Save the tag originalTag = status.MPI_TAG; // Create the stream stream = new UnmanagedMemoryStream(length); unsafe { // Receive serialized data int errorCode = Unsafe.MPI_Irecv(stream.Buffer, length, Unsafe.MPI_BYTE, status.MPI_SOURCE, originalTag, comm.comm, out request); if (errorCode != Unsafe.MPI_SUCCESS) { stream.Dispose(); throw Environment.TranslateErrorIntoException(errorCode); } } }
/// <summary> /// Given the header data, this routine will set up the receive of the /// serialized data on the shadow communicator. /// </summary> /// <param name="status"> /// The status message returned from the completion of the first /// receive (of the header data). /// </param> protected void SetupSerializedReceive(Unsafe.MPI_Status status) { // Save the tag originalTag = status.MPI_TAG; // Extract the header SerializedMessageHeader header = (SerializedMessageHeader)headerObj; // Create the stream stream = new UnmanagedMemoryStream(header.bytes); unsafe { // Receive serialized data via the shadow communicator int errorCode = Unsafe.MPI_Irecv(stream.Buffer, header.bytes, Unsafe.MPI_BYTE, status.MPI_SOURCE, header.tag, shadowComm, out request); if (errorCode != Unsafe.MPI_SUCCESS) { stream.Dispose(); throw Environment.TranslateErrorIntoException(errorCode); } } }
/// <summary> /// Constructs a <code>Status</code> object from a low-level <see cref="Unsafe.MPI_Status"/> structure. /// </summary> internal Status(Unsafe.MPI_Status status) { this.status = status; }
/// <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(Unsafe.MPI_Status status, int count) : base(status) { this.count = count; }