/*
* Copyright (c) 2001-2002 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 1998-2001 University of Notre Dame.
* All rights reserved.
* Copyright (c) 1994-1998 The Ohio State University.
* All rights reserved.
*
* This file is part of the LAM/MPI software package. For license
* information, see the LICENSE file in the top level directory of the
* LAM/MPI source distribution.
*
* $HEADER$
*
* $Id: alltoall.c,v 1.4 2002/11/23 04:06:57 jsquyres Exp $
*
* Example program that sends a message from each node each other node
* in a blocking pattern.
*/
#include <stdio.h>
#include <mpi.h>
int
main(int argc, char* argv[])
{
int i;
int rank;
int size;
int tag = 201;
int receive_message;
/* Normal MPI startup */
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Check to ensure that we have 2 ranks */
if (size < 2) {
printf("This program must be run with 2 or more ranks.\n");
MPI_Finalize();
return 1;
}
/* Loop over all ranks */
/* Note that we carefully distinguish between the order of sending
and receiving. It is *not* sufficient to have a single loop
where each rank does a simple "MPI_Send(...); MPI_Recv(...);" --
doing so can lead to deadlock. This is a subtlety in the MPI
standard -- MPI_Send() *may* or *may not* block. In LAM,
MPI_Send() will block if a message is too long; it will wait
until the message has been started to be received on the target
rank. Under that size, MPI_Send() will [most likely] return
immediately regardless of what the target rank is doing.
Note that this is not a LAM-specific issue; every MPI
implementation is coded in this way -- that MPI_Send tries to
complete immediately, but above a certain threshhold (usually
related a combination of message size and the cumulative size of
unreceived messages to that target), MPI_Send may block until the
target rank starts receiving. */
/* Notice also the use of MPI_STATUS_IGNORE. Since this example
program doesn't use the MPI_Status object at all, we use the
special constant MPI_STATUS_IGNORE to tell MPI not to fill it
in. */
/* Finally, notice that this program is actually a poor example of
the all-to-all communication pattern -- there is some degree of
serialization in the sending of messages. For example, rank N
has to wait for rank 0 to send to it before it can continue.
That is, rank 0 causes a daisy-chain of reactions that allow the
rest of the ranks to continue -- each rank will not "start" until
rank 0 contacts it. */
for (i = 0; i < size; i++) {
if (i == rank) {
/* Skip communicating with myself */
printf("Rank %d not sending to myself\n", i);
continue;
} else if (i < rank) {
/* If our rank number is *greater* than the target rank, we send
first, receive second. */
printf("Rank %d sending message \"%d\" to rank %d\n",
rank, rank, i);
MPI_Send(&rank, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
MPI_Recv(&receive_message, 1, MPI_INT, i, tag, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Rank %d received message \"%d\" from rank %d\n",
rank, receive_message, i);
} else {
/* If our rank number is *smaller* than the target rank, we
receive first, send second. */
MPI_Recv(&receive_message, 1, MPI_INT, i, tag, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Rank %d received message \"%d\" from rank %d\n",
rank, receive_message, i);
printf("Rank %d sending message \"%d\" to rank %d\n",
rank, rank, i);
MPI_Send(&rank, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
}
}
/* All done */
printf("Rank %d finished\n", rank);
MPI_Finalize();
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1