Epetra Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test/Directory/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_Map.h"
48 #ifdef EPETRA_MPI
49 #include "Epetra_MpiComm.h"
50 #include <mpi.h>
51 #endif
52 #include "Epetra_SerialComm.h"
53 #include "Epetra_Util.h"
54 #include "../epetra_test_err.h"
55 #include "Epetra_Version.h"
56 #include "Epetra_Directory.h"
57 
58 int directory_test_1(Epetra_Comm& Comm);
59 int directory_test_2(Epetra_Comm& Comm);
60 int directory_test_3(Epetra_Comm& Comm);
61 int directory_test_4(Epetra_Comm& Comm);
62 int directory_test_5(Epetra_Comm& Comm);
63 
64 int main(int argc, char *argv[]) {
65  bool verbose = false;
66  // Check if we should print results to standard out
67  if (argc > 1) {
68  if ((argv[1][0] == '-') && (argv[1][1] == 'v')) {
69  verbose = true;
70  }
71  }
72 
73  int returnierr = 0;
74 
75 #ifdef EPETRA_MPI
76 
77  // Initialize MPI
78  MPI_Init(&argc,&argv);
79  Epetra_MpiComm Comm(MPI_COMM_WORLD);
80 #else
81  Epetra_SerialComm Comm;
82 #endif
83 
84  if (!verbose) {
85  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
86  }
87  int MyPID = Comm.MyPID();
88 
89  int verbose_int = verbose ? 1 : 0;
90  Comm.Broadcast(&verbose_int, 1, 0);
91  verbose = verbose_int==1 ? true : false;
92 
93  if (verbose && MyPID==0)
94  cout << Epetra_Version() << endl << endl;
95 
96  EPETRA_TEST_ERR( directory_test_1(Comm), returnierr );
97 
98  EPETRA_TEST_ERR( directory_test_2(Comm), returnierr );
99 
100  EPETRA_TEST_ERR( directory_test_3(Comm), returnierr );
101 
102  EPETRA_TEST_ERR( directory_test_4(Comm), returnierr );
103 
104  EPETRA_TEST_ERR( directory_test_5(Comm), returnierr );
105 
106 #ifdef EPETRA_MPI
107  MPI_Finalize();
108 #endif
109 
110  if (MyPID == 0) {
111  if (returnierr == 0) {
112  cout << "Epetra_Directory tests passed."<<endl;
113  }
114  else {
115  cout << "Epetra_Directory tests failed."<<endl;
116  }
117  }
118 
119  return returnierr;
120 }
121 
123 {
124  //set up a map with arbitrary distribution of IDs, but with unique
125  //processor ID ownership (i.e., each ID only appears on 1 processor)
126 
127  int myPID = Comm.MyPID();
128  int numProcs = Comm.NumProc();
129 
130  if (numProcs < 2) return(0);
131 
132  int myFirstID = (myPID+1)*(myPID+1);
133  int myNumIDs = 3+myPID;
134 
135  int* myIDs = new int[myNumIDs];
136  int i;
137  for(i=0; i<myNumIDs; ++i) {
138  myIDs[i] = myFirstID+i;
139  }
140 
141  Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
142 
143  Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
144 
145  int proc = myPID+1;
146  if (proc >= numProcs) proc = 0;
147 
148  int procNumIDs = 3+proc;
149  int procFirstID = (proc+1)*(proc+1);
150  int procLastID = procFirstID+procNumIDs - 1;
151 
152  int queryProc1 = -1;
153  int queryProc2 = -1;
154 
155  int err = directory->GetDirectoryEntries(blkmap, 1, &procFirstID,
156  &queryProc1, NULL, NULL);
157  err += directory->GetDirectoryEntries(blkmap, 1, &procLastID,
158  &queryProc2, NULL, NULL);
159  delete directory;
160  delete [] myIDs;
161 
162  if (queryProc1 != proc || queryProc2 != proc) {
163  return(-1);
164  }
165 
166  return(0);
167 }
168 
170 {
171  //set up a Epetra_BlockMap with arbitrary distribution of IDs, but with unique
172  //processor ID ownership (i.e., each ID only appears on 1 processor)
173  //
174  //the thing that makes this Epetra_BlockMap nasty is that higher-numbered
175  //processors own lower IDs.
176 
177  int myPID = Comm.MyPID();
178  int numProcs = Comm.NumProc();
179 
180  if (numProcs < 2) return(0);
181 
182  int myFirstID = (numProcs-myPID)*(numProcs-myPID);
183  int myNumIDs = 3;
184 
185  int* myIDs = new int[myNumIDs];
186  int i;
187  for(i=0; i<myNumIDs; ++i) {
188  myIDs[i] = myFirstID+i;
189  }
190 
191  Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
192 
193  Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
194 
195  int proc = myPID+1;
196  if (proc >= numProcs) proc = 0;
197 
198  int procNumIDs = 3;
199  int procFirstID = (numProcs-proc)*(numProcs-proc);
200  int procLastID = procFirstID+procNumIDs - 1;
201 
202  int queryProc1 = -1;
203  int queryProc2 = -1;
204 
205  int err = directory->GetDirectoryEntries(blkmap, 1, &procFirstID,
206  &queryProc1, NULL, NULL);
207  err += directory->GetDirectoryEntries(blkmap, 1, &procLastID,
208  &queryProc2, NULL, NULL);
209  delete directory;
210  delete [] myIDs;
211 
212  if (queryProc1 != proc || queryProc2 != proc) {
213  return(-1);
214  }
215 
216  return(0);
217 }
218 
220 {
221  //set up a map with arbitrary distribution of IDs, including non-unique
222  //processor ID ownership (i.e., some IDs appear on more than 1 processor)
223 
224  int myPID = Comm.MyPID();
225  int numProcs = Comm.NumProc();
226 
227  if (numProcs < 2) return(0);
228 
229  int myFirstID = (myPID+1)*(myPID+1);
230  int myNumIDs = 4;
231 
232  int* myIDs = new int[myNumIDs];
233  int i;
234  for(i=0; i<myNumIDs-1; ++i) {
235  myIDs[i] = myFirstID+i;
236  }
237 
238  int nextProc = myPID+1;
239  if (nextProc >= numProcs) nextProc = 0;
240 
241  int nextProcFirstID = (nextProc+1)*(nextProc+1);
242  myIDs[myNumIDs-1] = nextProcFirstID;
243 
244  Epetra_BlockMap blkmap(-1, myNumIDs, myIDs, 1, 0, Comm);
245 
246  Epetra_Directory* directory = Comm.CreateDirectory(blkmap);
247 
248  bool uniqueGIDs = directory->GIDsAllUniquelyOwned();
249 
250  delete directory;
251  delete [] myIDs;
252 
253  if (uniqueGIDs) {
254  return(-1);
255  }
256 
257  return(0);
258 }
259 
261 {
262  int myPID = Comm.MyPID();
263  int numProcs = Comm.NumProc();
264 
265  if (numProcs < 2) return(0);
266 
267  //Set up a map with overlapping ranges of GIDs.
268  int num = 5;
269  int numMyGIDs = 2*num;
270  int myFirstGID = myPID*num;
271 
272  int* myGIDs = new int[numMyGIDs];
273 
274  for(int i=0; i<numMyGIDs; ++i) {
275  myGIDs[i] = myFirstGID+i;
276  }
277 
278  Epetra_Map overlappingmap(-1, numMyGIDs, myGIDs, 0, Comm);
279 
280  delete [] myGIDs;
281 
282  int numGlobal0 = overlappingmap.NumGlobalElements();
283 
284  Epetra_Map uniquemap1 =
285  Epetra_Util::Create_OneToOne_Map(overlappingmap);
286 
287  bool use_high_sharing_proc = true;
288 
289  Epetra_Map uniquemap2 =
290  Epetra_Util::Create_OneToOne_Map(overlappingmap, use_high_sharing_proc);
291 
292  int numGlobal1 = uniquemap1.NumGlobalElements();
293  int numGlobal2 = uniquemap2.NumGlobalElements();
294 
295  //The two one-to-one maps should have the same number of global elems.
296  if (numGlobal1 != numGlobal2) {
297  return(-1);
298  }
299 
300  //The number of global elems should be greater in the original map
301  //than in the one-to-one map.
302  if (numGlobal0 <= numGlobal1) {
303  return(-2);
304  }
305 
306  int numLocal1 = uniquemap1.NumMyElements();
307  int numLocal2 = uniquemap2.NumMyElements();
308 
309  //If this is proc 0 or proc numProcs-1, then the number of
310  //local elements should be different in the two one-to-one maps.
311  if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
312  return(-3);
313  }
314 
315  return(0);
316 }
317 
319 {
320  int myPID = Comm.MyPID();
321  int numProcs = Comm.NumProc();
322 
323  if (numProcs < 2) return(0);
324 
325  //Set up a map with overlapping ranges of GIDs.
326  int num = 5;
327  int numMyGIDs = 2*num;
328  int myFirstGID = myPID*num;
329 
330  int* myGIDs = new int[numMyGIDs];
331  int* sizes = new int[numMyGIDs];
332 
333  for(int i=0; i<numMyGIDs; ++i) {
334  myGIDs[i] = myFirstGID+i;
335  sizes[i] = myFirstGID+i+1;
336  }
337 
338  Epetra_BlockMap overlappingmap(-1, numMyGIDs, myGIDs, sizes, 0, Comm);
339 
340  delete [] myGIDs;
341  delete [] sizes;
342 
343  int numGlobal0 = overlappingmap.NumGlobalElements();
344 
345  Epetra_BlockMap uniquemap1 =
347 
348  bool use_high_sharing_proc = true;
349 
350  Epetra_BlockMap uniquemap2 =
351  Epetra_Util::Create_OneToOne_BlockMap(overlappingmap, use_high_sharing_proc);
352 
353  int numGlobal1 = uniquemap1.NumGlobalElements();
354  int numGlobal2 = uniquemap2.NumGlobalElements();
355 
356  //The two one-to-one maps should have the same number of global elems.
357  if (numGlobal1 != numGlobal2) {
358  return(-1);
359  }
360 
361  //The number of global elems should be greater in the original map
362  //than in the one-to-one map.
363  if (numGlobal0 <= numGlobal1) {
364  return(-2);
365  }
366 
367  int numLocal1 = uniquemap1.NumMyElements();
368  int numLocal2 = uniquemap2.NumMyElements();
369 
370  //If this is proc 0 or proc numProcs-1, then the number of
371  //local elements should be different in the two one-to-one maps.
372  if ((myPID==0 || myPID==numProcs-1) && numLocal1 == numLocal2) {
373  return(-3);
374  }
375 
376  return(0);
377 }
int NumGlobalElements() const
Number of elements across all processors.
Epetra_Map: A class for partitioning vectors and matrices.
Definition: Epetra_Map.h:127
int directory_test_3(Epetra_Comm &Comm)
static Epetra_Map Create_OneToOne_Map(const Epetra_Map &usermap, bool high_rank_proc_owns_shared=false)
Epetra_Util Create_OneToOne_Map function.
#define EPETRA_TEST_ERR(a, b)
virtual Epetra_Directory * CreateDirectory(const Epetra_BlockMap &Map) const =0
Create a directory object for the given Epetra_BlockMap.
static void SetTracebackMode(int TracebackModeValue)
Set the value of the Epetra_Object error traceback report mode.
virtual bool GIDsAllUniquelyOwned() const =0
GIDsAllUniquelyOwned: returns true if all GIDs appear on just one processor.
int MyPID() const
Return my process ID.
Epetra_MpiComm: The Epetra MPI Communication Class.
virtual int GetDirectoryEntries(const Epetra_BlockMap &Map, const int NumEntries, const int *GlobalEntries, int *Procs, int *LocalEntries, int *EntrySizes, bool high_rank_sharing_procs=false) const =0
GetDirectoryEntries : Returns proc and local id info for non-local map entries.
std::string Epetra_Version()
int directory_test_4(Epetra_Comm &Comm)
virtual int MyPID() const =0
Return my process ID.
int NumMyElements() const
Number of elements on the calling processor.
Epetra_Directory: This class is a pure virtual class whose interface allows Epetra_Map and Epetr_Bloc...
static Epetra_BlockMap Create_OneToOne_BlockMap(const Epetra_BlockMap &usermap, bool high_rank_proc_owns_shared=false)
Epetra_Util Create_OneToOne_Map function.
Epetra_Comm: The Epetra Communication Abstract Base Class.
Definition: Epetra_Comm.h:81
Epetra_BlockMap: A class for partitioning block element vectors and matrices.
int directory_test_5(Epetra_Comm &Comm)
int directory_test_2(Epetra_Comm &Comm)
Epetra_SerialComm: The Epetra Serial Communication Class.
int directory_test_1(Epetra_Comm &Comm)
virtual int NumProc() const =0
Returns total number of processes.
int main(int argc, char *argv[])
int Broadcast(double *MyVals, int Count, int Root) const
Epetra_SerialComm Broadcast function.