MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
proc4.cpp
Go to the documentation of this file.
1 
4 #include <mpi.h>
5 #include <vector>
6 using namespace std;
7 
8 #define WORKTAG 1
9 #define DIETAG 2
10 
11 
12 /* Local functions */
13 
14 const int numEntries = 10;
15 const int totCalls = 2 * 65536;
16 static vector< vector< double > > recvBuf;
17 static int clearPending( int numNodes, int myrank, MPI_Request *recvReq,
18  double& tot );
19 
20 static double* get_next_work_item( int numCalls )
21 {
22  static vector< double > ret( numEntries );
23  for ( int i = 0; i < numEntries; ++i )
24  ret[i] = i + numCalls;
25 
26  if ( numCalls >= totCalls )
27  return 0;
28  return &ret[0];
29 }
30 
31 static double doWork(double* work);
32 
33 int main(int argc, char **argv)
34 {
35  double tot = 0.0;
36  double tc = totCalls;
37  double ne = numEntries;
38  double expectedTot =
39  tc * ( ( ne * (ne - 1.0) )/2.0 ) +
40  ne * ( tc * (tc - 1.0) )/2.0;
41  int myrank;
42  int numNodes;
43 
44  /* Initialize MPI */
45 
46  MPI_Init(&argc, &argv);
47 
48  /* Find out my identity in the default communicator */
49 
50  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
51  MPI_Comm_size(MPI_COMM_WORLD, &numNodes);
52 
53  double sendBuf[numNodes * numEntries];
54  double recvBuf[ numEntries * numNodes ];
55 
56  int numCallsPerNode = totCalls / numNodes;
57 
58  int begin = myrank * numCallsPerNode;
59  int end = begin + numCallsPerNode;
60 
61  int k = 0;
62  for ( int i = 0; i < numCallsPerNode; ++i ) {
63  double* work = get_next_work_item( i + begin );
64  int targetNode = i % numNodes;
65  for ( int j = 0; j < numEntries; ++j ) {
66  sendBuf[targetNode * numEntries + j ] = work[j];
67  }
68 
69  if ( targetNode == numNodes - 1 ) {
70  for ( int j = 0; j < numNodes; ++j ) {
71  MPI_Scatter( sendBuf, numEntries, MPI_DOUBLE,
72  recvBuf, numEntries * (1 + j ), MPI_DOUBLE, j,
73  MPI_COMM_WORLD
74  );
75  tot += doWork( recvBuf );
76  }
77  }
78  }
79  // Final pass to consolidate all the data
80  double totBuf[ numNodes ];
81  MPI_Allgather( &tot, 1, MPI_DOUBLE,
82  totBuf, 1, MPI_DOUBLE,
83  MPI_COMM_WORLD
84  );
85  double subtot = tot;
86  tot = 0;
87  for ( int i = 0; i < numNodes; ++i )
88  {
89  tot += totBuf[i];
90  }
91 
92  cout << myrank << ": Tot = " << tot <<
93  ", expected = " << expectedTot <<
94  ", subtot = " << subtot << endl;
95 
96  /* Shut down MPI */
97 
98  MPI_Finalize();
99  return 0;
100 }
101 
102 
103 static double
104 doWork(double* work)
105 {
106  double tot = 0;
107  for (int i =0; i < numEntries; ++i )
108  tot += work[i];
109 }
static int clearPending(int numNodes, int myrank, MPI_Request *recvReq, double &tot)
const int numEntries
Definition: proc4.cpp:14
const int totCalls
Definition: proc4.cpp:15
static double doWork(double *work)
Definition: proc4.cpp:104
int main(int argc, char **argv)
Definition: proc4.cpp:33
static unsigned int numNodes
static double * get_next_work_item(int numCalls)
Definition: proc4.cpp:20
static vector< vector< double > > recvBuf
Definition: proc4.cpp:16