From: W. Trevor King Date: Wed, 15 Sep 2010 16:28:24 +0000 (-0400) Subject: Cleaned up src/MPI2_message_passing/. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=e559d922919e002b53f6edf23c28547d3519f7b7;p=parallel_computing.git Cleaned up src/MPI2_message_passing/. --- diff --git a/content/point_to_point/.html_toc b/content/point_to_point/.html_toc index a6165e9..ab7c2e3 100644 --- a/content/point_to_point/.html_toc +++ b/content/point_to_point/.html_toc @@ -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 index 407035b..0000000 --- a/content/point_to_point/examples/index.shtml +++ /dev/null @@ -1,37 +0,0 @@ - - -

Simple Examples

- -

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.
-
- - diff --git a/content/point_to_point/index.shtml b/content/point_to_point/index.shtml index cc5b6ef..4112f2e 100644 --- a/content/point_to_point/index.shtml +++ b/content/point_to_point/index.shtml @@ -267,11 +267,11 @@ MB/sec (real speed might be ~50MB/sec).

You can measure these communication costs via simple codes that time the send/receive messages. The -program ping_pong.c (see the Edinburgh -notes) does precisely this via the MPI_Wtime() -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.

+program ping_pong.c +(see the Edinburgh notes) does precisely this via +the MPI_Wtime() 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.

@@ -285,4 +285,41 @@ saturates into the network bandwidth.

Read the code, understand it, and run it to reproduce the figures above.

+

Simple Examples

+ +The following message passing examples are bundled in +MPI2_message_passing.tar.gz. + +

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 nodes. All other nodes + 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.
+
+ diff --git a/src/MPI2_message_passing/Makefile b/src/MPI2_message_passing/Makefile new file mode 100644 index 0000000..031c62b --- /dev/null +++ b/src/MPI2_message_passing/Makefile @@ -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 index 0000000..a723280 --- /dev/null +++ b/src/MPI2_message_passing/README @@ -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=" + +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 diff --git a/src/MPI2_message_passing/hop.c b/src/MPI2_message_passing/hop.c index 46be9fe..b95e488 100644 --- a/src/MPI2_message_passing/hop.c +++ b/src/MPI2_message_passing/hop.c @@ -1,58 +1,46 @@ - - /* node identifications */ +/* passing messages to neighbors */ - /* passing a message to neighbors */ - /* Michel Vallieres */ -#include -#include +/* Michel Vallieres */ + +#include +#include 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(); } - - diff --git a/src/MPI2_message_passing/hop_again_again.c b/src/MPI2_message_passing/hop_again_again.c index 36bdb27..00a2163 100644 --- a/src/MPI2_message_passing/hop_again_again.c +++ b/src/MPI2_message_passing/hop_again_again.c @@ -1,75 +1,61 @@ - - /* node identifications */ +/* passing a message to neighbors, multiple hops */ - /* passing a message to neighbors */ - /* multiple hops */ - /* Michel Vallieres */ -#include -#include +/* Michel Vallieres */ -void permute ( int hop, int *my_number, int my_rank, int size ) +#include +#include + +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(); +} diff --git a/src/MPI2_message_passing/ping_pong.c b/src/MPI2_message_passing/ping_pong.c index c0d2c16..ed9920d 100644 --- a/src/MPI2_message_passing/ping_pong.c +++ b/src/MPI2_message_passing/ping_pong.c @@ -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 @@ -11,95 +10,93 @@ * Contact: epcc-tec@epcc.ed.ac.uk * * Purpose: A program to experiment with point-to-point - * communications. + * communications. * * Contents: C source code. * ************************************************************************/ -#include -#include - -#define proc_A 0 -#define proc_B 1 -#define ping 101 -#define pong 101 +#include +#include -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); + } } } - - - - diff --git a/src/MPI2_message_passing/ring.c b/src/MPI2_message_passing/ring.c index c897d96..e03a875 100644 --- a/src/MPI2_message_passing/ring.c +++ b/src/MPI2_message_passing/ring.c @@ -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 -#include -#define tag_right 201 -#define tag_left 102 +#include +#include + +#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(); } - diff --git a/src/MPI2_message_passing/simple_message.c b/src/MPI2_message_passing/simple_message.c index 2865852..00d93b4 100644 --- a/src/MPI2_message_passing/simple_message.c +++ b/src/MPI2_message_passing/simple_message.c @@ -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 -#include +#include +#include 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 -#include +#include +#include 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 -#include +#include +#include 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