Epetra Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
Epetra_IntVector.cpp
Go to the documentation of this file.
1
2//@HEADER
3// ************************************************************************
4//
5// Epetra: Linear Algebra Services Package
6// Copyright 2011 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ************************************************************************
41//@HEADER
42
43#include "Epetra_ConfigDefs.h"
44#include "Epetra_IntVector.h"
45#include "Epetra_Map.h"
46#include "Epetra_Comm.h"
47
48//=============================================================================
50 : Epetra_DistObject(map, "Epetra::IntVector"),
51 Values_(0),
52 UserAllocated_(false),
53 Allocated_(false)
54{
56 if(zeroOut) PutValue(0); // Zero out values
57}
58//=============================================================================
60 : Epetra_DistObject(Source),
61 Values_(0),
62 UserAllocated_(false),
63 Allocated_(false)
64{
66 DoCopy(Source.Values_);
67}
68//=============================================================================
70 : Epetra_DistObject(map, "Epetra::IntVector"),
71 Values_(0),
72 UserAllocated_(false),
73 Allocated_(false)
74{
75 if (CV==Copy) {
77 DoCopy(V);
78 }
79 else {
81 DoView(V);
82 }
83}
84//=========================================================================
86
87
88 if (Allocated_ && (!UserAllocated_) && Values_!=0) delete [] Values_;
89}
90
91//=========================================================================
93{
94
95 if (Allocated_) return(0);
96
97 int myLength = MyLength();
98 if (myLength>0)
99 Values_ = new int[myLength];
100 else
101 Values_ = 0;
102
103 Allocated_ = true;
104 UserAllocated_ = false;
105 return(0);
106}
107
108//=========================================================================
110{
111 int iend = MyLength();
112 for (int i=0; i<iend; i++) Values_[i] = V[i];
113
114 return(0);
115}
116//=========================================================================
118{
119
120 Allocated_ = true;
121 UserAllocated_ = true;
122
123 return(0);
124}
125
126//=========================================================================
128{
129
130 Values_ = V;
131
132 return(0);
133}
134//=============================================================================
136
137 int iend = MyLength();
138 for (int i=0; i<iend; i++) V[i] = Values_[i];
139 return(0);
140}
141
142//=============================================================================
144{
145 *V = Values_;
146 return(0);
147}
148
149//=============================================================================
151 int iend = MyLength();
152 for (int i=0; i<iend; i++) Values_[i] = Value;
153 return(0);
154}
155//=============================================================================
157
158 int result = -2000000000; // Negative 2 billion is close to smallest 32 bit int
159 int iend = MyLength();
160 if (iend>0) result = Values_[0];
161 for (int i=0; i<iend; i++) result = EPETRA_MAX(result, Values_[i]);
162 int globalResult;
163 this->Comm().MaxAll(&result, &globalResult, 1);
164 return(globalResult);
165}
166//=============================================================================
168
169 int result = 2000000000; // 2 billion is close to largest 32 bit int
170 int iend = MyLength();
171 if (iend>0) result = Values_[0];
172 for (int i=0; i<iend; i++) result = EPETRA_MIN(result, Values_[i]);
173 int globalResult;
174 this->Comm().MinAll(&result, &globalResult, 1);
175 return(globalResult);
176}
177//========================================================================
179
180
181 if (MyLength() != V.MyLength())
182 throw ReportError("Length of IntVectors incompatible in Assign. The this IntVector has MyLength = " + toString(MyLength())
183 + ". The V IntVector has MyLength = " + toString(V.MyLength()), -1);
184
185 int iend = MyLength();
186 for (int i=0; i<iend; i++) Values_[i] =V[i];
187 return(*this);
188}
189
190void Epetra_IntVector::Print(std::ostream& os) const {
191 int MyPID = Map().Comm().MyPID();
192 int NumProc = Map().Comm().NumProc();
193
194 for (int iproc=0; iproc < NumProc; iproc++) {
195 if (MyPID==iproc) {
196 int NumMyElements1 =Map(). NumMyElements();
197 int MaxElementSize1 = Map().MaxElementSize();
198 int * MyGlobalElements1_int = 0;
199 long long * MyGlobalElements1_LL = 0;
200 if(Map().GlobalIndicesInt()) {
201#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
202 MyGlobalElements1_int = Map().MyGlobalElements();
203#else
204 throw ReportError("Epetra_IntVector::Print: Global indices int but no API for it.",-1);
205#endif
206 }
207 else if(Map().GlobalIndicesLongLong()) {
208#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
209 MyGlobalElements1_LL = Map().MyGlobalElements64();
210#else
211 throw ReportError("Epetra_IntVector::Print: Global indices long long but no API for it.",-1);
212#endif
213 }
214 int * FirstPointInElementList1=0;
215 if (MaxElementSize1!=1) FirstPointInElementList1 = Map().FirstPointInElementList();
216
217 if (MyPID==0) {
218 os.width(8);
219 os << " MyPID"; os << " ";
220 os.width(12);
221 if (MaxElementSize1==1)
222 os << "GID ";
223 else
224 os << " GID/Point";
225 os.width(20);
226 os << "Value ";
227 os << std::endl;
228 }
229 for (int i=0; i < NumMyElements1; i++) {
230 for (int ii=0; ii< Map().ElementSize(i); ii++) {
231 int iii;
232 os.width(10);
233 os << MyPID; os << " ";
234 os.width(10);
235 if (MaxElementSize1==1) {
236 if(MyGlobalElements1_int)
237 os << MyGlobalElements1_int[i] << " ";
238 if(MyGlobalElements1_LL)
239 os << MyGlobalElements1_LL[i] << " ";
240 iii = i;
241 }
242 else {
243 if(MyGlobalElements1_int)
244 os << MyGlobalElements1_int[i]<< "/" << ii << " ";
245 if(MyGlobalElements1_LL)
246 os << MyGlobalElements1_LL[i]<< "/" << ii << " ";
247 iii = FirstPointInElementList1[i]+ii;
248 }
249 os.width(20);
250 os << Values_[iii];
251 os << std::endl;
252 }
253 }
254 os << std::flush;
255 }
256
257 // Do a few global ops to give I/O a chance to complete
258 Map().Comm().Barrier();
259 Map().Comm().Barrier();
260 Map().Comm().Barrier();
261 }
262 return;
263}
264//=========================================================================
266{
267 (void)Source;
268 return(0);
269}
270
271//=========================================================================
273 int NumSameIDs,
274 int NumPermuteIDs,
275 int * PermuteToLIDs,
276 int *PermuteFromLIDs,
277 const Epetra_OffsetIndex * Indexor,
278 Epetra_CombineMode CombineMode)
279{
280 (void)Indexor;
281 const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source);
282
283 int * From;
284 A.ExtractView(&From);
285 int *To = Values_;
286
287 int * ToFirstPointInElementList = 0;
288 int * FromFirstPointInElementList = 0;
289 int * FromElementSizeList = 0;
290 int MaxElementSize = Map().MaxElementSize();
291 bool ConstantElementSize = Map().ConstantElementSize();
292
293 if (!ConstantElementSize) {
294 ToFirstPointInElementList = Map().FirstPointInElementList();
295 FromFirstPointInElementList = A.Map().FirstPointInElementList();
296 FromElementSizeList = A.Map().ElementSizeList();
297 }
298 int j, jj, jjj, k;
299
300 int NumSameEntries;
301
302 bool Case1 = false;
303 bool Case2 = false;
304 // bool Case3 = false;
305
306 if (MaxElementSize==1) {
307 Case1 = true;
308 NumSameEntries = NumSameIDs;
309 }
310 else if (ConstantElementSize) {
311 Case2 = true;
312 NumSameEntries = NumSameIDs * MaxElementSize;
313 }
314 else {
315 // Case3 = true;
316 NumSameEntries = FromFirstPointInElementList[NumSameIDs];
317 }
318
319 // Short circuit for the case where the source and target vector is the same.
320 if (To==From) NumSameEntries = 0;
321
322 // Do copy first
323 if (NumSameIDs>0)
324 if (To!=From) {
325 if (CombineMode==Epetra_AddLocalAlso)
326 for (j=0; j<NumSameEntries; j++) To[j] += From[j]; // Add to existing value
327 else
328 for (j=0; j<NumSameEntries; j++) To[j] = From[j];
329 }
330 // Do local permutation next
331 if (NumPermuteIDs>0) {
332
333 // Point entry case
334 if (Case1) {
335
336 if (CombineMode==Epetra_AddLocalAlso)
337 for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] += From[PermuteFromLIDs[j]]; // Add to existing value
338 else
339 for (j=0; j<NumPermuteIDs; j++) To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
340 }
341 // constant element size case
342 else if (Case2) {
343
344 if (CombineMode==Epetra_AddLocalAlso)
345 for (j=0; j<NumPermuteIDs; j++) {
346 jj = MaxElementSize*PermuteToLIDs[j];
347 jjj = MaxElementSize*PermuteFromLIDs[j];
348 for (k=0; k<MaxElementSize; k++)
349 To[jj+k] += From[jjj+k];
350 }
351 else
352 for (j=0; j<NumPermuteIDs; j++) {
353 jj = MaxElementSize*PermuteToLIDs[j];
354 jjj = MaxElementSize*PermuteFromLIDs[j];
355 for (k=0; k<MaxElementSize; k++)
356 To[jj+k] = From[jjj+k];
357 }
358 }
359
360 // variable element size case
361 else {
362
363 if (CombineMode==Epetra_AddLocalAlso)
364 for (j=0; j<NumPermuteIDs; j++) {
365 jj = ToFirstPointInElementList[PermuteToLIDs[j]];
366 jjj = FromFirstPointInElementList[PermuteFromLIDs[j]];
367 int ElementSize = FromElementSizeList[PermuteFromLIDs[j]];
368 for (k=0; k<ElementSize; k++)
369 To[jj+k] += From[jjj+k];
370 }
371 else
372 for (j=0; j<NumPermuteIDs; j++) {
373 jj = ToFirstPointInElementList[PermuteToLIDs[j]];
374 jjj = FromFirstPointInElementList[PermuteFromLIDs[j]];
375 int ElementSize = FromElementSizeList[PermuteFromLIDs[j]];
376 for (k=0; k<ElementSize; k++)
377 To[jj+k] = From[jjj+k];
378 }
379 }
380 }
381 return(0);
382}
383
384//=========================================================================
386 int NumExportIDs,
387 int * ExportLIDs,
388 int & LenExports,
389 char * & Exports,
390 int & SizeOfPacket,
391 int * Sizes,
392 bool & VarSizes,
393 Epetra_Distributor & Distor)
394{
395 (void)Sizes;
396 (void)VarSizes;
397 (void)Distor;
398 const Epetra_IntVector & A = dynamic_cast<const Epetra_IntVector &>(Source);
399
400 int j, jj, k;
401
402 int * From;
403 A.ExtractView(&From);
404 int MaxElementSize = Map().MaxElementSize();
405 bool ConstantElementSize = Map().ConstantElementSize();
406
407 int * FromFirstPointInElementList = 0;
408 int * FromElementSizeList = 0;
409
410 if (!ConstantElementSize) {
411 FromFirstPointInElementList = A.Map().FirstPointInElementList();
412 FromElementSizeList = A.Map().ElementSizeList();
413 }
414
415 SizeOfPacket = MaxElementSize * (int)sizeof(int);
416
417 if(NumExportIDs*SizeOfPacket>LenExports) {
418 if (LenExports>0) delete [] Exports;
419 LenExports = NumExportIDs*SizeOfPacket;
420 Exports = new char[LenExports];
421 }
422
423 int * ptr;
424
425 if (NumExportIDs>0) {
426 ptr = (int *) Exports;
427
428 // Point entry case
429 if (MaxElementSize==1) for (j=0; j<NumExportIDs; j++) *ptr++ = From[ExportLIDs[j]];
430
431 // constant element size case
432 else if (ConstantElementSize) {
433
434 for (j=0; j<NumExportIDs; j++) {
435 jj = MaxElementSize*ExportLIDs[j];
436 for (k=0; k<MaxElementSize; k++)
437 *ptr++ = From[jj+k];
438 }
439 }
440
441 // variable element size case
442 else {
443
444 int thisSizeOfPacket = MaxElementSize;
445 for (j=0; j<NumExportIDs; j++) {
446 ptr = (int *) Exports + j*thisSizeOfPacket;
447 jj = FromFirstPointInElementList[ExportLIDs[j]];
448 int ElementSize = FromElementSizeList[ExportLIDs[j]];
449 for (k=0; k<ElementSize; k++)
450 *ptr++ = From[jj+k];
451 }
452 }
453 }
454
455 return(0);
456}
457
458//=========================================================================
460 int NumImportIDs,
461 int * ImportLIDs,
462 int LenImports,
463 char * Imports,
464 int & SizeOfPacket,
465 Epetra_Distributor & Distor,
466 Epetra_CombineMode CombineMode,
467 const Epetra_OffsetIndex * Indexor)
468{
469 (void)Source;
470 (void)LenImports;
471 (void)SizeOfPacket;
472 (void)Distor;
473 (void)Indexor;
474 int j, jj, k;
475
476 if( CombineMode != Add
477 && CombineMode != Zero
478 && CombineMode != Insert
479 && CombineMode != Average
480 && CombineMode != AbsMax )
481 EPETRA_CHK_ERR(-1); //Unsupported CombinedMode, will default to Zero
482
483 if (NumImportIDs<=0) return(0);
484
485 int * To = Values_;
486 int MaxElementSize = Map().MaxElementSize();
487 bool ConstantElementSize = Map().ConstantElementSize();
488
489 int * ToFirstPointInElementList = 0;
490 int * ToElementSizeList = 0;
491
492 if (!ConstantElementSize) {
493 ToFirstPointInElementList = Map().FirstPointInElementList();
494 ToElementSizeList = Map().ElementSizeList();
495 }
496
497 int * ptr;
498 // Unpack it...
499
500 ptr = (int *) Imports;
501
502 // Point entry case
503 if (MaxElementSize==1) {
504
505 if (CombineMode==Add)
506 for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] += *ptr++; // Add to existing value
507 else if(CombineMode==Insert)
508 for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] = *ptr++;
509 else if(CombineMode==AbsMax)
510 for (j=0; j<NumImportIDs; j++) {
511 To[ImportLIDs[j]] = EPETRA_MAX( To[ImportLIDs[j]],std::abs(*ptr));
512 ptr++;
513 }
514 // Note: The following form of averaging is not a true average if more that one value is combined.
515 // This might be an issue in the future, but we leave this way for now.
516 else if(CombineMode==Average)
517 for (j=0; j<NumImportIDs; j++) {To[ImportLIDs[j]] += *ptr++; To[ImportLIDs[j]] /= 2;}
518 }
519
520 // constant element size case
521
522 else if (ConstantElementSize) {
523
524 if (CombineMode==Add) {
525 for (j=0; j<NumImportIDs; j++) {
526 jj = MaxElementSize*ImportLIDs[j];
527 for (k=0; k<MaxElementSize; k++)
528 To[jj+k] += *ptr++; // Add to existing value
529 }
530 }
531 else if(CombineMode==Insert) {
532 for (j=0; j<NumImportIDs; j++) {
533 jj = MaxElementSize*ImportLIDs[j];
534 for (k=0; k<MaxElementSize; k++)
535 To[jj+k] = *ptr++;
536 }
537 }
538 else if(CombineMode==AbsMax) {
539 for (j=0; j<NumImportIDs; j++) {
540 jj = MaxElementSize*ImportLIDs[j];
541 for (k=0; k<MaxElementSize; k++) {
542 To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
543 ptr++;
544 }
545 }
546 }
547 // Note: The following form of averaging is not a true average if more that one value is combined.
548 // This might be an issue in the future, but we leave this way for now.
549 else if(CombineMode==Average) {
550 for (j=0; j<NumImportIDs; j++) {
551 jj = MaxElementSize*ImportLIDs[j];
552 for (k=0; k<MaxElementSize; k++)
553 { To[jj+k] += *ptr++; To[jj+k] /= 2;}
554 }
555 }
556 }
557
558 // variable element size case
559
560 else {
561
562 int thisSizeOfPacket = MaxElementSize;
563
564 if (CombineMode==Add) {
565 for (j=0; j<NumImportIDs; j++) {
566 ptr = (int *) Imports + j*thisSizeOfPacket;
567 jj = ToFirstPointInElementList[ImportLIDs[j]];
568 int ElementSize = ToElementSizeList[ImportLIDs[j]];
569 for (k=0; k<ElementSize; k++)
570 To[jj+k] += *ptr++; // Add to existing value
571 }
572 }
573 else if(CombineMode==Insert){
574 for (j=0; j<NumImportIDs; j++) {
575 ptr = (int *) Imports + j*thisSizeOfPacket;
576 jj = ToFirstPointInElementList[ImportLIDs[j]];
577 int ElementSize = ToElementSizeList[ImportLIDs[j]];
578 for (k=0; k<ElementSize; k++)
579 To[jj+k] = *ptr++;
580 }
581 }
582 else if(CombineMode==AbsMax){
583 for (j=0; j<NumImportIDs; j++) {
584 ptr = (int *) Imports + j*thisSizeOfPacket;
585 jj = ToFirstPointInElementList[ImportLIDs[j]];
586 int ElementSize = ToElementSizeList[ImportLIDs[j]];
587 for (k=0; k<ElementSize; k++) {
588 To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
589 ptr++;
590 }
591 }
592 }
593 // Note: The following form of averaging is not a true average if more that one value is combined.
594 // This might be an issue in the future, but we leave this way for now.
595 else if(CombineMode==Average) {
596 for (j=0; j<NumImportIDs; j++) {
597 ptr = (int *) Imports + j*thisSizeOfPacket;
598 jj = ToFirstPointInElementList[ImportLIDs[j]];
599 int ElementSize = ToElementSizeList[ImportLIDs[j]];
600 for (k=0; k<ElementSize; k++)
601 { To[jj+k] += *ptr++; To[jj+k] /= 2;}
602 }
603 }
604 }
605
606 return(0);
607}
Epetra_CombineMode
@ Insert
@ AbsMax
@ Average
@ Zero
@ Epetra_AddLocalAlso
#define EPETRA_MIN(x, y)
#define EPETRA_MAX(x, y)
#define EPETRA_CHK_ERR(a)
Epetra_DataAccess
@ Copy
Epetra_BlockMap: A class for partitioning block element vectors and matrices.
int MaxElementSize() const
Maximum element size across all processors.
int MyGlobalElements(int *MyGlobalElementList) const
Puts list of global elements on this processor into the user-provided array.
long long * MyGlobalElements64() const
int * ElementSizeList() const
List of the element sizes corresponding to the array MyGlobalElements().
int ElementSize() const
Returns the size of elements in the map; only valid if map has constant element size.
int * FirstPointInElementList() const
Pointer to internal array containing a mapping between the local elements and the first local point n...
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
bool ConstantElementSize() const
Returns true if map has constant element size.
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 MinAll(double *PartialMins, double *GlobalMins, int Count) const =0
Epetra_Comm Global Min function.
virtual int MyPID() const =0
Return my process ID.
virtual void Barrier() const =0
Epetra_Comm Barrier function.
Epetra_DistObject: A class for constructing and using dense multi-vectors, vectors and matrices in pa...
const Epetra_BlockMap & Map() const
Returns the address of the Epetra_BlockMap for this multi-vector.
const Epetra_Comm & Comm() const
Returns the address of the Epetra_Comm for this multi-vector.
Epetra_Distributor: The Epetra Gather/Scatter Setup Base Class.
Epetra_IntVector: A class for constructing and using dense integer vectors on a parallel computer.
int ExtractView(int **V) const
Set user-provided address of V.
int CheckSizes(const Epetra_SrcDistObject &A)
Allows the source and target (this) objects to be compared for compatibility, return nonzero if not.
Epetra_IntVector(const Epetra_BlockMap &Map, bool zeroOut=true)
Basic Epetra_IntVector constuctor.
int MaxValue()
Find maximum value.
virtual void Print(std::ostream &os) const
Print method.
int PutValue(int 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.
int ExtractCopy(int *V) const
Put vector values into user-provided array.
virtual ~Epetra_IntVector()
Epetra_IntVector destructor.
int MinValue()
Find minimum value.
int PackAndPrepare(const Epetra_SrcDistObject &Source, int NumExportIDs, int *ExportLIDs, int &LenExports, char *&Exports, int &SizeOfPacket, int *Sizes, bool &VarSizes, Epetra_Distributor &Distor)
Perform any packing or preparation required for call to DoTransfer().
Epetra_IntVector & operator=(const Epetra_IntVector &Source)
= Operator.
int CopyAndPermute(const Epetra_SrcDistObject &Source, int NumSameIDs, int NumPermuteIDs, int *PermuteToLIDs, int *PermuteFromLIDs, const Epetra_OffsetIndex *Indexor, Epetra_CombineMode CombineMode=Zero)
Perform ID copies and permutations that are on processor.
int UnpackAndCombine(const Epetra_SrcDistObject &Source, int NumImportIDs, int *ImportLIDs, int LenImports, char *Imports, int &SizeOfPacket, Epetra_Distributor &Distor, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor)
Perform any unpacking and combining after call to DoTransfer().
virtual int ReportError(const std::string Message, int ErrorCode) const
Error reporting method.
std::string toString(const int &x) const
Epetra_OffsetIndex: This class builds index for efficient mapping of data from one Epetra_CrsGraph ba...
Epetra_SrcDistObject: A class for supporting flexible source distributed objects for import/export op...