Epetra Package Browser (Single Doxygen Collection) Development
Loading...
Searching...
No Matches
Epetra_BasicDirectory.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"
45#include "Epetra_BlockMap.h"
46#include "Epetra_Map.h"
47#include "Epetra_Comm.h"
48#include "Epetra_Distributor.h"
49#include "Epetra_Util.h"
50
51//==============================================================================
52// Epetra_BasicDirectory constructor for a Epetra_BlockMap object
54 : DirectoryMap_(0),
55 ProcList_(0),
56 ProcListLists_(0),
57 ProcListLens_(0),
58 numProcLists_(0),
59 entryOnMultipleProcs_(false),
60 LocalIndexList_(0),
61 SizeList_(0),
62 SizeIsConst_(true)
63#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
64 ,AllMinGIDs_int_(0)
65#endif
66#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
67 ,AllMinGIDs_LL_(0)
68#endif
69{
70 // Test for simple cases
71
72 // Uniprocessor and local map cases (Nothing to set up)
73
74 if (!(Map.DistributedGlobal())) return;
75
76 // Linear Map case
77
78 else if (Map.LinearMap()) {
79
80 // Build a list of the Minimum global ids for all processors on each processor.
81 // Since the map is linear, we know that all GIDs are contiguous on each processor
82 // and can be found using the MinGIDs.
83
84 int NumProc = Map.Comm().NumProc();
85
86#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
87 if(Map.GlobalIndicesInt())
88 {
89 AllMinGIDs_int_ = new int[NumProc+1];
90 int MinMyGID = (int) Map.MinMyGID64();
91 Map.Comm().GatherAll(&MinMyGID, AllMinGIDs_int_, 1);
92 AllMinGIDs_int_[NumProc] = (int) (1 + Map.MaxAllGID64()); // Set max cap
93 }
94 else
95#endif
96#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
97 if(Map.GlobalIndicesLongLong())
98 {
99 AllMinGIDs_LL_ = new long long[NumProc+1];
100 long long MinMyGID = Map.MinMyGID64();
101 Map.Comm().GatherAll(&MinMyGID, AllMinGIDs_LL_, 1);
102 AllMinGIDs_LL_[NumProc] = 1 + Map.MaxAllGID64(); // Set max cap
103 }
104 else
105#endif
106 throw "Epetra_BasicDirectory::Epetra_BasicDirectory: Unknown map index type";
107 }
108
109 // General case. Need to build a directory via calls to communication functions
110 else {
111#ifndef NDEBUG
112 int flag = -1;
113#endif
114 if(Map.GlobalIndicesInt())
115#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
116#ifndef NDEBUG
117 flag =
118#endif
119 Generate<int>(Map);
120#else
121 throw "Epetra_BasicDirectory::Epetra_BasicDirectory: ERROR, GlobalIndicesInt but no API for it.";
122#endif
123 else if(Map.GlobalIndicesLongLong())
126 flag =
127#endif
129#else
130 throw "Epetra_BasicDirectory::Epetra_BasicDirectory: ERROR, GlobalIndicesLongLong but no API for it.";
131#endif
132
133 assert(flag==0);
134 }
135}
136
137//==============================================================================
138// Epetra_BasicDirectory copy constructor
140 : DirectoryMap_(0),
141 ProcList_(0),
142 ProcListLists_(0),
143 ProcListLens_(0),
144 numProcLists_(0),
145 entryOnMultipleProcs_(false),
146 LocalIndexList_(0),
147 SizeList_(0),
148 SizeIsConst_(Directory.SizeIsConst_)
149#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
150 ,AllMinGIDs_int_(0)
151#endif
152#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
153 ,AllMinGIDs_LL_(0)
154#endif
155{
156 if (Directory.DirectoryMap_!=0) DirectoryMap_ = new Epetra_Map(Directory.DirectoryMap());
157
159
160 if (Directory.ProcList_!=0) {
161 ProcList_ = new int[Dir_NumMyElements];
162 for (int i=0; i<Dir_NumMyElements; i++) ProcList_[i] = Directory.ProcList_[i];
163 }
164 if (Directory.LocalIndexList_!=0) {
166 for (int i=0; i<Dir_NumMyElements; i++) LocalIndexList_[i] = Directory.LocalIndexList_[i];
167 }
168 if (Directory.SizeList_!=0) {
169 SizeList_ = new int[Dir_NumMyElements];
170 for (int i=0; i<Dir_NumMyElements; i++) SizeList_[i] = Directory.SizeList_[i];
171 }
172#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
173 if (Directory.AllMinGIDs_int_!=0) {
174 int NumProc = DirectoryMap_->Comm().NumProc();
175 AllMinGIDs_int_ = new int[NumProc+1];
176 for (int i=0; i<NumProc+1; i++) AllMinGIDs_int_[i] = Directory.AllMinGIDs_int_[i];
177 }
178#endif
179#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
180 if (Directory.AllMinGIDs_LL_!=0) {
181 int NumProc = DirectoryMap_->Comm().NumProc();
182 AllMinGIDs_LL_ = new long long[NumProc+1];
183 for (int i=0; i<NumProc+1; i++) AllMinGIDs_LL_[i] = Directory.AllMinGIDs_LL_[i];
184 }
185#endif
186
187 if (Directory.numProcLists_ > 0) {
188 int num = Directory.numProcLists_;
189 ProcListLens_ = new int[num];
190 ProcListLists_ = new int*[num];
192
193 for(int i=0; i<num; ++i) {
194 int len = Directory.ProcListLens_[i];
196
197 if (len > 0) {
198 ProcListLists_[i] = new int[len];
199 const int* dir_list = Directory.ProcListLists_[i];
200 for(int j=0; j<len; ++j) {
202 }
203 }
204 else ProcListLists_[i] = 0;
205 }
206 }
207
208 entryOnMultipleProcs_ = Directory.entryOnMultipleProcs_;
209}
210
211//==============================================================================
212// Epetra_BasicDirectory destructor
214{
215 if (numProcLists_>0) {
216 for(int i=0; i<numProcLists_; ++i) {
217 if (ProcListLens_[i] > 0) delete [] ProcListLists_[i];
218 }
219 delete [] ProcListLists_; ProcListLists_ = 0;
220 delete [] ProcListLens_; ProcListLens_ = 0;
221 numProcLists_ = 0;
222 }
223
224 if( DirectoryMap_ != 0 ) delete DirectoryMap_;
225 if( ProcList_ != 0 ) delete [] ProcList_;
226 if( LocalIndexList_ != 0 ) delete [] LocalIndexList_;
227 if( SizeList_ != 0 ) delete [] SizeList_;
228#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
229 if( AllMinGIDs_int_ != 0 ) delete [] AllMinGIDs_int_;
230 AllMinGIDs_int_ = 0;
231#endif
232#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
233 if( AllMinGIDs_LL_ != 0 ) delete [] AllMinGIDs_LL_;
234 AllMinGIDs_LL_ = 0;
235#endif
236
237 DirectoryMap_ = 0;
238 ProcList_ = 0 ;
239 LocalIndexList_ = 0;
240 SizeList_ = 0;
241}
242
243//==============================================================================
245{
247 ProcListLens_ = new int[numProcLists_];
248 ProcListLists_ = new int*[numProcLists_];
249
250 for(int i=0; i<numProcLists_; ++i) {
251 ProcListLens_[i] = 0;
252 ProcListLists_[i] = 0;
253 }
254}
255
256//==============================================================================
258{
259 int insertPoint = -1;
262 if (index < 0) {
263 int tmp = ProcListLens_[LID];
265 ProcListLens_[LID], tmp, 1);
266 }
267}
268
269//==============================================================================
270// Generate: Generates Directory Tables
271template<typename int_type>
273{
274 int i;
276 int_type MinAllGID = (int_type) Map.MinAllGID64();
277 int_type MaxAllGID = (int_type) Map.MaxAllGID64();
278 // DirectoryMap will have a range of elements from the minimum to the maximum
279 // GID of the user map, and an IndexBase of MinAllGID from the user map
280 int_type Dir_NumGlobalElements = MaxAllGID - MinAllGID + 1;
281
282 // Create a uniform linear map to contain the directory
283 DirectoryMap_ = new Epetra_Map( Dir_NumGlobalElements, MinAllGID, Map.Comm() );
284
285 int Dir_NumMyElements = DirectoryMap_->NumMyElements(); // Get NumMyElements
286
287
288
289 // Allocate Processor list and Local Index List. Initialize to -1s.
290
291 if (Dir_NumMyElements>0) {
292 ProcList_ = new int[ Dir_NumMyElements ];
294 if (!SizeIsConst_) SizeList_ = new int[ Dir_NumMyElements ];
295 // Initialize values to -1 in case the user global element list does
296 // fill all IDs from MinAllGID to MaxAllGID (e.g., allows global indices to be
297 // all even integers.
298 for (i=0; i<Dir_NumMyElements; i++) {
299 ProcList_[i] = -1;
300 LocalIndexList_[i] = -1;
301 if (!SizeIsConst_) SizeList_[i] = -1;
302 }
303 }
304
305
306 // Get list of processors owning the directory entries for the Map GIDs
307
308 int MyPID = Map.Comm().MyPID();
309
311 int * send_procs = 0;
314#if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
316
319 send_procs, 0));
320#endif
321
322 bool det_flag = true;
323
324 int num_recvs=0;
325
327
329
330 if (Map_NumMyElements>0) delete [] send_procs;
331
332 int * export_elements = 0;
333 char * c_import_elements = 0;
334 int * import_elements = 0;
335 int len_import_elements = 0;
336 int * ElementSizeList = 0;
337
338 int packetSize = (int) (sizeof(int_type) + 2*sizeof(int))/sizeof(int); // Assume we will send GIDs, PIDs and LIDs (will increase to 4 if also sending sizes)
339 if (!SizeIsConst_) packetSize++; // Must send element size info also
340
341 if (Map_NumMyElements>0) {
342 if (!SizeIsConst_) ElementSizeList = Map.ElementSizeList();
344 int * ptr = export_elements;
345 for( i = 0; i < Map_NumMyElements; i++ )
346 {
348 ptr += sizeof(int_type)/sizeof(int);
349 *ptr++ = MyPID;
350 *ptr++ = i;
351 if (!SizeIsConst_) *ptr++ = ElementSizeList[i];
352 }
353 }
354
355 //if (num_recvs>0) import_elements = new int[ packetSize * num_recvs ];
356 //for (i=0; i< packetSize*num_recvs; i++) import_elements[i] = 0;
357
358 EPETRA_CHK_ERR(Distor->Do(reinterpret_cast<char *> (export_elements),
359 packetSize * (int)sizeof( int ),
362
363 import_elements = reinterpret_cast<int *>(c_import_elements);
364
365 //bool MYPID = (Map.Comm().MyPID()==0);
366 int curr_LID;
367 //if (MYPID) cout << "Processor " << Map.Comm().MyPID()<< " num_recvs = "<< num_recvs << std::endl << flush;
368 int * ptr = import_elements;
369 for( i = 0; i < num_recvs; i++ )
370 {
371 curr_LID = DirectoryMap_->LID(*(int_type*)ptr); // Convert incoming GID to Directory LID
372 ptr += sizeof(int_type)/sizeof(int);
373 //if (MYPID) cout << " Receive ID = " << i << " GID = " << import_elements[3*i] << " LID = " << curr_LID << std::endl << flush;
374 assert(curr_LID !=-1); // Internal error
375 int proc = *ptr++;
376 if (ProcList_[curr_LID] >= 0) {
377 if (ProcList_[curr_LID] != proc) {
378 if (numProcLists_ < 1) {
380 }
381
384
385 //leave the lowest-numbered proc in ProcList_[curr_LID].
387 }
388 }
389 else {
391 }
393 if (!SizeIsConst_) SizeList_[ curr_LID ] = *ptr++;
394 }
395
396 int localval, globalval;
399 entryOnMultipleProcs_ = globalval > 0 ? true : false;
400
401 if (len_import_elements!=0) delete [] c_import_elements;
402 if (export_elements!=0) delete [] export_elements;
403
404 delete Distor;
405 return(0);
406}
407
408//==============================================================================
413
414//==============================================================================
415// GetDirectoryEntries: Get non-local GID references ( procID and localID )
416// Space should already be allocated for Procs and
417// LocalEntries.
418template<typename int_type>
420 const int NumEntries,
421 const int_type * GlobalEntries,
422 int * Procs,
423 int * LocalEntries,
424 int * EntrySizes,
425 bool high_rank_sharing_procs) const
426{
427 int ierr = 0;
428 int j;
429 int i;
430 int MyPID = Map.Comm().MyPID();
431 int NumProc = Map.Comm().NumProc();
432 int_type n_over_p = (int_type) (Map.NumGlobalElements64() / NumProc);
433
434 // Test for simple cases
435
436 // Uniprocessor and local map cases
437
438 if (!Map.DistributedGlobal()) {
439 int ElementSize = 0;
440 int * ElementSizeList = 0;
441 bool ConstantElementSize = Map.ConstantElementSize();
442 if (ConstantElementSize)
443 ElementSize = Map.MaxElementSize();
444 else
445 ElementSizeList = Map.ElementSizeList();
446 for (i=0; i<NumEntries; i++) {
447 int LID = Map.LID(GlobalEntries[i]); // Get LID
448 // Procs[i] will be MyPID, or -1 if the GID is not owned by this map
449 if (LID==-1) {
450 Procs[i] = -1;
451 ierr = 1; // Send warning error back that one of the GIDs is not part of this map
452 }
453 else Procs[i] = MyPID;
454
455 // Put LID in return array if needed
456 if (LocalEntries!=0) LocalEntries[i] = LID;
457
458 // Fill EntrySizes if needed
459 if (EntrySizes!=0) {
460 if (ConstantElementSize)
461 EntrySizes[i] = ElementSize;
462 else if (LID>-1)
463 EntrySizes[i] = ElementSizeList[LID];
464 else
465 EntrySizes[i] = 0;
466 }
467 }
469 return(0);
470 }
471
472 // Linear Map case
473 if (Map.LinearMap()) {
474
475 int_type MinAllGID = (int_type) Map.MinAllGID64(); // Get Min of all GID
476 int_type MaxAllGID = (int_type) Map.MaxAllGID64(); // Get Max of all GID
477 for (i=0; i<NumEntries; i++) {
478 int LID = -1; // Assume not found
479 int Proc = -1;
480 int_type GID = GlobalEntries[i];
481 if (GID<MinAllGID) ierr = 1;
482 else if (GID>MaxAllGID) ierr = 1;
483 else {
484 // Guess uniform distribution and start a little above it
485 int Proc1 = (int) EPETRA_MIN(GID/EPETRA_MAX(n_over_p,(int_type)1) + 2, (int_type) NumProc-1);
486 bool found = false;
488
489 while (Proc1 >= 0 && Proc1< NumProc) {
490 if (AllMinGIDs_ptr[Proc1]<=GID) {
491 if (GID <AllMinGIDs_ptr[Proc1+1]) {
492 found = true;
493 break;
494 }
495 else Proc1++;
496 }
497 else Proc1--;
498 }
499 if (found) {
500 Proc = Proc1;
501 LID = (int) (GID - AllMinGIDs_ptr[Proc]);
502 }
503 }
504 Procs[i] = Proc;
505 if (LocalEntries!=0) LocalEntries[i] = LID;
506 }
507 if (EntrySizes!=0) {
508 if (Map.ConstantElementSize()) {
509 int ElementSize = Map.MaxElementSize();
510 for (i=0; i<NumEntries; i++) EntrySizes[i] = ElementSize;
511 }
512 else {
513 int * ElementSizeList = Map.ElementSizeList(); // We know this exists
514
515
517
518 int Size_num_sends;
520 int * Size_send_procs = 0;
521
522
523 EPETRA_CHK_ERR(Size_Distor->CreateFromRecvs( NumEntries, GlobalEntries, Procs, true,
525
526 int * Size_exports = 0;
527 char * c_Size_imports = 0;
528 int * Size_imports = 0;
529 int packetSize = (int) (sizeof(int_type) + sizeof(int))/sizeof(int);
530 if (Size_num_sends>0) {
532 for( i = 0; i < Size_num_sends; i++ )
533 {
536 assert(Size_curr_LID!=-1); // Internal error
538 int Size_curr_size = ElementSizeList[Size_curr_LID];
540 }
541 }
542
543 int len_Size_imports = 0;
544 EPETRA_CHK_ERR(Size_Distor->Do( reinterpret_cast<char*> (Size_exports),
545 packetSize * (int)sizeof( int ),
548 Size_imports = reinterpret_cast<int*>(c_Size_imports);
549
550 for( i = 0; i < NumEntries; i++ )
551 {
552
553 // Need to change !!!!
554 //bool found = false;
556 for( j = 0; j < NumEntries; j++ )
558 {
560 // found = true;
561 break;
562 }
563 // if (!found) cout << "Internal error: Epetra_BasicDirectory::GetDirectoryEntries: Global Index " << curr_LID
564 // << " not on processor " << MyPID << std::endl; abort();
565 }
566
567 if( Size_send_gids != 0 ) delete [] Size_send_gids;
568 if( Size_send_procs != 0 ) delete [] Size_send_procs;
569
570 if( len_Size_imports != 0 ) delete [] c_Size_imports;
571 if( Size_exports != 0 ) delete [] Size_exports;
572
573 delete Size_Distor;
574 }
575 }
577 return(0);
578 }
579
580 // General case (need to set up an actual directory structure)
581
582 int PacketSize = (int) (sizeof(int_type) + sizeof(int))/sizeof(int); // We will send at least the GID and PID. Might also send LID and Size info
583 bool DoSizes = false;
584 if (EntrySizes!=0) {
585 if (Map.ConstantElementSize()) {
586 int ElementSize = Map.MaxElementSize();
587 for (i=0; i<NumEntries; i++) EntrySizes[i] = ElementSize;
588 }
589 else {
590 DoSizes = true;
591 PacketSize++; // Sending Size info
592 }
593 }
594
595 bool DoLIDs = (LocalEntries!=0); // Do LIDs?
596 if (DoLIDs) PacketSize++; // Sending LIDs also
597
598
600
601
602 int * dir_procs = 0;
603 if (NumEntries>0) dir_procs = new int[ NumEntries ];
604
605#if !defined(EPETRA_NO_32BIT_GLOBAL_INDICES) || !defined(EPETRA_NO_64BIT_GLOBAL_INDICES)
606 // Get directory locations for the requested list of entries
608#endif
609
610 //Check for unfound GlobalEntries and set corresponding Procs to -1
611 int NumMissing = 0;
612 {for( i = 0; i < NumEntries; ++i )
613 if( dir_procs[i] == -1 )
614 {
615 Procs[i] = -1;
616 if (DoLIDs) LocalEntries[i] = -1;
617 ++NumMissing;
618 }}
619
620 int num_sends;
621 int_type * send_gids = 0;
622 int * send_procs = 0;
623
624 EPETRA_CHK_ERR(Distor->CreateFromRecvs( NumEntries, GlobalEntries, dir_procs, true,
626
627 if (NumEntries>0) delete [] dir_procs;
628
629
630 int curr_LID;
631 int * exports = 0;
632 char * c_imports = 0;
633 int * imports = 0;
634 int len_imports = 0;
635 if (num_sends>0) {
636 exports = new int[ PacketSize * num_sends ];
637 int * ptr = exports;
638 for( i = 0; i < num_sends; i++ )
639 {
641 *(int_type*)ptr = curr_GID;
642 ptr += sizeof(int_type)/sizeof(int);
644 assert(curr_LID!=-1); // Internal error
645 if (high_rank_sharing_procs==false) {
646 *ptr++ = ProcList_[ curr_LID ];
647 }
648 else {
649 //high_rank_sharing_procs==true means that if multiple procs share a
650 //GID, we want to use the proc with highest rank rather than the
651 //proc with lowest rank.
652 if (numProcLists_ > 0) {
654 if (num > 1) {
656 }
657 else {
658 *ptr++ = ProcList_[ curr_LID ];
659 }
660 }
661 else {
662 *ptr++ = ProcList_[ curr_LID ];
663 }
664 }
665
667 if (DoSizes) *ptr++ = SizeList_[curr_LID];
668 }
669 }
670
671 int NumRecv = NumEntries - NumMissing;
672 EPETRA_CHK_ERR(Distor->Do(reinterpret_cast<char*> (exports),
673 PacketSize * (int)sizeof( int ),
675 c_imports));
676 imports = reinterpret_cast<int*>(c_imports);
677
678 //create a sorted copy of the GlobalEntries array, along with a companion
679 //array that will allow us to put result arrays (Procs, LocalEntries &
680 //EntrySizes) in the same order as the unsorted GlobalEntries array
681 int* sortedGE_int = new int[NumEntries*(1 + sizeof(int_type)/sizeof(int))];
682 int* offsets = sortedGE_int+NumEntries*sizeof(int_type)/sizeof(int);
683 int_type* sortedGE = reinterpret_cast<int_type*>(sortedGE_int);
684
685 for(i=0; i<NumEntries; ++i) {
686 offsets[i] = i;
687 }
688
689 std::memcpy(sortedGE, GlobalEntries, NumEntries*sizeof(int_type));
691 Utils.Sort(true, NumEntries, sortedGE, 0, 0, 1, &offsets, 0, 0);
692
693 int * ptr = imports;
694 int insertPoint; //insertPoint won't be used, but is argument to binary_search
695
696 for( i = 0; i < NumRecv; i++ ) {
698 ptr += sizeof(int_type)/sizeof(int);
700 if (j > -1) {
701 Procs[offsets[j]] = *ptr++;
702 if (DoLIDs) LocalEntries[offsets[j]] = *ptr++;
703 if (DoSizes) EntrySizes[offsets[j]] = *ptr++;
704 }
705 }
706
707 delete [] sortedGE_int;
708
709 if( send_gids ) delete [] send_gids;
710 if( send_procs ) delete [] send_procs;
711
712 if( len_imports ) delete [] c_imports;
713 if( exports ) delete [] exports;
714
715 delete Distor;
716 return(0);
717}
718
719//==============================================================================
720#ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
722 const int NumEntries,
723 const int * GlobalEntries,
724 int * Procs,
725 int * LocalEntries,
726 int * EntrySizes,
727 bool high_rank_sharing_procs) const
728{
729 if(!Map.GlobalIndicesInt())
730 throw "Epetra_BasicDirectory::GetDirectoryEntries: int version can't be called for non int map";
731
734}
735#endif
736
737#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
738// GetDirectoryEntries: Get non-local GID references ( procID and localID )
739// Space should already be allocated for Procs and
740// LocalEntries.
742 const int NumEntries,
743 const long long * GlobalEntries,
744 int * Procs,
745 int * LocalEntries,
746 int * EntrySizes,
747 bool high_rank_sharing_procs) const
748{
749 if(!Map.GlobalIndicesLongLong())
750 throw "Epetra_BasicDirectory::GetDirectoryEntries: long long version can't be called for non long long map";
751
754}
755#endif
756
757//==============================================================================
758void Epetra_BasicDirectory::Print(std::ostream & os) const {
759
760 int MyPID;
761 if( DirectoryMap_ != 0 ) {;
762 MyPID = DirectoryMap_->Comm().MyPID();
763 os << MyPID << " Epetra_BasicDirectory Object: "
764 << DirectoryMap_->NumMyElements() << std::endl;
765 for( int i = 0; i < DirectoryMap_->NumMyElements(); i++ ) {
766 os << " " << i << " " << ProcList_[i] << " "
767 << LocalIndexList_[i];
768 if (!SizeIsConst_)
769 os << " " << SizeList_[i];
770 os << std::endl;
771 os << std::endl;
772 }
773 }
774 else
775 {
776 std::cout << "Epetra_BasicDirectory not setup<<<<<<" << std::endl;
777 }
778
779 return;
780}
781
782//--------------------------------------------------------------------------------
784{
785 (void)src;
786 //not currently supported
787 bool throw_error = true;
788 if (throw_error) {
789 std::cerr << std::endl
790 << "Epetra_BasicDirectory::operator= not supported."
791 << std::endl;
792 throw -1;
793 }
794 return( *this );
795}
#define EPETRA_MIN(x, y)
#define EPETRA_MAX(x, y)
#define EPETRA_CHK_ERR(a)
int Epetra_Util_binary_search(T item, const T *list, int len, int &insertPoint)
Utility function to perform a binary-search on a list of data.
int Epetra_Util_insert(T item, int offset, T *&list, int &usedLength, int &allocatedLength, int allocChunkSize=32)
Function to insert an item in a list, at a specified offset.
Epetra_BasicDirectory: This class allows Epetra_Map objects to reference non-local elements.
Epetra_BasicDirectory(const Epetra_BlockMap &Map)
Epetra_BasicDirectory constructor.
int GetDirectoryEntries(const Epetra_BlockMap &Map, const int NumEntries, const int *GlobalEntries, int *Procs, int *LocalEntries, int *EntrySizes, bool high_rank_sharing_procs=false) const
GetDirectoryEntries : Returns proc and local id info for non-local map entries.
virtual ~Epetra_BasicDirectory(void)
Epetra_BasicDirectory destructor.
virtual void Print(std::ostream &os) const
Print method.
void addProcToList(int proc, int LID)
int Generate(const Epetra_BlockMap &Map)
Generate: Sets up Directory tables.
bool GIDsAllUniquelyOwned() const
GIDsAllUniquelyOwned: returns true if all GIDs appear on just one processor.
Epetra_BasicDirectory & operator=(const Epetra_BasicDirectory &src)
Epetra_BlockMap: A class for partitioning block element vectors and matrices.
int RemoteIDList(int NumIDs, const int *GIDList, int *PIDList, int *LIDList) const
Returns the processor IDs and corresponding local index value for a given list of global indices.
int MaxElementSize() const
Maximum element size across all processors.
long long MaxAllGID64() const
int * ElementSizeList() const
List of the element sizes corresponding to the array MyGlobalElements().
bool DistributedGlobal() const
Returns true if map is defined across more than one processor.
int LID(int GID) const
Returns local ID of global ID, return -1 if not found on this processor.
bool LinearMap() const
Returns true if the global ID space is contiguously divided (but not necessarily uniformly) across al...
long long NumGlobalElements64() const
bool GlobalIndicesInt() const
Returns true if map create with int NumGlobalElements.
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
bool ConstantElementSize() const
Returns true if map has constant element size.
long long MinAllGID64() const
long long MinMyGID64() const
int NumMyElements() const
Number of elements on the calling processor.
bool GlobalIndicesLongLong() const
Returns true if map create with long long NumGlobalElements.
int MyGlobalElementsPtr(int *&MyGlobalElementList) const
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 GatherAll(double *MyVals, double *AllVals, int Count) const =0
Epetra_Comm All Gather function.
virtual int MyPID() const =0
Return my process ID.
virtual Epetra_Distributor * CreateDistributor() const =0
Create a distributor object.
Epetra_Distributor: The Epetra Gather/Scatter Setup Base Class.
Epetra_Map: A class for partitioning vectors and matrices.
Definition Epetra_Map.h:119
Epetra_Util: The Epetra Util Wrapper Class.
Definition Epetra_Util.h:79
static void EPETRA_LIB_DLL_EXPORT Sort(bool SortAscending, int NumKeys, T *Keys, int NumDoubleCompanions, double **DoubleCompanions, int NumIntCompanions, int **IntCompanions, int NumLongLongCompanions, long long **LongLongCompanions)
Epetra_Util Sort Routine (Shell sort)