Example #1
0
        /// <summary>
        /// This method does the modification of the state for the following
        /// rules: R_SR, R_SR*
        /// </summary>
        /// <param name="recvIdx">The index in the _unmatchedRecieves list.</param>
        /// <param name="recvInstr"></param>
        /// <param name="senderRank"></param>
        /// <param name="sendIdx">The index in the _unmatchedSends list.</param>
        private void ProcessRule_Match_SendRecv(int recvIdx, AsyncReceiveInstruction recvInstr, int senderRank, int sendIdx)
        {
            // Get the send instruction
            MpiProcess senderP = GetProcessByRank(senderRank);

            // Look thru the sender's queue to get the match by looking for the
            // first one sent to the receiver.  This way, we ensure the
            // NonOvertaking requirement
            var sendInstr = senderP.SendQueue.FirstOrDefault(instr => instr.ReceiverRank == recvInstr.ReceiverRank);

            Debug.Assert(sendInstr != null, "If an instruction is in the ready queue, it should also be in the process's queue of instructions too.");

            // Since we got the lock open, lets remove it now
            senderP.SendQueue.Remove(sendInstr);

            // Now remove it from the receiver's queue
            recvInstr.Owner.ReceiveQueue.Remove(recvInstr);

            // Match up on our end
            recvInstr.MatchedSend = sendInstr;
            _unmatchedReceives.RemoveAt(recvIdx);
            _matched.Add(recvInstr);

            sendInstr.MatchedReceive = recvInstr;
            _unmatchedSends[senderRank].RemoveAt(sendIdx);
            _matched.Add(sendInstr);

            // And finally, Simulate the completion of the instructions by copying
            // their data
            recvInstr.Payload     = sendInstr.Payload;
            recvInstr.IsCompleted = true;
            // Even if the SendInstr was eager, just set it completed again
            sendInstr.IsCompleted = true;
        }
Example #2
0
        private bool RunRule_MatchDeterministicReceives()
        {
            bool didRuleGetFired = false;

            // Rule: R_SR - match between sends and deterministic receives
            for (int recvIdx = 0; recvIdx < _unmatchedReceives.Count; recvIdx++)
            {
                AsyncReceiveInstruction recvInstr = _unmatchedReceives[recvIdx];

                // Skip any non-deterministic receives (i.e. wildcard receives)
                if (recvInstr.IsWildcardReceive)
                {
                    continue;
                }

                int recverRank = recvInstr.ReceiverRank;
                int senderRank = recvInstr.SenderRank.Value;

                // Make sure that the recvInstr does not have an eligible receive
                // that was issued before it. (e.g. a wildcard receive before it
                // issued from the same MpiProcess)
                //   This check is only important if this recvInstr is not a wildcard receive.
                bool recvInstrHasUnmatchedPredecessor = _unmatchedReceives
                                                        .Take(recvIdx) // Look at all recvInstr before the current one
                                                        .Any(unmatchedRecv => unmatchedRecv.ReceiverRank == recverRank && unmatchedRecv.IsWildcardReceive);

                // Handle the deterministic receives first
                if (!recvInstrHasUnmatchedPredecessor)
                {
                    // before we look at the process and use it's lock, lets see if
                    // we can find it in the ready list first.
                    //   If it's in the list, then we know it's been added to the
                    // process' queues due to the logic in the async methods.
                    int sendIdx = _unmatchedSends[senderRank]
                                  .FindIndex(instr => instr.ReceiverRank == recverRank);
                    if (sendIdx != -1)
                    {
                        // Then we have a match
                        // Rules: R_SR
                        didRuleGetFired = true;

                        ProcessRule_Match_SendRecv(recvIdx, recvInstr, senderRank, sendIdx);

                        // Since we removed an element from the list we are iterating
                        // thru
                        recvIdx--;
                    }
                }
            }

            return(didRuleGetFired);
        }
Example #3
0
        /// <summary>
        ///	Receives a message from the source process.
        ///	See MPI_Irecv in the MPI2 API.
        /// </summary>
        /// <param name="srcRank">The source of the message.  Null specifies a "wildcard receive.</param>
        /// <returns>
        ///	A handle on the receive instruction that can be used with a function call
        ///	to <see cref="Wait(ReceiveHandle)" />.
        ///	</returns>
        public ReceiveHandle ReceiveAsync(int?srcRank)
        {
            if (srcRank.HasValue)
            {
                ValidateRankArgument("srcRank", srcRank.Value);
            }

            AssertProcessCanAccessMpiApi();
            Runtime.DetectCollectiveAbort();

            var instr = new AsyncReceiveInstruction(Process, Process.GetNextInstructionID(), srcRank);

            Process.AddInstructionToHistory(instr);

            AddInstructionToPendingQueue(instr);
            Runtime.NotifyStateChanged();

            return(new ReceiveHandle(instr));
        }
Example #4
0
 internal ReceiveHandle(AsyncReceiveInstruction instr) : base(instr)
 {
 }