Cleaned up src/MPI2_message_passing/.
authorW. Trevor King <wking@drexel.edu>
Wed, 15 Sep 2010 16:28:24 +0000 (12:28 -0400)
committerW. Trevor King <wking@drexel.edu>
Wed, 15 Sep 2010 16:28:24 +0000 (12:28 -0400)
13 files changed:
content/point_to_point/.html_toc
content/point_to_point/examples/index.shtml [deleted file]
content/point_to_point/index.shtml
src/MPI2_message_passing/Makefile [new file with mode: 0644]
src/MPI2_message_passing/README [new file with mode: 0644]
src/MPI2_message_passing/hop.c
src/MPI2_message_passing/hop_again_again.c
src/MPI2_message_passing/ping_pong.c
src/MPI2_message_passing/ring.c
src/MPI2_message_passing/simple_message.c
src/MPI2_message_passing/simplest_message.c
src/MPI2_message_passing/still_simple.c
src/hello_MPI/README

index a6165e9842a74ec67cd16b48069d35de56a20a27..ab7c2e3a496f7d0da726ba0169e350bad6f2b380 100644 (file)
@@ -1,2 +1 @@
-examples
 average_example
diff --git a/content/point_to_point/examples/index.shtml b/content/point_to_point/examples/index.shtml
deleted file mode 100644 (file)
index 407035b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--#set var="root_directory" value="../../.." --><!--#include virtual="$root_directory/shared/header.shtml"-->
-
-<h1>Simple Examples</h1>
-
-<h2 id="communication">Communication</h2>
-
-<dl>
-  <dt><a href="src/simplest_message.c">simplest_message.c</a></dt>
-  <dd>Simplest message passing example — node 0 sends a message
-    to other nodes.</dd>
-  <dt><a href="src/simple_message.c">simple_message.c</a></dt>
-  <dd>Next simplest message passing example — each node (<i>rank
-      != 0</i>) sends a message to node 0</dd>
-  <dt><a href="src/still_simple.c">still_simple.c</a></dt>
-  <dd>Node 0 sends a message to all other nodees.  All other nodees
-    process the message and send result back to node 0.  Nodes form a
-    "ring", each node communicating with its neighbors</dd>
-  <dt><a href="src/hop.c">hop.c</a></dt>
-  <dd>Each node sends a message to right neighbor in a ring.  Note:
-    The blocking version of the routines produces a deadlock in this
-    process.</dd>
-  <dt><a href="src/hop_again_again.c">hop_again_again.c</a></dt>
-  <dd>Each node sends a message to left and right neighbors in a ring
-    fashion again-and-again</dd>
-  <dt><a href="src/ring.c">ring.c</a></dt>
-  <dd>Non-blocking communication example</dd>
-</dl>
-
-<h2 id="time">Communication time</h2>
-
-<dl>
-  <dt><a href="src/ping_pong.c">ping_pong.c</a></dt>
-  <dd>Edinburgh example illustrating the scaling of communication
-    time.</dd>
-</dl>
-
-<!--#include virtual="$root_directory/shared/footer.shtml"-->
index cc5b6ef63a068e568e0d70f23acb907222186127..4112f2e2954f09a2089616c92803feca8fb816e4 100644 (file)
@@ -267,11 +267,11 @@ MB/sec (real speed might be ~50MB/sec).</p>
 
 <p>You can measure these communication costs via simple codes that
 time the send/receive messages. The
-program <a href="src/ping_pong.c">ping_pong.c</a> (see the Edinburgh
-notes) does precisely this via the <code>MPI_Wtime()</code>
-routines. It sends messages of various length back and forth between
-two processes and measures the round trip times. Running this program
-produces the following figures.</p>
+program <a href="../../src/MPI2_message_passing/ping_pong.c">ping_pong.c</a>
+(see the Edinburgh notes) does precisely this via
+the <code>MPI_Wtime()</code> routines. It sends messages of various
+length back and forth between two processes and measures the round
+trip times. Running this program produces the following figures.</p>
 
 <img border="0" src="img/Message_Time_Rates_1.png" width="384" height="372" />
 <img border="0" src="img/Message_Time_Rates_2.png" width="372" height="368" />
@@ -285,4 +285,41 @@ saturates into the network bandwidth.</p>
 <p>Read the code, understand it, and run it to reproduce the figures
 above.</p>
 
+<h2 id="examples">Simple Examples</h2>
+
+The following message passing examples are bundled in
+<a href="../../src/MPI2_message_passing/MPI2_message_passing.tar.gz">MPI2_message_passing.tar.gz</a>.
+
+<h3 id="communication">Communication</h3>
+
+<dl>
+  <dt><a href="../../src/MPI2_message_passing/simplest_message.c">simplest_message.c</a></dt>
+  <dd>Simplest message passing example — node 0 sends a message
+    to other nodes.</dd>
+  <dt><a href="../../src/MPI2_message_passing/simple_message.c">simple_message.c</a></dt>
+  <dd>Next simplest message passing example — each node (<i>rank
+      != 0</i>) sends a message to node 0</dd>
+  <dt><a href="../../src/MPI2_message_passing/still_simple.c">still_simple.c</a></dt>
+  <dd>Node 0 sends a message to all other nodes.  All other nodes
+    process the message and send result back to node 0.  Nodes form a
+    "ring", each node communicating with its neighbors</dd>
+  <dt><a href="../../src/MPI2_message_passing/hop.c">hop.c</a></dt>
+  <dd>Each node sends a message to right neighbor in a ring.  Note:
+    The blocking version of the routines produces a deadlock in this
+    process.</dd>
+  <dt><a href="../../src/MPI2_message_passing/hop_again_again.c">hop_again_again.c</a></dt>
+  <dd>Each node sends a message to left and right neighbors in a ring
+    fashion again-and-again</dd>
+  <dt><a href="../../src/MPI2_message_passing/ring.c">ring.c</a></dt>
+  <dd>Non-blocking communication example</dd>
+</dl>
+
+<h3 id="time">Communication time</h3>
+
+<dl>
+  <dt><a href="../../src/MPI2_message_passing/ping_pong.c">ping_pong.c</a></dt>
+  <dd>Edinburgh example illustrating the scaling of communication
+    time.</dd>
+</dl>
+
 <!--#include virtual="$root_directory/shared/footer.shtml"-->
diff --git a/src/MPI2_message_passing/Makefile b/src/MPI2_message_passing/Makefile
new file mode 100644 (file)
index 0000000..031c62b
--- /dev/null
@@ -0,0 +1,23 @@
+# Environment
+
+CC       = /usr/bin/mpicc
+CFLAGS   =
+LD       = $(CC)
+LDFLAGS  =
+RM       = /bin/rm
+EXECS    = simplest_message simple_message still_simple hop \
+       hop_again_again ring ping_pong
+
+all: $(EXECS)
+
+%.o : %.c
+       $(CC) -c $(CFLAGS) -o $@ $^
+
+$(EXECS) : % : %.o
+       $(LD) $(LDFLAGS) -o $@ $^
+
+clean:
+       $(RM) -f *.o $(EXECS)
+
+# Interesting Makefile sections
+#   4.12.1 Syntax of Static Pattern Rules
diff --git a/src/MPI2_message_passing/README b/src/MPI2_message_passing/README
new file mode 100644 (file)
index 0000000..a723280
--- /dev/null
@@ -0,0 +1,103 @@
+MPI2_message_passing
+====================
+
+Simple demonstrations of message passing in MPI.
+
+Manifest
+--------
+
+Administrative
+~~~~~~~~~~~~~~
+
+- README
+    This file.
+- Makefile
+    Automate building and cleanup.
+
+Communication
+~~~~~~~~~~~~~
+
+- simplest_message.c
+    Simplest message passing example - node 0 sends a message to other nodes.
+- simple_message.c
+    Next simplest message passing example - each node (rank != 0)
+    sends a message to node 0.
+- still_simple.c
+    Node 0 sends a message to all other nodees.  All other nodees
+    process the message and send result back to node 0.  Nodes form a
+    "ring", each node communicating with its neighbors.
+- hop.c
+    Each node sends a message to right neighbor in a ring.  Note: The
+    blocking version of the routines produces a deadlock in this process.
+- hop_again_again.c
+    Each node sends a message to left and right neighbors in a ring
+    fashion again-and-again.
+- ring.c
+    Non-blocking communication example.
+
+Communication time
+~~~~~~~~~~~~~~~~~~
+- ping_pong.c
+    Edinburgh example illustrating the scaling of communication time.
+
+Build
+-----
+
+Just run
+
+    $ make
+
+Usage
+-----
+
+MPI configuration
+~~~~~~~~~~~~~~~~~
+
+You should only have to do this once for each host, but since this is
+your first MPI program, you probably haven't done it yet.  From
+
+    $ man mpd
+
+we have:
+
+  "A file named .mpd.conf file must be present in the user's home
+  directory with read and write access only for the user, and must
+  contain at least a line with MPD_SECRETWORD=<secretword>"
+
+so create the file with a random secret word:
+
+    $ touch ~/.mpd.conf
+    $ chmod 600 ~/.mpd.conf
+    $ echo "MPD_SECRETWORD=$(cat /dev/urandom | tr -d -c A-Z-a-z-0-9 | head -c 60)" ~/.mpd.conf
+
+Running MPI programs
+~~~~~~~~~~~~~~~~~~~~
+
+Create a list of possible hosts `mpd.hosts`, for example
+
+    xphy1.physics.xterm.net
+    xphy2.physics.xterm.net
+    ...
+
+Start the Message Passing Daemons with
+
+    $ mpdboot -f mpd.hosts
+
+which spawns a daemon (`mpd`) on each host.  Then run your program
+(e.g. `simplest_message`) with.
+
+    $ mpiexec -n 4 ./simplest_message
+
+When you're done, clean up the daemons with
+
+    $ mpdallexit
+
+Examples for each of the executables in this package:
+
+    $ mpiexec -n 4 ./simplest_message
+    $ mpiexec -n 4 ./simple_message
+    $ mpiexec -n 4 ./still_simple
+    $ mpiexec -n 4 ./hop
+    $ mpiexec -n 4 ./hop_again_again
+    $ mpiexec -n 4 ./ring
+    $ mpiexec -n 4 ./ping_pong
index 46be9fe7019af1240b45cfbeb0b8286872d32317..b95e4886137d3396cc88da602740c99004da8679 100644 (file)
@@ -1,58 +1,46 @@
-             
-             /*      node identifications      */
+/* passing messages to neighbors */
 
-             /* passing a message to neighbors */
-                                                   /* Michel Vallieres */
-#include   <stdio.h>
-#include   <mpi.h>
+/* Michel Vallieres */
+
+#include <stdio.h>
+#include <mpi.h>
 
 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;
-
-   MPI_Init(&argc, &argv);
-
-   MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
-   MPI_Comm_size(MPI_COMM_WORLD, &size);
-
-                                /*  def my_number */
-   my_number = 2 * my_rank;
-                                /* define hop */
-   hop = 1 ;
-                                /* target node */
-   target_node = my_rank + hop;
-   target_node = target_node % size;
-                                /* from node */
-   from_node = my_rank- hop;
-   from_node = (from_node + size) % size;
-                                /* Print out a message from each processor */
-   fprintf( stderr,
-    "This is process %d out of %d -- target & from: %d %d -- my number %d\n",
-               my_rank, size, target_node, from_node, my_number ); 
-
-                                /* send info to target node */
-                                /*                          */
-                                /* note: a blocking send    */
-                                /* MPI_Ssend produces a     */
-                                /* deadlock in this case    */
-   message = my_number;
-   MPI_Ssend(&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;
-        
-   printf ( " I am process %d  --  my number is now : %d \n",
-                 my_rank, my_number ); 
-
-   MPI_Finalize();
+  int         rank, size;
+  int         number, hop;
+  int         target_node, from_node, count, tag;
+  int         message;
+  MPI_Status  recv_status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  count = 1;  /* only sending a single MPI_INT */
+  tag = 123;  /* arbitrary integer tagging the message */
+
+  number = 2 * rank;                       /* pick a number to pass */
+  hop = 1 ;                                /* define hop, from [0,size) */
+  target_node = (rank + hop) % size;       /* target node */
+  from_node = (rank - hop + size) % size;  /* from node */
+  /* The '+ size' in the from_node calculation ensures a positive from_node. */
+
+  /* Print out a message from each processor */
+  printf("This is process %d out of %d -- target %d, from %d, number %d\n",
+        rank, size, target_node, from_node, number);
+
+  /* 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 */
+
+  printf ("I am process %d  --  my number is now %d\n", rank, number);
+
+  MPI_Finalize();
 }
-
index 36bdb27a1a52dbb4f6922e06cf3abaaf8c4d6e84..00a2163066f9f745a770f0a5e1b8e9d3ccf46b5e 100644 (file)
@@ -1,75 +1,61 @@
-             
-             /*      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();
+}
index c0d2c169ddc7d5ead29693f2a817799ee7367294..ed9920d6dd5920daec445657268e6c78b9a8dd13 100644 (file)
@@ -1,6 +1,5 @@
-
 /************************************************************************
- * This file has been written as a sample solution to an exercise in a 
+ * This file has been written as a sample solution to an exercise in a
  * course given at the Edinburgh Parallel Computing Centre. It is made
  * freely available with the understanding that every copy of this file
  * must include this header and that EPCC takes no responsibility for
  * Contact:     epcc-tec@epcc.ed.ac.uk
  *
  * Purpose:     A program to experiment with point-to-point
- *              communications.   
+ *              communications.
  *
  * Contents:    C source code.
  *
  ************************************************************************/
 
-#include       <stdio.h>
-#include       <mpi.h>
-
-#define proc_A 0
-#define proc_B 1
-#define ping 101
-#define pong 101
+#include <stdio.h>
+#include <mpi.h>
 
-float buffer[100000];
+#define PROCESS_A   0          /* node sending the first ping */
+#define PROCESS_B   1          /* nore receiving the first ping */
+#define TAG_PING    100        /* A -> B messages */
+#define TAG_PONG    101        /* B -> A messages */
+#define BUF_SIZE    100000     /* size of the buffer holding the messages */
+#define MAX_LENGTH  30000      /* maximum message size (must be <= BUF_SIZE */
+#define MIN_LENGTH  1          /* minimum message size */
+#define LENGTH_INCREMENT 1000  /* increase in message size between messages */
+#define NUM_MSGS    100        /* number of messages to pass for each size */
 
-void processor_A (void);
-void processor_B (void);
+void processor_A(void);
+void processor_B(void);
 
-int main ( int argc, char *argv[] )
+int main (int argc, char *argv[])
 {
-     int ierror, rank, size;
-
-     MPI_Init(&argc, &argv);
+  int ierror, rank, size;
 
-     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
-     if (rank == proc_A) processor_A();
-     else if (rank == proc_B) processor_B();
+  if      (rank == PROCESS_A) processor_A();
+  else if (rank == PROCESS_B) processor_B();
+  /* other ranks fall through and die silently */
 
-     MPI_Finalize();
+  MPI_Finalize();
 }
 
-
-void processor_A( void )
+void processor_A(void)
 {
-    int i, ierror;
-    MPI_Status status;
-
-    double start, finish, time;
-
-    extern float buffer[100000];
+  int i, ierror;
+  MPI_Status status;
+  double start, finish, time;
+  float buffer[BUF_SIZE];
+  int length;
 
-    int length;
+  printf("length\ttime per message (s)\ttransfer rate (kB/s)\n");
 
-    printf("Length\tTotal Time\tTransfer Rate\n");
+  for (length = MIN_LENGTH; length <=  MAX_LENGTH; length += LENGTH_INCREMENT)
+    {
+      start = MPI_Wtime();
 
-     for (length = 1; length <=  30000; length += 1000)
-     { 
-        start = MPI_Wtime();
-
-        for (i = 1; i <= 100; i++)
+      for (i=0; i < NUM_MSGS; i++)
         {
-            MPI_Ssend(buffer, length, MPI_FLOAT, proc_B, ping,
-                      MPI_COMM_WORLD);
+         MPI_Ssend(buffer, length, MPI_FLOAT, PROCESS_B, TAG_PING,
+                   MPI_COMM_WORLD);
 
-            MPI_Recv(buffer, length, MPI_FLOAT, proc_B, pong,
-                     MPI_COMM_WORLD, &status);
+         MPI_Recv(buffer, length, MPI_FLOAT, PROCESS_B, TAG_PONG,
+                  MPI_COMM_WORLD, &status);
         }
 
-        finish = MPI_Wtime();
-        time = finish - start;
+      finish = MPI_Wtime();
+      time = finish - start;
 
-       printf("%d\t%f\t%f\n", length, time/200.,
-               (float)(2 * 8 * 100 * length)/time);
+      printf("%d\t%f\t%f\n",
+            length,
+            (float) time / (2 * NUM_MSGS),
+            (2 * NUM_MSGS * sizeof(float) * length) / (1e3 * time));
+      /* 2 to count ping and pong */
     }
 }
 
 
 void processor_B( void )
 {
-    int i, ierror;
-    MPI_Status status;
-    extern float buffer[100000];
-    int length;
-
-    for (length = 1; length <= 30000; length += 1000) 
-    { 
-            for (i = 1; i <= 100; i++) 
-            {
-                MPI_Recv(buffer, length, MPI_FLOAT, proc_A, ping,
-                         MPI_COMM_WORLD, &status);
-
-                MPI_Ssend(buffer, length, MPI_FLOAT, proc_A, pong,
-                         MPI_COMM_WORLD);
-            }
+  int i, ierror;
+  MPI_Status status;
+  float buffer[BUF_SIZE];
+  int length;
+
+  for (length = MIN_LENGTH; length <=  MAX_LENGTH; length += LENGTH_INCREMENT)
+    {
+      for (i=0; i < NUM_MSGS; i++)
+       {
+         MPI_Recv(buffer, length, MPI_FLOAT, PROCESS_A, TAG_PING,
+                  MPI_COMM_WORLD, &status);
+
+         MPI_Ssend(buffer, length, MPI_FLOAT, PROCESS_A, TAG_PONG,
+                   MPI_COMM_WORLD);
+       }
     }
 }
-
-
-
-
index c897d96077c0720c15fe9075006b04d7e6d969fb..e03a875b7cdc7599620d853c2cf13c76ec17d39b 100644 (file)
@@ -1,70 +1,62 @@
-
 /************************************************************************
- * This file has been written as a sample solution to an exercise in a 
+ * This file has been written as a sample solution to an exercise in a
  * course given at the Edinburgh Parallel Computing Centre. It is made
  * freely available with the understanding that every copy of this file
  * must include this header and that EPCC takes no responsibility for
  * the use of the enclosed teaching material.
  *
- * Author:      Joel Malard     
+ * Author:      Joel Malard
  *
  * Contact:     epcc-tec@epcc.ed.ac.uk
  *
- * Purpose:     A program to try out non-blocking point-to-point 
+ * Purpose:     A program to try out non-blocking point-to-point
  *              communications.
  *
  * Contents:    C source code.
  *
  ************************************************************************/
 
-#include       <stdio.h>
-#include       <mpi.h>
-#define tag_right 201
-#define tag_left  102
+#include <stdio.h>
+#include <mpi.h>
+
+#define TAG_RIGHT 123
 
 int main (int argc, char *argv[])
 {
-int ierror, rank, my_rank, size;
-int right, left;
-int other, sum, i;
-int message;
+  int ierror, rank, size;
+  int right, left, count, i;
+  int message, sum;
 
-MPI_Status  send_status;
-MPI_Status  recv_status;
-MPI_Request request;
+  MPI_Status  send_status;
+  MPI_Status  recv_status;
+  MPI_Request request;
 
-    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);
+  count = 1;                        /* only sending a single MPI_INT */
+  right = (rank + 1) % size;
+  left = (rank - 1 + size) % size;  /* the '+ size' ensures 'left >= 0'. */
 
-    right = my_rank + 1;
-    if (right == size) right = 0;
+  sum = 0;
+  message = rank;
 
-    left = my_rank - 1;
-    if (left == -1) left = size-1;
+  for (i=0; i < size; i++) {
+    /* Issend because? */
+    MPI_Issend(&message, count, MPI_INT, right, TAG_RIGHT,
+              MPI_COMM_WORLD, &request);
 
-    sum = 0;
-    message = my_rank;
+    MPI_Recv(&message, count, MPI_INT, left, TAG_RIGHT,
+            MPI_COMM_WORLD, &recv_status);
 
-    for( i = 0; i < size; i++) {
+    /* Wait because? */
+    MPI_Wait(&request, &send_status);
 
-        MPI_Issend(&message, 1, MPI_INT, right, tag_right,
-                   MPI_COMM_WORLD, &request);
-    
-        MPI_Recv(&other, 1, MPI_INT, left, tag_right,
-                 MPI_COMM_WORLD, &recv_status);
-    
-        MPI_Wait(&request, &send_status);
-    
-        sum = sum + other;
-        message = other;
-    
-    }
+    sum += message;
+  }
 
-    printf ("PE%d:\tSum = %d\n", my_rank, sum);
-
-    MPI_Finalize();
+  printf ("PE%d:\tSum = %d\n", rank, sum);
 
+  MPI_Finalize();
 }
-
index 2865852e45764edc75ef246f09d789efb7e2ba10..00d93b4e916a815b88e8e376b49846161e9c7a0b 100644 (file)
@@ -1,44 +1,42 @@
+/* Simplest code to illustrate Message Passing */
+/* Nodes 1 to size-1 send messages to node 0. */
 
-                /*  Simplest code to illustrate  */
-                /*       Message Passing         */
+/* Michel Vallieres */
 
-                /* nodes 1 to size-1 send message to node 0 */
-
-                                                   /* Michel Vallieres */
-#include       <stdio.h>
-#include       <mpi.h>
+#include <stdio.h>
+#include <mpi.h>
 
 int main (int argc, char *argv[])
 {
-int my_rank, size;
-int err, process, send_mesg, recv_mesg;
-
-MPI_Status  recv_status;
+  int rank, size;
+  int err, process, source, count, tag, send_mesg, recv_mesg;
+  MPI_Status recv_status;
 
-    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);
+  count = 1;  /* only sending a single MPI_INT */
+  tag = 123;  /* arbitrary integer tagging the message */
 
-    if ( my_rank == 0 )
-     {
-       for ( process=1; process<size; process++)
+  if (rank == 0)
+    {
+      for (process=1; process < size; process++)
         {
-           err = MPI_Recv(&recv_mesg, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG,
-                 MPI_COMM_WORLD, &recv_status);
-           printf("Received message %d from node %d  \n",
-                 recv_mesg, recv_status.MPI_SOURCE ); 
-           printf("err %d,  ( byte count, tag, and error code were: %d %d %d ) \n",
-                 err, recv_status.count,recv_status.MPI_TAG,
-                 recv_status.MPI_ERROR );
+         err = MPI_Recv(&recv_mesg, count, MPI_INT, MPI_ANY_SOURCE,
+                        MPI_ANY_TAG, MPI_COMM_WORLD, &recv_status);
+         printf("Received message %d from node %d\n",
+                 recv_mesg, recv_status.MPI_SOURCE);
+         printf(" (byte count %d, tag %d, error code %d)\n",
+                recv_status.count, recv_status.MPI_TAG, err);
         }
-     }
-    else
-     {
-        send_mesg=2*my_rank;
-        MPI_Ssend(&send_mesg, 1, MPI_INT, 0, 121, MPI_COMM_WORLD);
-     }
-    
-    
+    }
+  else
+    {
+      process = 0;         /* send to node 0 */
+      send_mesg = 2*rank;
+      MPI_Ssend(&send_mesg, count, MPI_INT, process, tag, MPI_COMM_WORLD);
+    }
+
     MPI_Finalize();
 }
index 30b5bc83bd38052d55aed5a981a67bb73cbf886a..30f137ebe9f37bf14ab39c981d328996e1cb371b 100644 (file)
@@ -1,39 +1,41 @@
-               /*  Simplest code to illustrate  */
-                /*       Message Passing         */
+/* Simplest code to illustrate Message Passing */
+/* Node 0 sends message to other nodes. */
 
-                /* nodes 0 sends message to other nodes */
+/* Michel Vallieres */
 
-                                                   /* Michel Vallieres */
-#include       <stdio.h>
-#include       <mpi.h>
+#include <stdio.h>
+#include <mpi.h>
 
 int main (int argc, char *argv[])
 {
-int my_rank, size;
-int err, process, send_mesg, recv_mesg;
+  int rank, size;
+  int err, process, source, count, tag, send_mesg, recv_mesg;
+  MPI_Status recv_status;
 
-MPI_Status  recv_status;
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
 
-    MPI_Init(&argc, &argv);
+  count = 1;  /* only sending a single MPI_INT */
+  tag = 123;  /* arbitrary integer tagging the message */
 
-    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
-    MPI_Comm_size(MPI_COMM_WORLD, &size);
-
-    if ( my_rank == 0 )
-     {
-       for ( process=1; process<size; process++)
-        {        
-           send_mesg=2*process;
-           err = MPI_Ssend(&send_mesg, 1, MPI_INT, process, 125, MPI_COMM_WORLD );
+  if (rank == 0)
+    {
+      for (process=1; process < size; process++)
+        {
+         send_mesg=2*process;
+         err = MPI_Ssend(&send_mesg, count, MPI_INT, process, tag,
+                         MPI_COMM_WORLD);
         }
-     }
-    else
-     {
-        err = MPI_Recv(&recv_mesg, 1, MPI_INT, 0, MPI_ANY_TAG,
-                                            MPI_COMM_WORLD, &recv_status);
-        printf( "Node %d received message %d (error %d) \n", my_rank, recv_mesg, err );
-     }
-    
-    
-    MPI_Finalize();
+    }
+  else
+    {
+      source = 0;  /* receive from node 0 */
+      err = MPI_Recv(&recv_mesg, count, MPI_INT, source, MPI_ANY_TAG,
+                    MPI_COMM_WORLD, &recv_status);
+      printf("Node %d received message %d (error %d)\n",
+            rank, recv_mesg, err );
+    }
+
+  MPI_Finalize();
 }
index 3ce47c0f4ec3e94e09aa8ed32a90aa650e468368..8ee742f7289c33ee2b1525120da997f7e7b68dab 100644 (file)
@@ -1,64 +1,72 @@
+/* Simple code to illustrate Message Passing */
 
-                /*  Simplest code to illustrate  */
-                /*       Message Passing         */
+/* Node 0 sends a message to all other processes, other nodes process
+ * info and send result back to node 0.
+ *
+ * The trivial operation the nodes preform is to divide a number
+ * (selected by the main program) by their own rank number.
+ */
 
-                /* process 0 sends a message to    */
-                /* all other processes             */
-                /* other processes process info    */
-                /*   send result back to process 0 */
+/* Michel Vallieres */
 
-                /* trivial operation to perfom is to divide*/
-                /* a number (selected by the main program) */
-                /* by the rank number of the process       */
-
-                                                   /* Michel Vallieres */
-#include       <stdio.h>
-#include       <mpi.h>
+#include <stdio.h>
+#include <mpi.h>
 
 int main (int argc, char *argv[])
 {
-int my_rank, size;
-int    process;
-double number, send_mesg, recv_mesg;
-
-MPI_Status  recv_status;
+  int rank, size, err;
+  int process, source, count, tag;
+  double number, send_mesg, recv_mesg;
+  MPI_Status recv_status;
 
-    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);
+  count = 1;  /* only sending a single MPI_INT */
+  tag = 123;  /* arbitrary integer tagging the message */
 
-    if ( my_rank == 0 )
-     {
-       number = 5.167321;                    /* arbitrary number */
-                                             /* send number to other nodes */
-       for ( process=1; process<size; process++)
+  if (rank == 0)
+    {
+      number = 5.167321;  /* arbitrary number */
+      for (process=1; process < size; process++)
         {
-           MPI_Ssend(&number, 1, MPI_DOUBLE, process, 121, MPI_COMM_WORLD);
+         /* send number to other nodes */
+         MPI_Ssend(&number, count, MPI_DOUBLE, process, tag, MPI_COMM_WORLD);
         }
-                                             /* then receive results */
-       for ( process=1; process<size; process++)
-        {
-           MPI_Recv(&recv_mesg, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 99,
-                 MPI_COMM_WORLD, &recv_status);
-           printf("Received message %f from node %d  \n",
-                 recv_mesg, recv_status.MPI_SOURCE ); 
-           printf(" ( byte count, tag, and error code were: %d %d %d ) \n",
-                 recv_status.count,recv_status.MPI_TAG,
-                 recv_status.MPI_ERROR );
+      for (process=1; process < size; process++)
+       {
+         /* receive results */
+         err = MPI_Recv(&recv_mesg, count, MPI_DOUBLE, MPI_ANY_SOURCE, tag,
+                        MPI_COMM_WORLD, &recv_status);
+         printf("Received message %f from node %d\n",
+                 recv_mesg, recv_status.MPI_SOURCE );
+         printf(" (byte count %d, tag %d, error code %d)\n",
+                 recv_status.count,recv_status.MPI_TAG, err);
+         /* Note that we do not use recv_status.MPI_ERROR.
+          * From the MPICH2 Manual, Section 47. Return Status:
+          *   http://www.mpi-forum.org/docs/mpi22-report/node47.htm#Node47
+          *   "In general, message-passing calls do not modify the
+          *   value of the error code field of status variables. This
+          *   field may be updated only by the functions in Section
+          *   Multiple Completions which return multiple
+          *   statuses. The field is updated if and only if such
+          *   function returns with an error code of
+          *   MPI_ERR_IN_STATUS."
+          */
         }
-     }
-    else
-     {
-                                             /* receives message from master */
-        MPI_Recv(&recv_mesg, 1, MPI_DOUBLE, 0, 121,
-                           MPI_COMM_WORLD, &recv_status);
-                                             /* processes info */
-        send_mesg=recv_mesg/my_rank;
-                                             /* sends results back to master */
-        MPI_Ssend(&send_mesg, 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD);
-     }
-    
-    
-    MPI_Finalize();
+    }
+  else
+    {
+      process = 0;  /* communicate with node 0 */
+      /* recieve information */
+      MPI_Recv(&recv_mesg, count, MPI_DOUBLE, process, tag,
+              MPI_COMM_WORLD, &recv_status);
+      /* processes information */
+      send_mesg=recv_mesg/rank;
+      /* sends results back */
+      MPI_Ssend(&send_mesg, count, MPI_DOUBLE, process, tag, MPI_COMM_WORLD);
+    }
+
+  MPI_Finalize();
 }
index e7ddd46444edf3ef9cd4e4a609533d7c603f9716..c3c1ca16178099b5eb3b32d13b595d104e2af1e6 100644 (file)
@@ -62,7 +62,7 @@ Start the Message Passing Daemons with
 which spawns a daemon (`mpd`) on each host.  Then run your program
 (e.g. `hello`) with.
 
-    $ mpiexec -l -n 1 ./hello
+    $ mpiexec -n 1 ./hello
 
 Note that we use ./hello instead of hello or you'll get errors like