Epetra Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test/MultiVector/cxx_main.cpp
Go to the documentation of this file.
1 //@HEADER
2 // ************************************************************************
3 //
4 // Epetra: Linear Algebra Services Package
5 // Copyright 2011 Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 //@HEADER
41 
42 
43 // Epetra_BlockMap Test routine
44 
45 #include "Epetra_Time.h"
46 #include "Epetra_BlockMap.h"
47 #include "Epetra_MultiVector.h"
48 #ifdef EPETRA_MPI
49 #include "Epetra_MpiComm.h"
50 #include <mpi.h>
51 #else
52 #include "Epetra_SerialComm.h"
53 #endif
54 #include "BuildTestProblems.h"
55 #include "ExecuteTestProblems.h"
56 #include "../epetra_test_err.h"
57 #include "Epetra_Version.h"
58 
59 // Restored MultiVector tests
60 int main(int argc, char *argv[]) {
61 
62  int ierr = 0, i, j;
63 
64 #ifdef EPETRA_MPI
65 
66  // Initialize MPI
67 
68  MPI_Init(&argc,&argv);
69  int rank; // My process ID
70 
71  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
72  Epetra_MpiComm Comm(MPI_COMM_WORLD);
73 
74 #else
75 
76  int rank = 0;
77  Epetra_SerialComm Comm;
78 
79 #endif
80 
81  Comm.SetTracebackMode(0); // This should shut down any error tracing
82  bool verbose = false;
83 
84  // Check if we should print results to standard out
85  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
86 
87  // char tmp;
88  // if (rank==0) cout << "Press any key to continue..."<< endl;
89  // if (rank==0) cin >> tmp;
90  // Comm.Barrier();
91 
92  int MyPID = Comm.MyPID();
93  int NumProc = Comm.NumProc();
94 
95  if (verbose && MyPID==0)
96  cout << Epetra_Version() << endl << endl;
97 
98  if (verbose) cout << Comm <<endl;
99 
100  bool verbose1 = verbose;
101 
102  // Redefine verbose to only print on PE 0
103  if (verbose && rank!=0) verbose = false;
104 
105  int NumMyElements = 10000;
106  int NumMyElements1 = NumMyElements; // Needed for localmap
107  int NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3);
108  if (MyPID < 3) NumMyElements++;
109  int IndexBase = 0;
110  int ElementSize = 7;
111  int NumVectors = 4;
112 
113  // Test LocalMap constructor
114  // and Petra-defined uniform linear distribution constructor
115 
116  if (verbose) cout << "\n*********************************************************" << endl;
117  if (verbose) cout << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl;
118  if (verbose) cout << " and Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm)" << endl;
119  if (verbose) cout << "*********************************************************" << endl;
120 
121  Epetra_LocalMap *LocalMap = new Epetra_LocalMap(NumMyElements1, IndexBase,
122  Comm);
123  Epetra_BlockMap * BlockMap = new Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm);
124  EPETRA_TEST_ERR(MultiVectorTests(*BlockMap, NumVectors, verbose),ierr);
125 
126 
127  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, NumVectors, verbose),ierr);
128 
129  delete BlockMap;
130 
131  // Test User-defined linear distribution constructor
132 
133  if (verbose) cout << "\n*********************************************************" << endl;
134  if (verbose) cout << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm)" << endl;
135  if (verbose) cout << "*********************************************************" << endl;
136 
137  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm);
138 
139  EPETRA_TEST_ERR(MultiVectorTests(*BlockMap, NumVectors, verbose),ierr);
140 
141  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, NumVectors, verbose),ierr);
142 
143  delete BlockMap;
144 
145  // Test User-defined arbitrary distribution constructor
146  // Generate Global Element List. Do in reverse for fun!
147 
148  int * MyGlobalElements = new int[NumMyElements];
149  int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
150  if (Comm.MyPID()>2) MaxMyGID+=3;
151  for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;
152 
153  if (verbose) cout << "\n*********************************************************" << endl;
154  if (verbose) cout << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize, IndexBase, Comm)" << endl;
155  if (verbose) cout << "*********************************************************" << endl;
156 
157  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize,
158  IndexBase, Comm);
159  EPETRA_TEST_ERR(MultiVectorTests(*BlockMap, NumVectors, verbose),ierr);
160 
161  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, NumVectors, verbose),ierr);
162 
163  delete BlockMap;
164 
165  int * ElementSizeList = new int[NumMyElements];
166  int NumMyEquations = 0;
167  int NumGlobalEquations = 0;
168  for (i = 0; i<NumMyElements; i++)
169  {
170  ElementSizeList[i] = i%6+2; // blocksizes go from 2 to 7
171  NumMyEquations += ElementSizeList[i];
172  }
173  ElementSize = 7; // Set to maximum for use in checkmap
174  NumGlobalEquations = Comm.NumProc()*NumMyEquations;
175 
176  // Adjust NumGlobalEquations based on processor ID
177  if (Comm.NumProc() > 3)
178  {
179  if (Comm.MyPID()>2)
180  NumGlobalEquations += 3*((NumMyElements)%6+2);
181  else
182  NumGlobalEquations -= (Comm.NumProc()-3)*((NumMyElements-1)%6+2);
183  }
184 
185  if (verbose) cout << "\n*********************************************************" << endl;
186  if (verbose) cout << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList, IndexBase, Comm)" << endl;
187  if (verbose) cout << "*********************************************************" << endl;
188 
189  BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList,
190  IndexBase, Comm);
191  EPETRA_TEST_ERR(MultiVectorTests(*BlockMap, NumVectors, verbose),ierr);
192 
193  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, NumVectors, verbose),ierr);
194 
195  // Test Copy constructor
196 
197  if (verbose) cout << "\n*********************************************************" << endl;
198  if (verbose) cout << "Checking Epetra_BlockMap(*BlockMap)" << endl;
199  if (verbose) cout << "*********************************************************" << endl;
200 
201  Epetra_BlockMap * BlockMap1 = new Epetra_BlockMap(*BlockMap);
202 
203  EPETRA_TEST_ERR(MultiVectorTests(*BlockMap, NumVectors, verbose),ierr);
204 
205  EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, NumVectors, verbose),ierr);
206 
207  delete [] ElementSizeList;
208  delete [] MyGlobalElements;
209  delete BlockMap;
210  delete BlockMap1;
211 
212 
213  // Test Petra-defined uniform linear distribution constructor
214 
215  if (verbose) cout << "\n*********************************************************" << endl;
216  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl;
217  if (verbose) cout << "*********************************************************" << endl;
218 
219  Epetra_Map * Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm);
220  EPETRA_TEST_ERR(MultiVectorTests(*Map, NumVectors, verbose),ierr);
221 
222  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, NumVectors, verbose),ierr);
223 
224  delete Map;
225 
226  // Test User-defined linear distribution constructor
227 
228  if (verbose) cout << "\n*********************************************************" << endl;
229  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl;
230  if (verbose) cout << "*********************************************************" << endl;
231 
232  Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm);
233 
234  EPETRA_TEST_ERR(MultiVectorTests(*Map, NumVectors, verbose),ierr);
235 
236  EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, NumVectors, verbose),ierr);
237 
238  delete Map;
239 
240  // Test User-defined arbitrary distribution constructor
241  // Generate Global Element List. Do in reverse for fun!
242 
243  MyGlobalElements = new int[NumMyElements];
244  MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase;
245  if (Comm.MyPID()>2) MaxMyGID+=3;
246  for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i;
247 
248  if (verbose) cout << "\n*********************************************************" << endl;
249  if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm)" << endl;
250  if (verbose) cout << "*********************************************************" << endl;
251 
252  Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements,
253  IndexBase, Comm);
254  EPETRA_TEST_ERR(MultiVectorTests(*Map, NumVectors, verbose),ierr);
255 
256  //EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, NumVectors, verbose),ierr);
257 
258  // Test Copy constructor
259 
260  if (verbose) cout << "\n*********************************************************" << endl;
261  if (verbose) cout << "Checking Epetra_Map(*Map)" << endl;
262  if (verbose) cout << "*********************************************************" << endl;
263 
264  Epetra_Map Map1(*Map);
265 
266  EPETRA_TEST_ERR(MultiVectorTests(*Map, NumVectors, verbose),ierr);
267 
268  //EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, NumVectors, verbose),ierr);
269 
270  delete [] MyGlobalElements;
271  delete Map;
272  delete LocalMap;
273 
274  if (verbose1)
275  {
276  // Test MultiVector MFLOPS for 2D Dot Product
277  int M = 27;
278  int N = 27;
279  int K = 10000;
280  Epetra_Map Map2(-1, K, IndexBase, Comm);
281  Epetra_LocalMap Map3(M, IndexBase, Comm);
282 
283  Epetra_MultiVector A(Map2,N);A.Random();
284  Epetra_MultiVector B(Map2,N);B.Random();
285  Epetra_MultiVector C(Map3,N);C.Random();
286 
287  if (verbose) cout << "Testing Assignment operator" << endl;
288 
289  double tmp1 = 1.00001* (double) (MyPID+1);
290  double tmp2 = tmp1;
291  A[1][1] = tmp1;
292  tmp2 = A[1][1];
293  cout << "On PE "<< MyPID << " A[1][1] should equal = " << tmp1;
294  if (tmp1==tmp2) cout << " and it does!" << endl;
295  else cout << " but it equals " << tmp2;
296 
297  Comm.Barrier();
298 
299  if (verbose) cout << "Testing MFLOPs" << endl;
300  Epetra_Flops counter;
301  C.SetFlopCounter(counter);
302  Epetra_Time mytimer(Comm);
303  C.Multiply('T', 'N', 0.5, A, B, 0.0);
304  double Multiply_time = mytimer.ElapsedTime();
305  double Multiply_flops = C.Flops();
306  if (verbose) cout << "\n\nTotal FLOPs = " << Multiply_flops << endl;
307  if (verbose) cout << "Total Time = " << Multiply_time << endl;
308  if (verbose) cout << "MFLOPs = " << Multiply_flops/Multiply_time/1000000.0 << endl;
309 
310  Comm.Barrier();
311 
312  // Test MultiVector ostream operator with Petra-defined uniform linear distribution constructor
313  // and a small vector
314 
315  Epetra_Map Map4(100, IndexBase, Comm);
316  double * Dp = new double[200];
317  for (j=0; j<2; j++)
318  for (i=0; i<100; i++)
319  Dp[i+j*100] = i+j*100;
320  Epetra_MultiVector D(View, Map4,Dp, 100, 2);
321 
322  if (verbose) cout << "\n\nTesting ostream operator: Multivector should be 100-by-2 and print i,j indices"
323  << endl << endl;
324  cout << D << endl;
325 
326  Epetra_BlockMap Map5(-1, 25, 4, IndexBase, Comm);
327  Epetra_MultiVector D1(View, Map5,Dp, 100, 2);
328  if (verbose) cout << "\n\nTesting ostream operator: Same Multivector as before except using BlockMap of 25x4"
329  << endl << endl;
330  cout << D1 << endl;
331 
332  if (verbose) cout << "Traceback Mode value = " << D.GetTracebackMode() << endl;
333  delete [] Dp;
334  }
335 
336 #ifdef EPETRA_MPI
337  MPI_Finalize();
338 #endif
339 
340  return ierr;
341 }
342 
Epetra_MultiVector: A class for constructing and using dense multi-vectors, vectors and matrices in p...
void SetFlopCounter(const Epetra_Flops &FlopCounter_in)
Set the internal Epetra_Flops() pointer.
Epetra_Map: A class for partitioning vectors and matrices.
Definition: Epetra_Map.h:127
int Random()
Set multi-vector values to random numbers.
#define EPETRA_TEST_ERR(a, b)
double ElapsedTime(void) const
Epetra_Time elapsed time function.
static void SetTracebackMode(int TracebackModeValue)
Set the value of the Epetra_Object error traceback report mode.
int MatrixTests(const Epetra_BlockMap &Map, const Epetra_LocalMap &LocalMap, int NumVectors, bool verbose)
#define EPETRA_MIN(x, y)
int MyPID() const
Return my process ID.
Epetra_MpiComm: The Epetra MPI Communication Class.
std::string Epetra_Version()
Epetra_Time: The Epetra Timing Class.
Definition: Epetra_Time.h:83
int MultiVectorTests(const Epetra_Map &Map, int NumVectors, bool verbose)
Epetra_BlockMap: A class for partitioning block element vectors and matrices.
int NumProc() const
Returns total number of processes (always returns 1 for SerialComm).
Epetra_SerialComm: The Epetra Serial Communication Class.
Epetra_Flops: The Epetra Floating Point Operations Class.
Definition: Epetra_Flops.h:66
int Multiply(char TransA, char TransB, double ScalarAB, const Epetra_MultiVector &A, const Epetra_MultiVector &B, double ScalarThis)
Matrix-Matrix multiplication, this = ScalarThis*this + ScalarAB*A*B.
void Barrier() const
Epetra_SerialComm Barrier function.
static int GetTracebackMode()
Get the value of the Epetra_Object error report mode.
double Flops() const
Returns the number of floating point operations with this multi-vector.
int main(int argc, char *argv[])
Epetra_LocalMap: A class for replicating vectors and matrices across multiple processors.