Epetra Package Browser (Single Doxygen Collection)  Development
test/ImportExport_LL/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 #include "Epetra_Map.h"
44 #include "Epetra_Time.h"
45 #include "Epetra_CrsMatrix.h"
46 #include "Epetra_Vector.h"
47 #include "Epetra_LongLongVector.h"
48 #include "Epetra_Import.h"
49 #include "Epetra_Export.h"
50 #include "Epetra_OffsetIndex.h"
51 #ifdef EPETRA_MPI
52 #include "Epetra_MpiComm.h"
53 #include "mpi.h"
54 #else
55 #include "Epetra_SerialComm.h"
56 #endif
57 #ifndef __cplusplus
58 #define __cplusplus
59 #endif
60 #include "../epetra_test_err.h"
61 #include "Epetra_Version.h"
62 
66 
67 int main(int argc, char *argv[])
68 {
69  int ierr = 0, i, j, forierr = 0;
70 
71 #ifdef EPETRA_MPI
72  // Initialize MPI
73  MPI_Init(&argc,&argv);
74  Epetra_MpiComm Comm( MPI_COMM_WORLD );
75 #else
76  Epetra_SerialComm Comm;
77 #endif
78 
79  bool verbose = false;
80 
81  // Check if we should print results to standard out
82  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;
83 
84 
85 
86 
87  //char tmp;
88  //if (Comm.MyPID()==0) cout << "Press any key to continue..."<< endl;
89  //if (Comm.MyPID()==0) cin >> tmp;
90  //Comm.Barrier();
91 
92  Comm.SetTracebackMode(0); // This should shut down any error traceback reporting
93  int MyPID = Comm.MyPID();
94  int NumProc = Comm.NumProc();
95 
96  if (verbose && MyPID==0)
97  cout << Epetra_Version() << endl << endl;
98 
99  if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc
100  << " is alive."<<endl;
101 
102  // Redefine verbose to only print on PE 0
103  if (verbose && Comm.MyPID()!=0) verbose = false;
104 
105  int NumMyEquations = 20;
106  long long NumGlobalEquations = NumMyEquations*NumProc+EPETRA_MIN(NumProc,3);
107  if (MyPID < 3) NumMyEquations++;
108  // Construct a Source Map that puts approximately the same Number of equations on each processor in
109  // uniform global ordering
110 
111  Epetra_Map SourceMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);
112 
113  // Get update list and number of local equations from newly created Map
114  int NumMyElements = SourceMap.NumMyElements();
115  long long * SourceMyGlobalElements = new long long[NumMyElements];
116  SourceMap.MyGlobalElements(SourceMyGlobalElements);
117 
118  // Construct a Target Map that will contain:
119  // some unchanged elements (relative to the soure map),
120  // some permuted elements
121  // some off-processor elements
122  Epetra_Vector RandVec(SourceMap);
123  RandVec.Random(); // This creates a vector of random numbers between negative one and one.
124 
125  long long *TargetMyGlobalElements = new long long[NumMyElements];
126 
127  long long MinGID = SourceMap.MinMyGID64();
128  for (i=0; i< NumMyEquations/2; i++) TargetMyGlobalElements[i] = i + MinGID; // Half will be the same...
129  for (i=NumMyEquations/2; i<NumMyEquations; i++) {
130  int index = abs((int)(((double) (NumGlobalEquations-1) ) * RandVec[i]));
131  TargetMyGlobalElements[i] = EPETRA_MIN(NumGlobalEquations-1,(long long) EPETRA_MAX(0,index));
132  }
133 
134  int NumSameIDs = 0;
135  int NumPermutedIDs = 0;
136  int NumRemoteIDs = 0;
137  bool StillContiguous = true;
138  for (i=0; i < NumMyEquations; i++) {
139  if (SourceMyGlobalElements[i]==TargetMyGlobalElements[i] && StillContiguous)
140  NumSameIDs++;
141  else if (SourceMap.MyGID(TargetMyGlobalElements[i])) {
142  StillContiguous = false;
143  NumPermutedIDs++;
144  }
145  else {
146  StillContiguous = false;
147  NumRemoteIDs++;
148  }
149  }
150  EPETRA_TEST_ERR(!(NumMyEquations==NumSameIDs+NumPermutedIDs+NumRemoteIDs),ierr);
151 
152  Epetra_Map TargetMap((long long) -1, NumMyElements, TargetMyGlobalElements, 0LL, Comm);
153 
154  // Create a multivector whose elements are GlobalID * (column number +1)
155 
156  int NumVectors = 3;
157  Epetra_MultiVector SourceMultiVector(SourceMap, NumVectors);
158  for (j=0; j < NumVectors; j++)
159  for (i=0; i < NumMyElements; i++)
160  SourceMultiVector[j][i] = (double) SourceMyGlobalElements[i]*(j+1);
161 
162  // Create a target multivector that we will fill using an Import
163 
164  Epetra_MultiVector TargetMultiVector(TargetMap, NumVectors);
165 
166  Epetra_Import Importer(TargetMap, SourceMap);
167 
168  EPETRA_TEST_ERR(!(TargetMultiVector.Import(SourceMultiVector, Importer, Insert)==0),ierr);
169 
170  // Test Target against expected values
171  forierr = 0;
172  for (j=0; j < NumVectors; j++)
173  for (i=0; i < NumMyElements; i++) {
174  if (TargetMultiVector[j][i]!= (double) TargetMyGlobalElements[i]*(j+1))
175  cout << "TargetMultiVector["<<i<<"]["<<j<<"] = " << TargetMultiVector[j][i]
176  << " TargetMyGlobalElements[i]*(j+1) = " << TargetMyGlobalElements[i]*(j+1) << endl;
177  forierr += !(TargetMultiVector[j][i]== (double) TargetMyGlobalElements[i]*(j+1));
178  }
179  EPETRA_TEST_ERR(forierr,ierr);
180 
181  if (verbose) cout << "MultiVector Import using Importer Check OK" << endl << endl;
182 
183 
185 
186  // Now use Importer to do an export
187 
188  Epetra_Vector TargetVector(SourceMap);
189  Epetra_Vector ExpectedTarget(SourceMap);
190  Epetra_Vector SourceVector(TargetMap);
191 
192  NumSameIDs = Importer.NumSameIDs();
193  int NumPermuteIDs = Importer.NumPermuteIDs();
194  int NumExportIDs = Importer.NumExportIDs();
195  int *PermuteFromLIDs = Importer.PermuteFromLIDs();
196  int *ExportLIDs = Importer.ExportLIDs();
197  int *ExportPIDs = Importer.ExportPIDs();
198 
199  for (i=0; i < NumSameIDs; i++) ExpectedTarget[i] = (double) (MyPID+1);
200  for (i=0; i < NumPermuteIDs; i++) ExpectedTarget[PermuteFromLIDs[i]] =
201  (double) (MyPID+1);
202  for (i=0; i < NumExportIDs; i++) ExpectedTarget[ExportLIDs[i]] +=
203  (double) (ExportPIDs[i]+1);
204 
205  for (i=0; i < NumMyElements; i++) SourceVector[i] = (double) (MyPID+1);
206 
207  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, Importer, Add)==0),ierr);
208 
209  forierr = 0;
210  for (i=0; i < NumMyElements; i++) {
211  if (TargetVector[i]!= ExpectedTarget[i])
212  cout << " TargetVector["<<i<<"] = " << TargetVector[i]
213  << " ExpectedTarget["<<i<<"] = " << ExpectedTarget[i] << " on PE " << MyPID << endl;
214  forierr += !(TargetVector[i]== ExpectedTarget[i]);
215  }
216  EPETRA_TEST_ERR(forierr,ierr);
217 
218  if (verbose) cout << "Vector Export using Importer Check OK" << endl << endl;
219 
221  // Now use Importer to create a reverse exporter
222  TargetVector.PutScalar(0.0);
223  Epetra_Export ReversedImport(Importer);
224 
225  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedImport, Add)==0),ierr);
226 
227  forierr = 0;
228  for (i=0; i < NumMyElements; i++) {
229  if (TargetVector[i]!= ExpectedTarget[i])
230  cout << " TargetVector["<<i<<"] = " << TargetVector[i]
231  << " ExpectedTarget["<<i<<"] = " << ExpectedTarget[i] << " on PE " << MyPID << endl;
232  forierr += !(TargetVector[i]== ExpectedTarget[i]);
233  }
234  EPETRA_TEST_ERR(forierr,ierr);
235 
236  if (verbose) cout << "Vector Export using Reversed Importer Check OK" << endl << endl;
237 
239  // Now use Exporter to create a reverse importer
240  TargetVector.PutScalar(0.0);
241  Epetra_Import ReversedExport(ReversedImport);
242 
243  EPETRA_TEST_ERR(!(TargetVector.Export(SourceVector, ReversedExport, Add)==0),ierr);
244 
245  forierr = 0;
246  for (i=0; i < NumMyElements; i++) {
247  if (TargetVector[i]!= ExpectedTarget[i])
248  cout << " TargetVector["<<i<<"] = " << TargetVector[i]
249  << " ExpectedTarget["<<i<<"] = " << ExpectedTarget[i] << " on PE " << MyPID << endl;
250  forierr += !(TargetVector[i]== ExpectedTarget[i]);
251  }
252  EPETRA_TEST_ERR(forierr,ierr);
253 
254  if (verbose) cout << "Vector Export using Reversed Exporter Check OK" << endl << endl;
255 
256 
258  // Build a tridiagonal system two ways:
259  // 1) From "standard" matrix view where equations are uniquely owned.
260  // 2) From 1D PDE view where nodes (equations) between processors are shared and partial contributions are done
261  // in parallel, then merged together at the end of the construction process.
262  //
264 
265 
266 
267  // Construct a Standard Map that puts approximately the same number of equations on each processor in
268  // uniform global ordering
269 
270  Epetra_Map StandardMap(NumGlobalEquations, NumMyEquations, 0LL, Comm);
271 
272  // Get update list and number of local equations from newly created Map
273  NumMyElements = StandardMap.NumMyElements();
274  long long * StandardMyGlobalElements = new long long[NumMyElements];
275  StandardMap.MyGlobalElements(StandardMyGlobalElements);
276 
277 
278  // Create a standard Epetra_CrsGraph
279 
280  Epetra_CrsGraph StandardGraph(Copy, StandardMap, 3);
281  EPETRA_TEST_ERR(StandardGraph.IndicesAreGlobal(),ierr);
282  EPETRA_TEST_ERR(StandardGraph.IndicesAreLocal(),ierr);
283 
284  // Add rows one-at-a-time
285  // Need some vectors to help
286  // Off diagonal Values will always be -1
287 
288 
289  long long *Indices = new long long[2];
290  int NumEntries;
291 
292  forierr = 0;
293  for (i=0; i<NumMyEquations; i++)
294  {
295  if (StandardMyGlobalElements[i]==0)
296  {
297  Indices[0] = 1;
298  NumEntries = 1;
299  }
300  else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
301  {
302  Indices[0] = NumGlobalEquations-2;
303  NumEntries = 1;
304  }
305  else
306  {
307  Indices[0] = StandardMyGlobalElements[i]-1;
308  Indices[1] = StandardMyGlobalElements[i]+1;
309  NumEntries = 2;
310  }
311  forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], NumEntries, Indices)==0);
312  forierr += !(StandardGraph.InsertGlobalIndices(StandardMyGlobalElements[i], 1, StandardMyGlobalElements+i)==0); // Put in the diagonal entry
313  }
314  EPETRA_TEST_ERR(forierr,ierr);
315 
316  // Finish up
317  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreGlobal()),ierr);
318  EPETRA_TEST_ERR(!(StandardGraph.FillComplete()==0),ierr);
319  EPETRA_TEST_ERR(!(StandardGraph.IndicesAreLocal()),ierr);
320  EPETRA_TEST_ERR(StandardGraph.StorageOptimized(),ierr);
321  StandardGraph.OptimizeStorage();
322  EPETRA_TEST_ERR(!(StandardGraph.StorageOptimized()),ierr);
323  EPETRA_TEST_ERR(StandardGraph.UpperTriangular(),ierr);
324  EPETRA_TEST_ERR(StandardGraph.LowerTriangular(),ierr);
325 
326  // Create Epetra_CrsMatrix using the just-built graph
327 
328  Epetra_CrsMatrix StandardMatrix(Copy, StandardGraph);
329  EPETRA_TEST_ERR(StandardMatrix.IndicesAreGlobal(),ierr);
330  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
331 
332  // Add rows one-at-a-time
333  // Need some vectors to help
334  // Off diagonal Values will always be -1
335 
336 
337  double *Values = new double[2];
338  Values[0] = -1.0; Values[1] = -1.0;
339  double two = 2.0;
340 
341  forierr = 0;
342  for (i=0; i<NumMyEquations; i++)
343  {
344  if (StandardMyGlobalElements[i]==0)
345  {
346  Indices[0] = 1;
347  NumEntries = 1;
348  }
349  else if (StandardMyGlobalElements[i] == NumGlobalEquations-1)
350  {
351  Indices[0] = NumGlobalEquations-2;
352  NumEntries = 1;
353  }
354  else
355  {
356  Indices[0] = StandardMyGlobalElements[i]-1;
357  Indices[1] = StandardMyGlobalElements[i]+1;
358  NumEntries = 2;
359  }
360  forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], NumEntries, Values, Indices)==0);
361  // Put in the diagonal entry
362  forierr += !(StandardMatrix.ReplaceGlobalValues(StandardMyGlobalElements[i], 1, &two, StandardMyGlobalElements+i)==0);
363  }
364  EPETRA_TEST_ERR(forierr,ierr);
365 
366  // Finish up
367  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
368  EPETRA_TEST_ERR(!(StandardMatrix.FillComplete()==0),ierr);
369  EPETRA_TEST_ERR(!(StandardMatrix.IndicesAreLocal()),ierr);
370  // EPETRA_TEST_ERR((StandardMatrix.StorageOptimized()),ierr);
371  EPETRA_TEST_ERR((StandardMatrix.OptimizeStorage()),ierr);
372  EPETRA_TEST_ERR(!(StandardMatrix.StorageOptimized()),ierr);
373  EPETRA_TEST_ERR(StandardMatrix.UpperTriangular(),ierr);
374  EPETRA_TEST_ERR(StandardMatrix.LowerTriangular(),ierr);
375 
376  // Construct an Overlapped Map of StandardMap that include the endpoints from two neighboring processors.
377 
378  int OverlapNumMyElements;
379  long long OverlapMinMyGID;
380 
381  OverlapNumMyElements = NumMyElements + 1;
382  if (MyPID==0) OverlapNumMyElements--;
383 
384  if (MyPID==0) OverlapMinMyGID = StandardMap.MinMyGID64();
385  else OverlapMinMyGID = StandardMap.MinMyGID64()-1;
386 
387  long long * OverlapMyGlobalElements = new long long[OverlapNumMyElements];
388 
389  for (i=0; i< OverlapNumMyElements; i++) OverlapMyGlobalElements[i] = OverlapMinMyGID + i;
390 
391  Epetra_Map OverlapMap((long long) -1, OverlapNumMyElements, OverlapMyGlobalElements, 0LL, Comm);
392 
393  // Create the Overlap Epetra_Matrix
394 
395  Epetra_CrsMatrix OverlapMatrix(Copy, OverlapMap, 4);
396  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreGlobal(),ierr);
397  EPETRA_TEST_ERR(OverlapMatrix.IndicesAreLocal(),ierr);
398 
399  // Add matrix element one cell at a time.
400  // Each cell does an incoming and outgoing flux calculation
401 
402 
403  double pos_one = 1.0;
404  double neg_one = -1.0;
405 
406  forierr = 0;
407  for (i=0; i<OverlapNumMyElements; i++)
408  {
409  long long node_left = OverlapMyGlobalElements[i]-1;
410  long long node_center = node_left + 1;
411  long long node_right = node_left + 2;
412  if (i>0) {
413  if (node_left>-1)
414  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_left)==0);
415  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
416  }
417  if (i<OverlapNumMyElements-1) {
418  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0);
419  if (node_right<NumGlobalEquations)
420  forierr += !(OverlapMatrix.InsertGlobalValues(node_center, 1, &neg_one, &node_right)==0);
421  }
422  }
423  EPETRA_TEST_ERR(forierr,ierr);
424 
425  // Handle endpoints
426  if (MyPID==0) {
427  long long node_center = 0;
428  EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
429  }
430  if (MyPID==NumProc-1) {
431  long long node_center = OverlapMyGlobalElements[OverlapNumMyElements-1];
432  EPETRA_TEST_ERR(!(OverlapMatrix.InsertGlobalValues(node_center, 1, &pos_one, &node_center)==0),ierr);
433  }
434 
435  EPETRA_TEST_ERR(!(OverlapMatrix.FillComplete()==0),ierr);
436 
437  // Make a gathered matrix from OverlapMatrix. It should be identical to StandardMatrix
438 
439  Epetra_CrsMatrix GatheredMatrix(Copy, StandardGraph);
440  Epetra_Export Exporter(OverlapMap, StandardMap);
441  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);
442  EPETRA_TEST_ERR(!(GatheredMatrix.FillComplete()==0),ierr);
443 
444  // Check if entries of StandardMatrix and GatheredMatrix are identical
445 
446  int StandardNumEntries, GatheredNumEntries;
447  int * StandardIndices, * GatheredIndices;
448  double * StandardValues, * GatheredValues;
449 
450  int StandardNumMyNonzeros = StandardMatrix.NumMyNonzeros();
451  int GatheredNumMyNonzeros = GatheredMatrix.NumMyNonzeros();
452  EPETRA_TEST_ERR(!(StandardNumMyNonzeros==GatheredNumMyNonzeros),ierr);
453 
454  int StandardNumMyRows = StandardMatrix.NumMyRows();
455  int GatheredNumMyRows = GatheredMatrix.NumMyRows();
456  EPETRA_TEST_ERR(!(StandardNumMyRows==GatheredNumMyRows),ierr);
457 
458  forierr = 0;
459  for (i=0; i< StandardNumMyRows; i++)
460  {
461  forierr += !(StandardMatrix.ExtractMyRowView(i, StandardNumEntries, StandardValues, StandardIndices)==0);
462  forierr += !(GatheredMatrix.ExtractMyRowView(i, GatheredNumEntries, GatheredValues, GatheredIndices)==0);
463  forierr += !(StandardNumEntries==GatheredNumEntries);
464  for (j=0; j < StandardNumEntries; j++) {
465  //if (StandardIndices[j]!=GatheredIndices[j])
466  // cout << "MyPID = " << MyPID << " i = " << i << " StandardIndices[" << j << "] = " << StandardIndices[j]
467  // << " GatheredIndices[" << j << "] = " << GatheredIndices[j] << endl;
468  //if (StandardValues[j]!=GatheredValues[j])
469  //cout << "MyPID = " << MyPID << " i = " << i << " StandardValues[" << j << "] = " << StandardValues[j]
470  // << " GatheredValues[" << j << "] = " << GatheredValues[j] << endl;
471  forierr += !(StandardIndices[j]==GatheredIndices[j]);
472  forierr += !(StandardValues[j]==GatheredValues[j]);
473  }
474  }
475  EPETRA_TEST_ERR(forierr,ierr);
476 
477  if (verbose) cout << "Matrix Export Check OK" << endl << endl;
478 
479  //Do Again with use of Epetra_OffsetIndex object for speed
480  Epetra_OffsetIndex OffsetIndex( OverlapMatrix.Graph(), GatheredMatrix.Graph(), Exporter );
481  EPETRA_TEST_ERR(!(GatheredMatrix.Export(OverlapMatrix, Exporter, Add)==0),ierr);
482 
483  if (verbose) cout << "Optimized Matrix Export Check OK" << endl << endl;
484 
485  bool passed;
486  Epetra_LongLongVector v1(StandardMap); v1.PutValue(2);
487  Epetra_LongLongVector v2(StandardMap); v2.PutValue(3);
488 
489  Epetra_Export identExporter(StandardMap,StandardMap); // Identity exporter
490  EPETRA_TEST_ERR(!(v2.Export(v1, identExporter, Insert)==0),ierr);
491  passed = (v2.MinValue()==2);
492  EPETRA_TEST_ERR(!passed,ierr);
493 
494  v1.PutValue(1);
495  Epetra_Import identImporter(StandardMap,StandardMap); // Identity importer
496  EPETRA_TEST_ERR(!(v2.Import(v1, identExporter, Insert)==0),ierr);
497  passed = passed && (v2.MaxValue()==1);
498  EPETRA_TEST_ERR(!passed,ierr);
499 
500  if (verbose) {
501  if (passed) cout << "Identity Import/Export Check OK" << endl << endl;
502  else cout << "Identity Import/Export Check Failed" << endl << endl;
503  }
504 
505  int NumSubMapElements = StandardMap.NumMyElements()/2;
506  int SubStart = Comm.MyPID();
507  NumSubMapElements = EPETRA_MIN(NumSubMapElements,StandardMap.NumMyElements()-SubStart);
508  Epetra_Map SubMap((long long) -1, NumSubMapElements, StandardMyGlobalElements+SubStart, 0LL, Comm);
509 
510  Epetra_LongLongVector v3(View, SubMap, SubMap.MyGlobalElements64()); // Fill v3 with GID values for variety
511  Epetra_Export subExporter(SubMap, StandardMap); // Export to a subset of indices of standard map
512  EPETRA_TEST_ERR(!(v2.Export(v3,subExporter,Insert)==0),ierr);
513 
514  forierr = 0;
515  for (i=0; i<SubMap.NumMyElements(); i++) {
516  int i1 = StandardMap.LID(SubMap.GID64(i));
517  forierr += !(v3[i]==v2[i1]);
518  }
519  EPETRA_TEST_ERR(forierr,ierr);
520 
521  Epetra_Import subImporter(StandardMap, SubMap); // Import to a subset of indices of standard map
522  EPETRA_TEST_ERR(!(v1.Import(v3,subImporter,Insert)==0),ierr);
523 
524  for (i=0; i<SubMap.NumMyElements(); i++) {
525  int i1 = StandardMap.LID(SubMap.GID64(i));
526  forierr += !(v3[i]==v1[i1]);
527  }
528  EPETRA_TEST_ERR(forierr,ierr);
529 
530  if (verbose) {
531  if (forierr==0) cout << "SubMap Import/Export Check OK" << endl << endl;
532  else cout << "SubMap Import/Export Check Failed" << endl << endl;
533  }
534 
535 #ifdef DOESNT_WORK_IN_PARALLEL
536  forierr = special_submap_import_test(Comm);
537  EPETRA_TEST_ERR(forierr, ierr);
538 
539  if (verbose) {
540  if (forierr==0) cout << "Special SubMap Import Check OK" << endl << endl;
541  else cout << "Special SubMap Import Check Failed" << endl << endl;
542  }
543 #endif
544 
545  forierr = alternate_import_constructor_test(Comm);
546  EPETRA_TEST_ERR(forierr, ierr);
547 
548  if (verbose) {
549  if (forierr==0) cout << "Alternative Import Constructor Check OK" << endl << endl;
550  else cout << "Alternative Import Constructor Check Failed" << endl << endl;
551  }
552 
553  // Release all objects
554 
555  delete [] SourceMyGlobalElements;
556  delete [] TargetMyGlobalElements;
557  delete [] OverlapMyGlobalElements;
558  delete [] StandardMyGlobalElements;
559 
560  delete [] Values;
561  delete [] Indices;
562 
563 #ifdef EPETRA_MPI
564  MPI_Finalize() ;
565 #endif
566 
567 /* end main
568 */
569 return ierr ;
570 }
571 
573 {
574  int localProc = Comm.MyPID();
575 
576  //set up ids_source and ids_target such that ids_source are only
577  //a subset of ids_target, and furthermore that ids_target are ordered
578  //such that the LIDs don't match up. In other words, even if gid 2 does
579  //exist in both ids_source and ids_target, it will correspond to different
580  //LIDs on at least 1 proc.
581  //
582  //This is to test a certain bug-fix in Epetra_Import where the 'RemoteLIDs'
583  //array wasn't being calculated correctly on all procs.
584 
585  long long ids_source[1];
586  ids_source[0] = localProc*2+2;
587 
588  long long ids_target[3];
589  ids_target[0] = localProc*2+2;
590  ids_target[1] = localProc*2+1;
591  ids_target[2] = localProc*2+0;
592 
593  Epetra_Map map_source((long long) -1, 1, &ids_source[0], 0LL, Comm);
594  Epetra_Map map_target((long long) -1, 3, &ids_target[0], 0LL, Comm);
595 
596  Epetra_Import importer(map_target, map_source);
597 
598  Epetra_LongLongVector vec_source(map_source);
599  Epetra_LongLongVector vec_target(map_target);
600 
601  vec_target.PutValue(0);
602 
603  //set vec_source's contents so that entry[i] == GID[i].
604  long long* GIDs = map_source.MyGlobalElements64();
605  for(int i=0; i<map_source.NumMyElements(); ++i) {
606  vec_source[i] = GIDs[i];
607  }
608 
609  //Import vec_source into vec_target. This should result in the contents
610  //of vec_target remaining 0 for the entries that don't exist in vec_source,
611  //and other entries should be equal to the corresponding GID in the map.
612 
613  vec_target.Import(vec_source, importer, Insert);
614 
615  GIDs = map_target.MyGlobalElements64();
616  int test_failed = 0;
617 
618  //the test passes if the i-th entry in vec_target equals either 0 or
619  //GIDs[i].
620  for(int i=0; i<vec_target.MyLength(); ++i) {
621  if (vec_target[i] != GIDs[i] && vec_target[i] != 0) test_failed = 1;
622  }
623 
624  int global_result;
625  Comm.MaxAll(&test_failed, &global_result, 1);
626 
627  //If test didn't fail on any procs, global_result should be 0.
628  //If test failed on any proc, global_result should be 1.
629  return global_result;
630 }
631 
633 {
634  int localProc = Comm.MyPID();
635 
636 
637  long long ids_source[1];
638  ids_source[0] = localProc*2+2;
639 
640  long long ids_target[3];
641  ids_target[0] = localProc*2+2;
642  ids_target[1] = localProc*2+1;
643  ids_target[2] = localProc*2+0;
644 
645  Epetra_Map map_source((long long) -1, 1, &ids_source[0], 0LL, Comm);
646  Epetra_Map map_target((long long) -1, 3, &ids_target[0], 0LL, Comm);
647 
648  Epetra_Import importer(map_target, map_source);
649 
650  Epetra_LongLongVector vec_source(map_source);
651  Epetra_LongLongVector vec_target(map_target);
652 
653  vec_target.PutValue(0);
654 
655  //set vec_source's contents so that entry[i] == GID[i].
656  long long* GIDs = map_source.MyGlobalElements64();
657  for(int i=0; i<map_source.NumMyElements(); ++i) {
658  vec_source[i] = GIDs[i];
659  }
660 
661  //Import vec_source into vec_target. This should result in the contents
662  //of vec_target remaining 0 for the entries that don't exist in vec_source,
663  //and other entries should be equal to the corresponding GID in the map.
664 
665  vec_target.Import(vec_source, importer, Insert);
666 
667  GIDs = map_target.MyGlobalElements64();
668  int test_failed = 0;
669 
670  //the test passes if the i-th entry in vec_target equals either 0 or
671  //GIDs[i].
672  for(int i=0; i<vec_target.MyLength(); ++i) {
673  if (vec_target[i] != GIDs[i] && vec_target[i] != 0) test_failed = 1;
674  }
675 
676  int global_result;
677  Comm.MaxAll(&test_failed, &global_result, 1);
678 
679  //If test didn't fail on any procs, global_result should be 0.
680  //If test failed on any proc, global_result should be 1.
681  return global_result;
682 }
683 
684 
685 int test_import_gid(const char * name,Epetra_LongLongVector & Source, Epetra_LongLongVector & Target, const Epetra_Import & Import){
686  int i;
687  bool test_passed=true;
688 
689  // Setup
690  for(i=0; i<Source.MyLength(); i++)
691  Source[i] = Source.Map().GID64(i);
692  Target.PutValue(0);
693 
694  // Import
695  Target.Import(Source,Import,Add);
696 
697  // Test
698  for(i=0; i<Target.MyLength(); i++){
699  if(Target[i] != Target.Map().GID64(i)) test_passed=false;
700  }
701 
702  if(!test_passed){
703  printf("[%d] test_import_gid %s failed: ",Source.Map().Comm().MyPID(),name);
704  for(i=0; i<Target.MyLength(); i++)
705  printf("%2lld(%2lld) ",Target[i],Target.Map().GID64(i));
706  printf("\n");
707  fflush(stdout);
708  }
709 
710  return !test_passed;
711 }
712 
713 
714 
716  int rv=0;
717  int nodes_per_proc=10;
718  int numprocs = Comm.NumProc();
719  int mypid = Comm.MyPID();
720 
721  // Only run if we have multiple procs & MPI
722  if(numprocs==0) return 0;
723 #ifndef HAVE_MPI
724  return 0;
725 #endif
726 
727  // Build Map 1 - linear
728  Epetra_Map Map1((long long)-1,nodes_per_proc,(long long)0,Comm);
729 
730  // Build Map 2 - mod striped
731  std::vector<long long> MyGIDs(nodes_per_proc);
732  for(int i=0; i<nodes_per_proc; i++)
733  MyGIDs[i] = (mypid*nodes_per_proc + i) % numprocs;
734  Epetra_Map Map2((long long)-1,nodes_per_proc,&MyGIDs[0],(long long)0,Comm);
735 
736  // For testing
737  Epetra_LongLongVector Source(Map1), Target(Map2);
738 
739 
740  // Build Import 1 - normal
741  Epetra_Import Import1(Map2,Map1);
742  rv = rv|| test_import_gid("Alt test: 2 map constructor",Source,Target, Import1);
743 
744  // Build Import 2 - no-comm constructor
745  int Nremote=Import1.NumRemoteIDs();
746  const int * RemoteLIDs = Import1.RemoteLIDs();
747  std::vector<int> RemotePIDs(Nremote+1); // I hate you, stl vector....
748  std::vector<int> AllPIDs;
749  Epetra_Util::GetPids(Import1,AllPIDs,true);
750 
751  for(int i=0; i<Nremote; i++) {
752  RemotePIDs[i]=AllPIDs[RemoteLIDs[i]];
753  }
754  Epetra_Import Import2(Import1.TargetMap(),Import1.SourceMap(),Nremote,&RemotePIDs[0],Import1.NumExportIDs(),Import1.ExportLIDs(),Import1.ExportPIDs());
755 
756  rv = rv || test_import_gid("Alt test: no comm constructor",Source,Target,Import2);
757 
758 
759  // Build Import 3 - Remotes only
760  Epetra_Import Import3(Import1.TargetMap(),Import1.SourceMap(),Nremote,&RemotePIDs[0]);
761  rv = rv || test_import_gid("Alt test: remote only constructor",Source,Target, Import3);
762 
763 
764  return rv;
765 }
Epetra_LongLongVector::MaxValue
long long MaxValue()
Find maximum value.
Definition: Epetra_LongLongVector.cpp:168
Epetra_BlockMap::Comm
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
Definition: Epetra_BlockMap.h:770
Epetra_BlockMap::NumMyElements
int NumMyElements() const
Number of elements on the calling processor.
Definition: Epetra_BlockMap.h:555
Epetra_Import::PermuteFromLIDs
int * PermuteFromLIDs() const
List of elements in the source map that are permuted.
Definition: Epetra_Import.h:268
Epetra_Comm::NumProc
virtual int NumProc() const =0
Returns total number of processes.
Epetra_CrsGraph::LowerTriangular
bool LowerTriangular() const
If graph is lower triangular in local index space, this query returns true, otherwise it returns fals...
Definition: Epetra_CrsGraph.h:520
Epetra_Version.h
Epetra_CrsMatrix::IndicesAreLocal
bool IndicesAreLocal() const
If matrix indices has been transformed to local, this query returns true, otherwise it returns false.
Definition: Epetra_CrsMatrix.h:1016
EPETRA_MIN
#define EPETRA_MIN(x, y)
Definition: Epetra_ConfigDefs.h:63
Epetra_LongLongVector::PutValue
int PutValue(long long Value)
Set all elements of the vector to Value.
Definition: Epetra_LongLongVector.cpp:162
Epetra_Import::NumRemoteIDs
int NumRemoteIDs() const
Returns the number of elements that are not on the calling processor.
Definition: Epetra_Import.h:273
Add
Definition: Epetra_CombineMode.h:64
Epetra_MultiVector::PutScalar
int PutScalar(double ScalarConstant)
Initialize all values in a multi-vector with constant value.
Definition: Epetra_MultiVector.cpp:595
Epetra_MultiVector::Random
int Random()
Set multi-vector values to random numbers.
Definition: Epetra_MultiVector.cpp:490
Epetra_OffsetIndex.h
View
Definition: Epetra_DataAccess.h:57
combine_mode_test
int combine_mode_test(Epetra_Comm &Comm)
Definition: test/ImportExport_LL/cxx_main.cpp:632
Epetra_CrsGraph::FillComplete
int FillComplete()
Tranform to local index space. Perform other operations to allow optimal matrix operations.
Definition: Epetra_CrsGraph.cpp:968
Epetra_DistObject::Map
const Epetra_BlockMap & Map() const
Returns the address of the Epetra_BlockMap for this multi-vector.
Definition: Epetra_DistObject.h:192
Epetra_CrsGraph::UpperTriangular
bool UpperTriangular() const
If graph is upper triangular in local index space, this query returns true, otherwise it returns fals...
Definition: Epetra_CrsGraph.h:526
Epetra_CrsGraph::IndicesAreLocal
bool IndicesAreLocal() const
If column indices are in local range, this query returns true, otherwise it returns false.
Definition: Epetra_CrsGraph.h:514
Epetra_BlockMap::LID
int LID(int GID) const
Returns local ID of global ID, return -1 if not found on this processor.
Definition: Epetra_BlockMap.cpp:1218
Epetra_CrsMatrix.h
Copy
Definition: Epetra_DataAccess.h:55
Epetra_Util::GetPids
static int GetPids(const Epetra_Import &Importer, std::vector< int > &pids, bool use_minus_one_for_local)
Epetra_Util GetPids function.
Definition: Epetra_Util.cpp:731
Epetra_Import::NumPermuteIDs
int NumPermuteIDs() const
Returns the number of elements that are local to the calling processor, but not part of the first Num...
Definition: Epetra_Import.h:265
EPETRA_TEST_ERR
#define EPETRA_TEST_ERR(a, b)
Definition: epetra_test_err.h:55
Epetra_LongLongVector::MyLength
int MyLength() const
Returns the local vector length on the calling processor of vectors in the multi-vector.
Definition: Epetra_LongLongVector.h:252
Epetra_Comm
Epetra_Comm: The Epetra Communication Abstract Base Class.
Definition: Epetra_Comm.h:73
Epetra_Vector.h
Epetra_SerialComm::MyPID
int MyPID() const
Return my process ID.
Definition: Epetra_SerialComm.h:432
Epetra_Import::ExportPIDs
int * ExportPIDs() const
List of processors to which elements will be sent, ExportLIDs() [i] will be sent to processor ExportP...
Definition: Epetra_Import.h:285
Epetra_Version
std::string Epetra_Version()
Definition: Epetra_Version.h:47
Epetra_CrsMatrix::InsertGlobalValues
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
Insert a list of elements in a given global row of the matrix.
Definition: Epetra_CrsMatrix.cpp:540
Epetra_CrsMatrix::NumMyRows
int NumMyRows() const
Returns the number of matrix rows owned by the calling processor.
Definition: Epetra_CrsMatrix.h:1108
Epetra_SerialComm::NumProc
int NumProc() const
Returns total number of processes (always returns 1 for SerialComm).
Definition: Epetra_SerialComm.h:435
Epetra_CrsMatrix::Graph
const Epetra_CrsGraph & Graph() const
Returns a reference to the Epetra_CrsGraph object associated with this matrix.
Definition: Epetra_CrsMatrix.h:1163
special_submap_import_test
int special_submap_import_test(Epetra_Comm &Comm)
Definition: test/ImportExport_LL/cxx_main.cpp:572
Insert
Definition: Epetra_CombineMode.h:68
Epetra_SerialComm.h
Epetra_CrsMatrix
Epetra_CrsMatrix: A class for constructing and using real-valued double-precision sparse compressed r...
Definition: Epetra_CrsMatrix.h:173
Epetra_MpiComm.h
Epetra_DistObject::Export
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
Exports an Epetra_DistObject using the Epetra_Import object.
Definition: Epetra_DistObject.cpp:198
main
int main(int argc, char *argv[])
Definition: test/ImportExport_LL/cxx_main.cpp:67
Epetra_CrsMatrix::ExtractMyRowView
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
Returns a view of the specified local row values via pointers to internal data.
Definition: Epetra_CrsMatrix.cpp:1577
alternate_import_constructor_test
int alternate_import_constructor_test(Epetra_Comm &Comm)
Definition: test/ImportExport_LL/cxx_main.cpp:715
Epetra_BlockMap::MinMyGID64
long long MinMyGID64() const
Definition: Epetra_BlockMap.h:523
Epetra_MpiComm
Epetra_MpiComm: The Epetra MPI Communication Class.
Definition: Epetra_MpiComm.h:64
Epetra_SerialComm
Epetra_SerialComm: The Epetra Serial Communication Class.
Definition: Epetra_SerialComm.h:61
Epetra_Import::SourceMap
const Epetra_BlockMap & SourceMap() const
Returns the SourceMap used to construct this importer.
Definition: Epetra_Import.h:294
Epetra_Export.h
Epetra_BlockMap::MyGlobalElements
int MyGlobalElements(int *MyGlobalElementList) const
Puts list of global elements on this processor into the user-provided array.
Definition: Epetra_BlockMap.cpp:848
Epetra_CrsGraph::InsertGlobalIndices
int InsertGlobalIndices(int GlobalRow, int NumIndices, int *Indices)
Enter a list of elements in a specified global row of the graph.
Definition: Epetra_CrsGraph.cpp:272
Epetra_Vector
Epetra_Vector: A class for constructing and using dense vectors on a parallel computer.
Definition: Epetra_Vector.h:142
Epetra_Import::ExportLIDs
int * ExportLIDs() const
List of elements that will be sent to other processors.
Definition: Epetra_Import.h:282
Epetra_OffsetIndex
Epetra_OffsetIndex: This class builds index for efficient mapping of data from one Epetra_CrsGraph ba...
Definition: Epetra_OffsetIndex.h:60
Epetra_CrsMatrix::FillComplete
int FillComplete(bool OptimizeDataStorage=true)
Signal that data entry is complete. Perform transformations to local index space.
Definition: Epetra_CrsMatrix.cpp:1140
Epetra_CrsGraph::StorageOptimized
bool StorageOptimized() const
If OptimizeStorage() has been called, this query returns true, otherwise it returns false.
Definition: Epetra_CrsGraph.h:508
Epetra_Import.h
Epetra_LongLongVector
Epetra_LongLongVector: A class for constructing and using dense integer vectors on a parallel compute...
Definition: Epetra_LongLongVector.h:126
Epetra_CrsGraph
Epetra_CrsGraph: A class for constructing and using sparse compressed row graphs.
Definition: Epetra_CrsGraph.h:213
Epetra_MultiVector
Epetra_MultiVector: A class for constructing and using dense multi-vectors, vectors and matrices in p...
Definition: Epetra_MultiVector.h:184
Epetra_Comm::MaxAll
virtual int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const =0
Epetra_Comm Global Max function.
Epetra_CrsGraph::OptimizeStorage
int OptimizeStorage()
Make consecutive row index sections contiguous, minimize internal storage used for constructing graph...
Definition: Epetra_CrsGraph.cpp:1881
Epetra_Import::TargetMap
const Epetra_BlockMap & TargetMap() const
Returns the TargetMap used to construct this importer.
Definition: Epetra_Import.h:297
Epetra_LongLongVector::MinValue
long long MinValue()
Find minimum value.
Definition: Epetra_LongLongVector.cpp:178
Epetra_Map.h
Epetra_Import::NumExportIDs
int NumExportIDs() const
Returns the number of elements that must be sent by the calling processor to other processors.
Definition: Epetra_Import.h:279
Epetra_CrsMatrix::IndicesAreGlobal
bool IndicesAreGlobal() const
If matrix indices has not been transformed to local, this query returns true, otherwise it returns fa...
Definition: Epetra_CrsMatrix.h:1013
Epetra_DistObject::Import
int Import(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
Imports an Epetra_DistObject using the Epetra_Import object.
Definition: Epetra_DistObject.cpp:113
Epetra_BlockMap::MyGlobalElements64
long long * MyGlobalElements64() const
Definition: Epetra_BlockMap.cpp:908
Epetra_LongLongVector.h
test_import_gid
int test_import_gid(const char *name, Epetra_LongLongVector &Source, Epetra_LongLongVector &Target, const Epetra_Import &Import)
Definition: test/ImportExport_LL/cxx_main.cpp:685
Epetra_CrsMatrix::NumMyNonzeros
int NumMyNonzeros() const
Returns the number of nonzero entries in the calling processor's portion of the matrix.
Definition: Epetra_CrsMatrix.h:1105
Epetra_Object::SetTracebackMode
static void SetTracebackMode(int TracebackModeValue)
Set the value of the Epetra_Object error traceback report mode.
Definition: Epetra_Object.cpp:77
Epetra_Import::NumSameIDs
int NumSameIDs() const
Returns the number of elements that are identical between the source and target maps,...
Definition: Epetra_Import.h:262
Epetra_BlockMap::GID64
long long GID64(int LID) const
Definition: Epetra_BlockMap.cpp:1252
Epetra_Export
Epetra_Export: This class builds an export object for efficient exporting of off-processor elements.
Definition: Epetra_Export.h:62
Epetra_Map
Epetra_Map: A class for partitioning vectors and matrices.
Definition: Epetra_Map.h:119
Epetra_CrsGraph::IndicesAreGlobal
bool IndicesAreGlobal() const
If column indices are in global range, this query returns true, otherwise it returns false.
Definition: Epetra_CrsGraph.h:511
Epetra_Import::RemoteLIDs
int * RemoteLIDs() const
List of elements in the target map that are coming from other processors.
Definition: Epetra_Import.h:276
Epetra_Comm::MyPID
virtual int MyPID() const =0
Return my process ID.
Epetra_BlockMap::MyGID
bool MyGID(int GID_in) const
Returns true if the GID passed in belongs to the calling processor in this map, otherwise returns fal...
Definition: Epetra_BlockMap.h:479
Epetra_Import
Epetra_Import: This class builds an import object for efficient importing of off-processor elements.
Definition: Epetra_Import.h:63
Epetra_Time.h
EPETRA_MAX
#define EPETRA_MAX(x, y)
Definition: Epetra_ConfigDefs.h:62