/*
* 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: ezstart.c,v 6.7 2002/10/09 20:55:33 brbarret Exp $
*
*/
#include <mpi.h>
#include <unistd.h>
#define WORKTAG 1
#define DIETAG 2
#define NUM_WORK_REQS 200
/*
* Local functions
*/
static void master(void);
static void slave(void);
/*
* main
* This program is really MIMD, bit is written SPMD for
* simplicity in launching the application.
*/
int
main(int argc, char* argv[])
{
int myrank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, /* group of everybody */
&myrank); /* 0 thru N-1 */
if (myrank == 0) {
master();
} else {
slave();
}
MPI_Finalize();
return(0);
}
/*
* master
* The master process sends work requests to the slaves
* and collects results.
*/
static void
master(void)
{
int ntasks, rank, work;
double result;
MPI_Status status;
MPI_Comm_size(MPI_COMM_WORLD,
&ntasks); /* #processes in app */
/*
* Seed the slaves.
*/
work = NUM_WORK_REQS; /* simulated work */
for (rank = 1; rank < ntasks; ++rank) {
MPI_Send(&work, /* message buffer */
1, /* one data item */
MPI_INT, /* of this type */
rank, /* to this rank */
WORKTAG, /* a work message */
MPI_COMM_WORLD);/* always use this */
work--;
}
/*
* Receive a result from any slave and dispatch a new work
* request until work requests have been exhausted.
*/
while (work > 0) {
MPI_Recv(&result, /* message buffer */
1, /* one data item */
MPI_DOUBLE, /* of this type */
MPI_ANY_SOURCE, /* from anybody */
MPI_ANY_TAG, /* any message */
MPI_COMM_WORLD, /* communicator */
&status); /* recv'd msg info */
MPI_Send(&work, 1, MPI_INT, status.MPI_SOURCE,
WORKTAG, MPI_COMM_WORLD);
work--; /* simulated work */
}
/*
* Receive results for outstanding work requests.
*/
for (rank = 1; rank < ntasks; ++rank) {
MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
MPI_ANY_TAG, MPI_COMM_WORLD, &status);
}
/*
* Tell all the slaves to exit.
*/
for (rank = 1; rank < ntasks; ++rank) {
MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD);
}
}
/*
* slave
* Each slave process accepts work requests and returns
* results until a special termination request is received.
*/
static void
slave(void)
{
double result;
int work;
MPI_Status status;
for (;;) {
MPI_Recv(&work, 1, MPI_INT, 0, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
/*
* Check the tag of the received message.
*/
if (status.MPI_TAG == DIETAG) {
return;
}
sleep(2);
result = 6.0; /* simulated result */
MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
}
}
syntax highlighted by Code2HTML, v. 0.9.1