Epetra Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
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"
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
67int 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
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*/
569return 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
685int 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}
@ Insert
#define EPETRA_MIN(x, y)
#define EPETRA_MAX(x, y)
@ View
@ Copy
std::string Epetra_Version()
int MyGlobalElements(int *MyGlobalElementList) const
Puts list of global elements on this processor into the user-provided array.
long long * MyGlobalElements64() const
int LID(int GID) const
Returns local ID of global ID, return -1 if not found on this processor.
long long GID64(int LID) const
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
long long MinMyGID64() const
int NumMyElements() const
Number of elements on the calling processor.
bool MyGID(int GID_in) const
Returns true if the GID passed in belongs to the calling processor in this map, otherwise returns fal...
Epetra_Comm: The Epetra Communication Abstract Base Class.
Definition: Epetra_Comm.h:73
virtual int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const =0
Epetra_Comm Global Max function.
virtual int NumProc() const =0
Returns total number of processes.
virtual int MyPID() const =0
Return my process ID.
Epetra_CrsGraph: A class for constructing and using sparse compressed row graphs.
int InsertGlobalIndices(int GlobalRow, int NumIndices, int *Indices)
Enter a list of elements in a specified global row of the graph.
bool IndicesAreLocal() const
If column indices are in local range, this query returns true, otherwise it returns false.
bool StorageOptimized() const
If OptimizeStorage() has been called, this query returns true, otherwise it returns false.
bool LowerTriangular() const
If graph is lower triangular in local index space, this query returns true, otherwise it returns fals...
bool IndicesAreGlobal() const
If column indices are in global range, this query returns true, otherwise it returns false.
bool UpperTriangular() const
If graph is upper triangular in local index space, this query returns true, otherwise it returns fals...
int FillComplete()
Tranform to local index space. Perform other operations to allow optimal matrix operations.
int OptimizeStorage()
Make consecutive row index sections contiguous, minimize internal storage used for constructing graph...
Epetra_CrsMatrix: A class for constructing and using real-valued double-precision sparse compressed r...
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.
int FillComplete(bool OptimizeDataStorage=true)
Signal that data entry is complete. Perform transformations to local index space.
virtual int ReplaceGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
Replace specified existing values with this list of entries for a given global row of the matrix.
int NumMyNonzeros() const
Returns the number of nonzero entries in the calling processor's portion of the matrix.
const Epetra_CrsGraph & Graph() const
Returns a reference to the Epetra_CrsGraph object associated with this matrix.
bool StorageOptimized() const
If OptimizeStorage() has been called, this query returns true, otherwise it returns false.
bool IndicesAreLocal() const
If matrix indices has been transformed to local, this query returns true, otherwise it returns false.
bool LowerTriangular() const
If matrix is lower triangular in local index space, this query returns true, otherwise it returns fal...
int OptimizeStorage()
Make consecutive row index sections contiguous, minimize internal storage used for constructing graph...
bool UpperTriangular() const
If matrix is upper triangular in local index space, this query returns true, otherwise it returns fal...
int NumMyRows() const
Returns the number of matrix rows owned by the calling processor.
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.
bool IndicesAreGlobal() const
If matrix indices has not been transformed to local, this query returns true, otherwise it returns fa...
const Epetra_BlockMap & Map() const
Returns the address of the Epetra_BlockMap for this multi-vector.
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.
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.
Epetra_Export: This class builds an export object for efficient exporting of off-processor elements.
Definition: Epetra_Export.h:62
Epetra_Import: This class builds an import object for efficient importing of off-processor elements.
Definition: Epetra_Import.h:63
int NumPermuteIDs() const
Returns the number of elements that are local to the calling processor, but not part of the first Num...
int * ExportPIDs() const
List of processors to which elements will be sent, ExportLIDs() [i] will be sent to processor ExportP...
int * PermuteFromLIDs() const
List of elements in the source map that are permuted.
int NumExportIDs() const
Returns the number of elements that must be sent by the calling processor to other processors.
int NumSameIDs() const
Returns the number of elements that are identical between the source and target maps,...
int * RemoteLIDs() const
List of elements in the target map that are coming from other processors.
int NumRemoteIDs() const
Returns the number of elements that are not on the calling processor.
int * ExportLIDs() const
List of elements that will be sent to other processors.
const Epetra_BlockMap & SourceMap() const
Returns the SourceMap used to construct this importer.
const Epetra_BlockMap & TargetMap() const
Returns the TargetMap used to construct this importer.
Epetra_LongLongVector: A class for constructing and using dense integer vectors on a parallel compute...
int PutValue(long long Value)
Set all elements of the vector to Value.
int MyLength() const
Returns the local vector length on the calling processor of vectors in the multi-vector.
long long MinValue()
Find minimum value.
long long MaxValue()
Find maximum value.
Epetra_Map: A class for partitioning vectors and matrices.
Definition: Epetra_Map.h:119
Epetra_MpiComm: The Epetra MPI Communication Class.
int NumProc() const
Returns total number of processes.
int MyPID() const
Return my process ID.
Epetra_MultiVector: A class for constructing and using dense multi-vectors, vectors and matrices in p...
int Random()
Set multi-vector values to random numbers.
int PutScalar(double ScalarConstant)
Initialize all values in a multi-vector with constant value.
static void SetTracebackMode(int TracebackModeValue)
Set the value of the Epetra_Object error traceback report mode.
Epetra_OffsetIndex: This class builds index for efficient mapping of data from one Epetra_CrsGraph ba...
Epetra_SerialComm: The Epetra Serial Communication Class.
static int GetPids(const Epetra_Import &Importer, std::vector< int > &pids, bool use_minus_one_for_local)
Epetra_Util GetPids function.
Epetra_Vector: A class for constructing and using dense vectors on a parallel computer.
#define EPETRA_TEST_ERR(a, b)
int main(int argc, char *argv[])
int special_submap_import_test(Epetra_Comm &Comm)
int combine_mode_test(Epetra_Comm &Comm)
int test_import_gid(const char *name, Epetra_LongLongVector &Source, Epetra_LongLongVector &Target, const Epetra_Import &Import)
int alternate_import_constructor_test(Epetra_Comm &Comm)