MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
proc.cpp File Reference
#include <mpi.h>
#include <vector>
+ Include dependency graph for proc.cpp:

Go to the source code of this file.

Macros

#define DIETAG   2
 
#define WORKTAG   1
 

Functions

static double do_work (double *work)
 
static double * get_next_work_item ()
 
int main (int argc, char **argv)
 
static void master (void)
 
static void slave (void)
 

Variables

const int numEntries = 10
 

Macro Definition Documentation

#define DIETAG   2

Definition at line 55 of file proc.cpp.

Referenced by master(), and slave().

#define WORKTAG   1

Definition at line 54 of file proc.cpp.

Referenced by master().

Function Documentation

static double do_work ( double *  work)
static

Definition at line 217 of file proc.cpp.

References numEntries.

Referenced by slave().

218 {
219  double tot = 0;
220  for (int i =0; i < numEntries; ++i )
221  tot += work[i];
222 }
const int numEntries
Definition: proc.cpp:60

+ Here is the caller graph for this function:

static double* get_next_work_item ( )
static

Definition at line 63 of file proc.cpp.

References numEntries.

Referenced by master().

64 {
65 
66  static vector< double > ret( numEntries );
67  static unsigned int numCalls = 0;
68  for ( unsigned int i = 0; i < numEntries; ++i )
69  ret[i] = i + numCalls;
70 
71  numCalls++;
72  if ( numCalls > 1000 )
73  return 0;
74  return &ret[0];
75 }
const int numEntries
Definition: proc.cpp:60

+ Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 79 of file proc.cpp.

References master(), and slave().

80 {
81  int myrank;
82 
83  /* Initialize MPI */
84 
85  MPI_Init(&argc, &argv);
86 
87  /* Find out my identity in the default communicator */
88 
89  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
90  if (myrank == 0) {
91  master();
92  } else {
93  slave();
94  }
95 
96  /* Shut down MPI */
97 
98  MPI_Finalize();
99  return 0;
100 }
static void master(void)
Definition: proc.cpp:105
static void slave(void)
Definition: proc.cpp:187

+ Here is the call graph for this function:

static void master ( void  )
static

Definition at line 105 of file proc.cpp.

References DIETAG, get_next_work_item(), numEntries, and WORKTAG.

Referenced by main().

106 {
107  int ntasks, rank;
108  double* work;
109  double result;
110  MPI_Status status;
111  double tot = 0.0;
112 
113  /* Find out how many processes there are in the default
114  communicator */
115 
116  MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
117 
118  /* Seed the slaves; send one unit of work to each slave. */
119 
120  for (rank = 1; rank < ntasks; ++rank) {
121 
122  /* Find the next item of work to do */
123 
124  work = get_next_work_item();
125 
126  /* Send it to each rank */
127 
128  MPI_Send(work, /* message buffer */
129  numEntries, /* one data item */
130  MPI_DOUBLE, /* data item is a double */
131  rank, /* destination process rank */
132  WORKTAG, /* user chosen message tag */
133  MPI_COMM_WORLD); /* default communicator */
134  }
135 
136  /* Loop over getting new work requests until there is no more work
137  to be done */
138 
139  work = get_next_work_item();
140  while (work != NULL) {
141 
142  /* Receive results from a slave */
143 
144  MPI_Recv(&result, /* message buffer */
145  1, /* one data item */
146  MPI_DOUBLE, /* of type double real */
147  MPI_ANY_SOURCE, /* receive from any sender */
148  MPI_ANY_TAG, /* any type of message */
149  MPI_COMM_WORLD, /* default communicator */
150  &status); /* info about the received message */
151 
152  /* Send the slave a new work unit */
153 
154  MPI_Send(work, /* message buffer */
155  numEntries, /* one data item */
156  MPI_DOUBLE, /* data item is an integer */
157  status.MPI_SOURCE, /* to who we just received from */
158  WORKTAG, /* user chosen message tag */
159  MPI_COMM_WORLD); /* default communicator */
160 
161  /* Get the next unit of work to be done */
162 
163  work = get_next_work_item();
164  tot += result;
165  }
166 
167  /* There's no more work to be done, so receive all the outstanding
168  results from the slaves. */
169 
170  for (rank = 1; rank < ntasks; ++rank) {
171  MPI_Recv(&result, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
172  MPI_ANY_TAG, MPI_COMM_WORLD, &status);
173  tot += result;
174  }
175 
176  /* Tell all the slaves to exit by sending an empty message with the
177  DIETAG. */
178 
179  for (rank = 1; rank < ntasks; ++rank) {
180  MPI_Send(0, 0, MPI_INT, rank, DIETAG, MPI_COMM_WORLD);
181  }
182  cout << "Tot = " << tot << endl;
183 }
static double * get_next_work_item()
Definition: proc.cpp:63
const int numEntries
Definition: proc.cpp:60
#define DIETAG
Definition: proc.cpp:55
#define WORKTAG
Definition: proc.cpp:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void slave ( void  )
static

Definition at line 187 of file proc.cpp.

References DIETAG, do_work(), and numEntries.

Referenced by main().

188 {
189  double work[numEntries];
190  double result;
191  MPI_Status status;
192 
193  while (1) {
194 
195  /* Receive a message from the master */
196 
197  MPI_Recv( work, numEntries, MPI_DOUBLE, 0, MPI_ANY_TAG,
198  MPI_COMM_WORLD, &status);
199 
200  /* Check the tag of the received message. */
201 
202  if (status.MPI_TAG == DIETAG) {
203  return;
204  }
205 
206  /* Do the work */
207 
208  result = do_work(work);
209 
210  /* Send the result back */
211 
212  MPI_Send(&result, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
213  }
214 }
const int numEntries
Definition: proc.cpp:60
#define DIETAG
Definition: proc.cpp:55
static double do_work(double *work)
Definition: proc.cpp:217

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation