MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
proc.cpp
Go to the documentation of this file.
1 /*
2 void process( const Eref& e, ProcPtr p )
3 {
4  for ( unsigned int i = 0; i < numNodes; ++i ){
5  if ( i != myNode ) {
6  isend( outbuf_[i] );
7 
8  inbufNum = recv(from anywhere)
9  readBuf( inbuf_[inbufNum] );
10  }
11  }
12 }
13 
14 vector< vector< double > > outBuf_; // outbuf[tgtnode][data]
15 vector< vector< double > > inBuf_;// inbuf[srcnode][data]
16 
17 
18 // Things to monitor:
19 // - The send happens with a standard buf size, and if the contents
20 // exceed it there is a signal to this effect and the rest of it is sent
21 // right away as a big block.
22 // - The Recv likewise
23 //
24 // mpi_testsome checks which msgs have been received.
25 //
26 //
27 
28 // Assumes we already have an irecv out for all the nodes.
29 //
30 void checkIncoming()
31 {
32  MPI_request* array_of_requests;
33  MPI_status* array_of_statuses;
34 
35  MPI_testsome()
36  int MPI_Testsome(int incount, MPI_Request array_of_requests[],
37  int *outcount, int array_of_indices[], MPI_Status array_of_statuses[])
38 
39  for ( unsigned int
40 
41  MPI_Irecv (&buf,count,datatype,source,tag,comm,&request)
42 }
43 
44 
45 main()
46 {
47 }
48 */
49 
50 #include <mpi.h>
51 #include <vector>
52 using namespace std;
53 
54 #define WORKTAG 1
55 #define DIETAG 2
56 
57 
58 /* Local functions */
59 
60 const int numEntries = 10;
61 static void master(void);
62 static void slave(void);
63 static double* get_next_work_item()
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 }
76 
77 static double do_work(double* work);
78 
79 int main(int argc, char **argv)
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 }
101 
102 
103 
104 static void
105 master(void)
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 }
184 
185 
186 static void
187 slave(void)
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 }
215 
216 static double
217 do_work(double* work)
218 {
219  double tot = 0;
220  for (int i =0; i < numEntries; ++i )
221  tot += work[i];
222 }
static void master(void)
Definition: proc.cpp:105
static double * get_next_work_item()
Definition: proc.cpp:63
static void slave(void)
Definition: proc.cpp:187
const int numEntries
Definition: proc.cpp:60
int main(int argc, char **argv)
Definition: proc.cpp:79
#define DIETAG
Definition: proc.cpp:55
#define WORKTAG
Definition: proc.cpp:54
static double do_work(double *work)
Definition: proc.cpp:217