コード例 #1
0
ファイル: communications.cpp プロジェクト: optimad/bitpit
/*!
    Discover the receives inspecting the sends that the user has already set.

    \param discoverTag is the tag to be used for the communications needed
    to discover the receives
*/
void DataCommunicator::discoverRecvs(int discoverTag)
{
	// Cancel current receives
	clearAllRecvs();

	// Send the size of the messages that will be send
	for (auto &entry : m_sendIds) {
		int rank = entry.first;
		SendBuffer &buffer = getSendBuffer(rank);
		long dataSize = buffer.capacity();

		MPI_Request dataSizeRequest;
		MPI_Isend(&dataSize, 1, MPI_LONG, rank, discoverTag, m_communicator, &dataSizeRequest);

		// MPI_Isend initiates an asynchronous (background) data transfer.
		// The actual data transfer might not happen unless one of the
		// MPI_Wait* or MPI_Test* calls has been made on the request.
		int completeFlag;
		MPI_Test(&dataSizeRequest, &completeFlag, MPI_STATUS_IGNORE);
	}

	// Raise a barrier to make sure that all the sends starts
	MPI_Barrier(m_communicator);

	// Receive the data size of the sends
	std::unordered_map<int, long> dataSizes;
	while (true) {
		// Probe for messages
		int messageAvailable;
		MPI_Status status;

		MPI_Iprobe(MPI_ANY_SOURCE, discoverTag, m_communicator, &messageAvailable, &status);
		if (!messageAvailable) {
			break;
		}

		// Receive the data size that will be received from the source
		long dataSize;
		MPI_Recv(&dataSize, 1, MPI_LONG, status.MPI_SOURCE, discoverTag, m_communicator, MPI_STATUS_IGNORE);
		dataSizes[status.MPI_SOURCE] = dataSize;
	}

	// Wait that all processors correctly receive the data to communicate.
	//
	// Without the barrier some processors may start the receives while other
	// are still waiting to receive the data sizes. Since the probe for the
	// data size will accept message for all sources, if a processor start
	// receiveing data it will intefere with the other processors still
	// receiving the data sizes.
	if (discoverTag == m_tag) {
		MPI_Barrier(m_communicator);
	}

	// Set the receives
	for (auto &entry : dataSizes) {
		setRecv(entry.first, entry.second);
	}
}
コード例 #2
0
    void sendMsg(unsigned id, F f, O o, Message msg)
    {
        if (hasConnection(id)) {
            PtrBuffer buffer = getSendBuffer(id);
            ostream os(&(*buffer));

            os << msg.serialize() << '\0';

            async_write(*getSocket(id), *buffer,
                        bind(&ConnectionList::_sendMsg<F, O>, this, id, f, o, msg, _1, _2));
        }
    }