-
- /* node identifications */
+/* passing a message to neighbors, multiple hops */
- /* passing a message to neighbors */
- /* multiple hops */
- /* Michel Vallieres */
-#include <stdio.h>
-#include <mpi.h>
+/* Michel Vallieres */
-void permute ( int hop, int *my_number, int my_rank, int size )
+#include <stdio.h>
+#include <mpi.h>
+
+void permute (int hop, int *number, int rank, int size)
{
-MPI_Status recv_status;
-int target_node, from_node;
-int message;
- /* target node */
- target_node = my_rank + hop;
- target_node = (target_node +size) % size;
- /* from node */
- from_node = my_rank- hop;
- from_node = (from_node + size) % size;
- /* send info to target node */
- /* */
- /* note: a blocking send */
- /* MPI_Ssend will node lock */
- /* in this case */
- message = *my_number;
- MPI_Send(&message, 1, MPI_INT, target_node, 121, MPI_COMM_WORLD);
- /* receive new number from the */
- /* - from node - */
- MPI_Recv(&message, 1, MPI_INT, from_node, 121,
- MPI_COMM_WORLD, &recv_status);
- /* update my_number */
- *my_number = message;
+ MPI_Status recv_status;
+ int target_node, from_node, count, tag;
+ int message;
+
+ count = 1; /* only sending a single MPI_INT */
+ tag = 123; /* arbitrary integer tagging the message */
+
+ target_node = (rank + hop + size) % size; /* target node */
+ from_node = (rank - hop + size) % size; /* from node */
+ /* The '+ size' ensures positive nodes for hops in the range (-size,size). */
+
+ /* Send info to target node. Note: a blocking send MPI_Ssend
+ * produces a deadlock in this case. */
+ message = *number;
+ MPI_Send(&message, count, MPI_INT, target_node, tag, MPI_COMM_WORLD);
+
+ /* Receive new number from the from node. */
+ MPI_Recv(&message, count, MPI_INT, from_node, tag,
+ MPI_COMM_WORLD, &recv_status);
+ *number = message; /* update number */
}
-
int main (int argc, char *argv[])
{
-int my_rank, size;
-MPI_Status recv_status;
-int my_number, hop;
-int target_node, from_node;
-int message;
+ int rank, size;
+ int number, hop;
- MPI_Init(&argc, &argv);
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
- MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
- MPI_Comm_size(MPI_COMM_WORLD, &size);
+ number = 2 * rank; /* pick a number to pass */
- /* def my_number */
- my_number = 2 * my_rank;
-
- printf ( " I am process %d -- my number is : %d \n",
- my_rank, my_number );
+ printf ("0: I am process %d -- my number is %d\n", rank, number);
- /* first hop */
- hop = 1;
- permute( hop, &my_number, my_rank, size );
- printf ( " I am process %d -- my number is : %d \n",
- my_rank, my_number );
- /* second hop */
- hop = -2;
- permute( hop, &my_number, my_rank, size );
- printf ( " I am process %d -- my number is : %d \n",
- my_rank, my_number );
- /* third hop */
- hop = 1;
- permute( hop, &my_number, my_rank, size );
- printf ( " I am process %d -- my number is : %d \n",
- my_rank, my_number );
+ /* first hop */
+ hop = 1;
+ permute(hop, &number, rank, size);
+ printf("1: I am process %d -- my number is %d\n", rank, number);
- MPI_Finalize();
-}
+ /* second hop */
+ hop = -2;
+ permute(hop, &number, rank, size);
+ printf("2: I am process %d -- my number is %d\n", rank, number);
-
+ /* third hop */
+ hop = 1;
+ permute(hop, &number, rank, size);
+ printf("3: I am process %d -- my number is %d \n", rank, number);
+
+ MPI_Finalize();
+}