44 #include <Epetra_Comm.h>
45 #include <Epetra_CrsMatrix.h>
46 #include <Epetra_Import.h>
47 #include <Epetra_Export.h>
48 #include <Epetra_Distributor.h>
49 #include <Epetra_HashTable.h>
50 #include <Epetra_Util.h>
51 #include <Epetra_Import_Util.h>
52 #include <Epetra_GIDTypeSerialDenseVector.h>
54 #include <Teuchos_TimeMonitor.hpp>
59 #include "Epetra_MpiComm.h"
60 #include "Epetra_MpiDistributor.h"
62 #define MIN(x,y) ((x)<(y)?(x):(y))
63 #define MIN3(x,y,z) ((x)<(y)?(MIN(x,z)):(MIN(y,z)))
72 printf(
"[%d] %s\n",Comm.
MyPID(),label);
74 printf(
"[%d] ProcsTo = ",Comm.
MyPID());
75 for(
int ii=0; ii<MDistor->
NumSends(); ii++)
76 printf(
"%d ",MDistor->
ProcsTo()[ii]);
77 printf(
"\n[%d] ProcsFrom = ",Comm.
MyPID());
88 if(!Import1 && !Import2)
return;
92 if( (!Import1 && Import2) || (Import2 && !Import1) ) {printf(
"[%d] DCI: One Import exists, the other does not\n",PID);
return;}
104 if(Import1->
NumSend() != Import2->
NumSend()) {printf(
"[%d] DCI NumSend() mismatch %d vs. %d\n",PID,Import1->
NumSend(),Import2->
NumSend()); flag=
false;}
106 if(Import1->
NumRecv() != Import2->
NumRecv()) {printf(
"[%d] DCI NumRecv() mismatch %d vs. %d\n",PID,Import1->
NumRecv(),Import2->
NumRecv()); flag=
false;}
109 if(flag) printf(
"[%d] DCI Importers compare OK\n",PID);
121 : numRows(0), numEntriesPerRow(NULL), indices(NULL), values(NULL),
122 remote(NULL), numRemote(0), importColMap(NULL), rowMap(NULL), colMap(NULL),
123 domainMap(NULL), importMatrix(NULL), origMatrix(NULL)
151 std::cout <<
"numRows: " << M.
numRows<<std::endl;
152 for(
int i=0; i<M.
numRows; ++i) {
155 std::cout <<
" *"<<M.
rowMap->GID64(i)<<
" "
159 std::cout <<
" "<<M.
rowMap->GID64(i)<<
" "
168 : ecrsmat_(epetracrsmatrix)
187 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
201 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
218 template<
typename int_type>
226 emap.MyGlobalElementsPtr(rows);
228 for(
int i=0; i<num_rows; ++i) {
229 graph_[rows[i]] =
new std::set<int_type>;
233 template<
typename int_type>
236 typename std::map<int_type,std::set<int_type>*>::iterator
237 iter = graph_.begin(), iter_end = graph_.end();
238 for(; iter!=iter_end; ++
iter) {
245 template<
typename int_type>
251 template<
typename int_type>
255 typename std::map<int_type,std::set<int_type>*>::iterator
256 iter = graph_.find(GlobalRow);
258 if (iter == graph_.end())
return(-1);
260 std::set<int_type>& cols = *(iter->second);
262 for(
int i=0; i<NumEntries; ++i) {
263 cols.insert(Indices[i]);
266 int row_length = cols.size();
267 if (row_length > max_row_length_) max_row_length_ = row_length;
272 template<
typename int_type>
276 return InsertGlobalValues(GlobalRow, NumEntries, Values, Indices);
279 template<
typename int_type>
280 std::map<int_type,std::set<int_type>*>&
286 template<
typename int_type>
291 if (max_row_length < 1)
return;
293 std::vector<int_type> indices(max_row_length);
294 int_type* indices_ptr = &indices[0];
295 std::vector<double> zeros(max_row_length, 0.0);
296 double* zeros_ptr = &zeros[0];
298 std::map<int_type,std::set<int_type>*>& graph = graphbuilder.
get_graph();
300 typename std::map<int_type,std::set<int_type>*>::iterator
301 iter = graph.begin(), iter_end = graph.end();
303 for(; iter!=iter_end; ++
iter) {
304 int_type row = iter->first;
305 std::set<int_type>& cols = *(iter->second);
306 int num_entries = cols.size();
308 typename std::set<int_type>::iterator
309 col_iter = cols.begin(), col_end = cols.end();
310 for(
int j=0; col_iter!=col_end; ++col_iter, ++j) {
311 indices_ptr[j] = *col_iter;
318 template<
typename int_type>
320 const std::vector<int_type>& proc_col_ranges,
321 std::vector<int_type>& send_rows,
322 std::vector<int>& rows_per_send_proc)
328 int* col_indices = NULL;
329 int_type* Tcol_indices = NULL;
330 int num_col_ranges = proc_col_ranges.size()/2;
331 rows_per_send_proc.resize(num_col_ranges);
333 for(
int nc=0; nc<num_col_ranges; ++nc) {
334 int_type first_col = proc_col_ranges[nc*2];
335 int_type last_col = proc_col_ranges[nc*2+1];
336 int num_send_rows = 0;
337 for(
int i=0; i<numrows; ++i) {
338 int_type grow = (int_type) rowmap.GID64(i);
342 for(
int j=0; j<rowlen; ++j) {
343 int_type col = (int_type) colmap.GID64(col_indices[j]);
344 if (first_col <= col && last_col >= col) {
346 send_rows.push_back(grow);
353 for(
int j=0; j<rowlen; ++j) {
354 if (first_col <= Tcol_indices[j] && last_col >= Tcol_indices[j]) {
356 send_rows.push_back(grow);
362 rows_per_send_proc[nc] = num_send_rows;
366 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
368 const std::vector<int>& proc_col_ranges,
369 std::vector<int>& send_rows,
370 std::vector<int>& rows_per_send_proc)
373 Tpack_outgoing_rows<int>(mtx, proc_col_ranges, send_rows, rows_per_send_proc);
376 throw "EpetraExt::pack_outgoing_rows: Global indices not int";
381 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
383 const std::vector<long long>& proc_col_ranges,
384 std::vector<long long>& send_rows,
385 std::vector<int>& rows_per_send_proc)
388 Tpack_outgoing_rows<long long>(mtx, proc_col_ranges, send_rows, rows_per_send_proc);
391 throw "EpetraExt::pack_outgoing_rows: Global indices not long long";
396 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
400 if(emap.GlobalIndicesInt())
401 return std::make_pair(emap.MinMyGID(),emap.MaxMyGID());
403 throw "EpetraExt::get_col_range<int>: Unknown Global Indices for Epetra_Map";
407 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
411 if(emap.GlobalIndicesLongLong())
412 return std::make_pair(emap.MinMyGID64(),emap.MaxMyGID64());
414 throw "EpetraExt::get_col_range<long long>: Unknown Global Indices for Epetra_Map";
418 template<
typename int_type>
421 std::pair<int_type,int_type> col_range;
423 col_range = get_col_range<int_type>(mtx.
ColMap());
427 col_range.first = row_map.MaxMyGID64();
428 col_range.second = row_map.MinMyGID64();
430 int_type* col_indices = NULL;
434 for(
int j=0; j<rowlen; ++j) {
435 if (col_indices[j] < col_range.first) col_range.first = col_indices[j];
436 if (col_indices[j] > col_range.second) col_range.second = col_indices[j];
444 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
448 if(mtx.RowMatrixRowMap().GlobalIndicesInt())
449 return Tget_col_range<int>(mtx);
451 throw "EpetraExt::get_col_range<int>: Unknown Global Indices for Epetra_CrsMatrix";
455 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
459 if(mtx.RowMatrixRowMap().GlobalIndicesLongLong())
460 return Tget_col_range<long long>(mtx);
462 throw "EpetraExt::get_col_range<long long>: Unknown Global Indices for Epetra_CrsMatrix";
471 template <
typename MyType>
472 void boundary_exchange(
const Epetra_MpiComm Comm, MPI_Datatype DataType,
473 int NumSends,
const int * SendProcs,
const int * SendSizes, MyType* SendBuffer,
474 int NumRecvs,
const int * RecvProcs,
const int * RecvSizes, MyType* RecvBuffer,
int SizeOfPacket,
int msg_tag)
477 MPI_Comm comm = Comm.
Comm();
478 std::vector<MPI_Request> requests(NumRecvs);
479 std::vector<MPI_Status> status(NumRecvs);
481 int i,num_waits=0,MyPID=Comm.
MyPID();
482 int start, self_recv_len=-1,self_recv_start=-1, self_send_start=-1;
485 int mysendsize=1, myrecvsize=1;
489 for(i=0; i<NumRecvs; i++){
490 if(RecvSizes) myrecvsize=RecvSizes[i]*SizeOfPacket;
491 if(RecvProcs[i] != MyPID) {
492 MPI_Irecv(RecvBuffer + start, myrecvsize, DataType, RecvProcs[i], msg_tag, comm, &requests[num_waits]);
496 self_recv_len = myrecvsize;
497 self_recv_start=start;
504 for(i=0; i<NumSends; i++){
505 if(SendSizes) mysendsize=SendSizes[i]*SizeOfPacket;
506 if(SendProcs[i] != MyPID)
507 MPI_Send(SendBuffer + start, mysendsize,DataType,SendProcs[i],msg_tag,comm);
509 self_send_start=start;
514 if(self_recv_len != -1)
515 memcpy(RecvBuffer+self_recv_start,SendBuffer+self_send_start,self_recv_len*
sizeof(MyType)*SizeOfPacket);
519 MPI_Waitall(num_waits, &requests[0],&status[0]);
525 template <
typename MyType>
526 void boundary_exchange_varsize(
const Epetra_MpiComm Comm, MPI_Datatype DataType,
527 int NumSends,
const int * SendProcs,
const int * SendSizes, MyType* SendBuffer,
528 int NumRecvs,
const int * RecvProcs,
int * RecvSizes, MyType*& RecvBuffer,
int SizeOfPacket,
int msg_tag)
534 boundary_exchange<int>(Comm,MPI_INT,NumSends,SendProcs,(
int*)0,const_cast<int*>(SendSizes),NumRecvs,RecvProcs,(
int*)0,RecvSizes,1,msg_tag);
537 for(i=0; i<NumRecvs; i++) rbuffersize+=RecvSizes[i]*SizeOfPacket;
538 RecvBuffer =
new MyType[rbuffersize];
541 boundary_exchange<MyType>(Comm,DataType,NumSends,SendProcs,SendSizes,SendBuffer,NumRecvs,RecvProcs,RecvSizes,RecvBuffer,SizeOfPacket,msg_tag+100);
552 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
555 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
563 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
566 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
576 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
577 void LightweightMap::Construct_int(
int ,
int numMyElements,
const int * myGlobalElements,
long long ,
bool GenerateHash)
584 for(
int i=0; i < numMyElements; ++i ) {
586 if(GenerateHash) Data_->
LIDHash_int_->Add(myGlobalElements[i], i);
593 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
594 void LightweightMap::Construct_LL(
long long ,
int numMyElements,
const long long * myGlobalElements,
long long ,
bool GenerateHash)
596 Data_=
new LightweightMapData();
601 for(
int i=0; i < numMyElements; ++i ) {
603 if(GenerateHash) Data_->
LIDHash_LL_->Add(myGlobalElements[i], i);
610 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
613 Construct_int(numGlobalElements, numMyElements, myGlobalElements, indexBase, GenerateHash);
617 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
620 Construct_LL(numGlobalElements, numMyElements, myGlobalElements, indexBase, GenerateHash);
625 Construct_LL(numGlobalElements, numMyElements, myGlobalElements, indexBase, GenerateHash);
642 Data_->IncrementReferenceCount();
643 IsLongLong = map.IsLongLong;
655 if((
this != &map) && (Data_ != map.Data_)) {
658 Data_->IncrementReferenceCount();
660 IsLongLong = map.IsLongLong;
666 void LightweightMap::CleanupData(){
668 Data_->DecrementReferenceCount();
669 if(Data_->ReferenceCount() == 0) {
675 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
680 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
689 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
694 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
699 throw "EpetraExt::LightweightMap::NumMyElements: Global indices unknowns";
703 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
709 throw "EpetraExt::LightweightMap::LID: Int version called for long long map";
711 throw "EpetraExt::LightweightMap::LID: unknown GID type";
714 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
721 throw "EpetraExt::LightweightMap::LID: Long long version called for int map";
723 throw "EpetraExt::LightweightMap::LID: unknown GID type";
728 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
737 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
744 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
751 throw "EpetraExt::LightweightMap::GID64: Global indices unknown.";
755 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
762 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
780 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
785 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
790 throw "EpetraExt::LightweightMap::MaxLID: Global indices unknowns";
804 TargetMap_=&RemoteOnlyTargetMap;
810 Distor_ = &Importer.Distributor();
817 throw std::runtime_error(
"RemoteOnlyImport: Importer doesn't match RemoteOnlyTargetMap for number of remotes.");
820 ExportLIDs_ =
new int[NumExportIDs_];
821 ExportPIDs_ =
new int[NumExportIDs_];
822 for(i=0; i<NumExportIDs_; i++) {
823 ExportLIDs_[i] = OldExportLIDs[i];
824 ExportPIDs_[i] = OldExportPIDs[i];
830 RemoteLIDs_ =
new int[NumRemoteIDs_];
832 for(i=0; i<NumRemoteIDs_; i++)
833 RemoteLIDs_[i] = TargetMap_->
LID( (
int) Importer.
TargetMap().GID64(OldRemoteLIDs[i]));
836 for(i=0; i<NumRemoteIDs_; i++)
837 RemoteLIDs_[i] = TargetMap_->
LID(Importer.
TargetMap().GID64(OldRemoteLIDs[i]));
840 throw std::runtime_error(
"RemoteOnlyImport: TargetMap_ index type unknown.");
843 for(i=0; i<NumRemoteIDs_-1; i++)
844 if(RemoteLIDs_[i] > RemoteLIDs_[i+1])
845 throw std::runtime_error(
"RemoteOnlyImport: Importer and RemoteOnlyTargetMap order don't match.");
851 delete [] ExportLIDs_;
852 delete [] ExportPIDs_;
853 delete [] RemoteLIDs_;
863 std::vector<int>& RemotePermuteIDs, std::vector<int>& RemoteOwningPIDs,
bool SortGhostsAssociatedWithEachProcessor_);
867 std::vector<int>& RemotePermuteIDs, std::vector<int>& RemoteOwningPIDs,
bool SortGhostsAssociatedWithEachProcessor_)
872 if(NumRemoteColGIDs > 0) {
873 SortLists[0] = RemoteColindices;
874 SortLists[1] = &RemotePermuteIDs[0];
875 Epetra_Util::Sort(
true, NumRemoteColGIDs, &RemoteOwningPIDs[0], 0, 0, NLists, SortLists);
880 if (SortGhostsAssociatedWithEachProcessor_) {
886 int StartCurrent, StartNext;
887 StartCurrent = 0; StartNext = 1;
888 while ( StartNext < NumRemoteColGIDs ) {
889 if (RemoteOwningPIDs[StartNext]==RemoteOwningPIDs[StartNext-1]) StartNext++;
891 SortLists[0] = &RemotePermuteIDs[StartCurrent];
892 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(RemoteColindices[StartCurrent]),0,0,NLists,SortLists);
893 StartCurrent = StartNext; StartNext++;
896 SortLists[0] = &RemotePermuteIDs[StartCurrent];
897 Epetra_Util::Sort(
true, StartNext-StartCurrent, &(RemoteColindices[StartCurrent]), 0, 0, NLists, SortLists);
903 std::vector<int>& RemotePermuteIDs, std::vector<int>& RemoteOwningPIDs,
bool SortGhostsAssociatedWithEachProcessor_)
906 if(NumRemoteColGIDs > 0) {
907 long long* SortLists_LL[1] = {RemoteColindices};
908 int* SortLists_int[1] = {&RemotePermuteIDs[0]};
909 Epetra_Util::Sort(
true, NumRemoteColGIDs, &RemoteOwningPIDs[0], 0, 0, 1, SortLists_int, 1, SortLists_LL);
913 if (SortGhostsAssociatedWithEachProcessor_) {
919 int StartCurrent, StartNext;
920 StartCurrent = 0; StartNext = 1;
921 while ( StartNext < NumRemoteColGIDs ) {
922 if (RemoteOwningPIDs[StartNext]==RemoteOwningPIDs[StartNext-1]) StartNext++;
924 int* SortLists[1] = {&RemotePermuteIDs[StartCurrent]};
925 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(RemoteColindices[StartCurrent]),0,0,NLists,SortLists, 0, 0);
926 StartCurrent = StartNext; StartNext++;
929 int* SortLists[1] = {&RemotePermuteIDs[StartCurrent]};
930 Epetra_Util::Sort(
true, StartNext-StartCurrent, &(RemoteColindices[StartCurrent]), 0, 0, NLists, SortLists, 0, 0);
935 int LightweightCrsMatrix::MakeColMapAndReindex(std::vector<int> owningPIDs, std::vector<GO> Gcolind,
bool SortGhosts,
const char * label)
937 #ifdef ENABLE_MMM_TIMINGS
939 if(label) tpref = std::string(label);
940 using Teuchos::TimeMonitor;
941 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS-3.1"))));
950 std::vector<bool> LocalGIDs(numDomainElements,
false);
953 if(DoSizes) EPETRA_CHK_ERR(-1);
962 int hashsize = numMyBlockRows;
if (hashsize < 100) hashsize = 100;
964 std::vector<GO> RemoteGIDList; RemoteGIDList.reserve(hashsize);
965 std::vector<int> RemoteOwningPIDs; RemoteOwningPIDs.reserve(hashsize);
970 int NumLocalColGIDs = 0;
971 int NumRemoteColGIDs = 0;
972 for(
int i = 0; i < numMyBlockRows; i++) {
978 bool alreadyFound = LocalGIDs[LID];
980 LocalGIDs[LID] =
true;
986 GO hash_value=RemoteGIDs.Get(GID);
987 if(hash_value == -1) {
988 int PID = owningPIDs[j];
990 colind_[j] = numDomainElements + NumRemoteColGIDs;
991 RemoteGIDs.Add(GID, NumRemoteColGIDs);
992 RemoteGIDList.push_back(GID);
993 RemoteOwningPIDs.push_back(PID);
997 colind_[j] = numDomainElements + hash_value;
1004 if (NumRemoteColGIDs!=0) {
1005 throw "Some column IDs are not in domainMap. If matrix is rectangular, you must pass in domainMap to FillComplete";
1008 if (NumLocalColGIDs==numDomainElements) {
1019 int numMyBlockCols = NumLocalColGIDs + NumRemoteColGIDs;
1021 if(numMyBlockCols > 0)
1022 Colindices.Size(numMyBlockCols);
1023 GO* RemoteColindices = Colindices.Values() + NumLocalColGIDs;
1025 for(
int i = 0; i < NumRemoteColGIDs; i++)
1026 RemoteColindices[i] = RemoteGIDList[i];
1029 std::vector<int> RemotePermuteIDs(NumRemoteColGIDs);
1030 for(
int i=0; i<NumRemoteColGIDs; i++) RemotePermuteIDs[i]=i;
1032 MakeColMapAndReindexSort<GO>(NumRemoteColGIDs, RemoteColindices, RemotePermuteIDs, RemoteOwningPIDs,SortGhosts);
1035 std::vector<int> ReverseRemotePermuteIDs(NumRemoteColGIDs);
1036 for(
int i=0; i<NumRemoteColGIDs; i++) ReverseRemotePermuteIDs[RemotePermuteIDs[i]]=i;
1039 bool use_local_permute=
false;
1040 std::vector<int> LocalPermuteIDs(numDomainElements);
1052 GO* MyGlobalElements = 0;
1053 DomainMap_.MyGlobalElementsPtr(MyGlobalElements);
1054 int NumLocalAgain = 0;
1055 use_local_permute =
true;
1056 for(
int i = 0; i < numDomainElements; i++) {
1058 LocalPermuteIDs[i] = NumLocalAgain;
1059 Colindices[NumLocalAgain++] = MyGlobalElements[i];
1062 assert(NumLocalAgain==NumLocalColGIDs);
1069 for(
int i=0;i<NumRemoteColGIDs;i++)
1072 #ifdef ENABLE_MMM_TIMINGS
1073 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS-3.2"))));
1077 LightweightMap temp((GO) -1, numMyBlockCols, Colindices.Values(), (GO)
DomainMap_.IndexBase64());
1081 #ifdef ENABLE_MMM_TIMINGS
1082 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS-3.3"))));
1086 for(
int i=0; i<numMyBlockRows; i++){
1087 for(
int j=rowptr_[i]; j<rowptr_[i+1]; j++){
1089 if(ID < numDomainElements){
1095 colind_[j] = NumLocalColGIDs + ReverseRemotePermuteIDs[
colind_[j]-numDomainElements];
1109 static inline bool lessthan12(std::pair<int,int> i, std::pair<int,int> j){
1110 return ((i.first<j.first) || (i.first==j.first && i.second <j.second));
1115 template<
typename ImportType,
typename int_type>
1116 int LightweightCrsMatrix::PackAndPrepareReverseComm(
const Epetra_CrsMatrix & SourceMatrix, ImportType & RowImporter,
1117 std::vector<int> &ReverseSendSizes, std::vector<int_type> &ReverseSendBuffer) {
1122 if(MyImporter == 0)
return -1;
1124 int MyPID = MpiComm->
MyPID();
1127 int NumExportIDs = RowImporter.NumExportIDs();
1128 int* ExportLIDs = RowImporter.ExportLIDs();
1129 int* ExportPIDs = RowImporter.ExportPIDs();
1136 const int * ProcsFrom = MDistor->
ProcsFrom();
1142 std::vector<int> RemotePIDOrder(SourceMatrix.
NumMyCols(),-1);
1145 for(i=0,j=0;i<NumRecvs;i++){
1146 for(k=0;k<LengthsFrom[i];k++){
1147 int pid=ProcsFrom[i];
1148 if(pid!=MyPID) RemotePIDOrder[RemoteLIDs[j]]=i;
1154 std::vector<std::set<std::pair<int,int_type> > > ReversePGIDs(NumRecvs);
1155 int *rowptr, *colind;
1161 for(i=0; i < NumExportIDs; i++) {
1162 int lid = ExportLIDs[i];
1163 int exp_pid = ExportPIDs[i];
1164 for(j=rowptr[lid]; j<rowptr[lid+1]; j++){
1165 int pid_order = RemotePIDOrder[colind[j]];
1167 int_type gid = (int_type) SourceMatrix.GCID64(colind[j]);
1169 ReversePGIDs[pid_order].insert(std::pair<int,int_type>(exp_pid,gid));
1175 ReverseSendSizes.resize(NumRecvs+1);
1177 for(i=0; i<NumRecvs; i++) {
1178 ReverseSendSizes[i] = 2*ReversePGIDs[i].size();
1179 totalsize += ReverseSendSizes[i];
1183 ReverseSendBuffer.resize(totalsize+1);
1184 for(i=0, j=0; i<NumRecvs; i++) {
1185 for(
typename std::set<std::pair<int,int_type> >::iterator it=ReversePGIDs[i].begin(); it!=ReversePGIDs[i].end(); it++) {
1186 ReverseSendBuffer[j] = it->first;
1187 ReverseSendBuffer[j+1] = it->second;
1198 template<
typename int_type>
1204 int * companion = &ExportGID3[0];
1211 long long * companion = &ExportGID3[0];
1215 template<
typename int_type>
1216 int build_type3_exports(
int MyPID,
int Nrecv,
Epetra_BlockMap &DomainMap, std::vector<int> &ReverseRecvSizes,
const int_type *ReverseRecvBuffer, std::vector<int> &ExportLID3, std::vector<int> &ExportPID3){
1220 int total_length3=0;
1221 for(i=0; i<Nrecv; i++)
1222 total_length3+=ReverseRecvSizes[i]/2;
1223 if(total_length3==0)
return 0;
1225 std::vector<int_type> ExportGID3(total_length3);
1226 ExportLID3.resize(total_length3);
1227 ExportPID3.resize(total_length3);
1230 for(i=0,j=0; i<2*total_length3; i+=2) {
1231 if(ReverseRecvBuffer[i] != MyPID){
1232 ExportPID3[j]=ReverseRecvBuffer[i];
1233 ExportGID3[j]=ReverseRecvBuffer[i+1];
1239 if(total_length3==0)
return 0;
1242 build_type3_exports_sort<int_type>(ExportGID3, ExportPID3, total_length3);
1243 int StartCurrent, StartNext;
1244 StartCurrent = 0; StartNext = 1;
1245 while ( StartNext < total_length3 ) {
1246 if(ExportPID3[StartNext] == ExportPID3[StartNext-1]) StartNext++;
1248 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(ExportGID3[StartCurrent]),0,0,0,0, 0, 0);
1249 StartCurrent = StartNext; StartNext++;
1252 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(ExportGID3[StartCurrent]),0,0,0,0, 0, 0);
1263 for(i=1,j=1; i<total_length3; i++){
1264 if(ExportPID3[i]!=ExportPID3[i-1] || ExportGID3[i]!=ExportGID3[i-1]){
1265 ExportPID3[j] = ExportPID3[i];
1266 ExportGID3[j] = ExportGID3[i];
1270 ExportPID3.resize(j);
1271 ExportLID3.resize(j);
1283 for(i=0; i<total_length3; i++) {
1284 ExportLID3[i]=DomainMap.
LID(ExportGID3[i]);
1285 if(ExportLID3[i] < 0)
throw std::runtime_error(
"LightweightCrsMatrix:MakeExportLists invalid LID");
1294 return total_length3;
1298 template<
typename ImportType,
typename int_type>
1300 int total_length2=0;
1305 int *rowptr, *colind;
1311 const int* ExportLIDs = MyImporter.ExportLIDs();
1312 const int* ExportPIDs = MyImporter.ExportPIDs();
1313 if(NumExportIDs==0)
return 0;
1320 std::vector<bool> IsOwned(SourceMatrix.
NumMyCols(),
true);
1321 if(SourceImporter) {
1322 const int * RemoteLIDs = SourceImporter->
RemoteLIDs();
1325 IsOwned[RemoteLIDs[i]]=
false;
1329 std::vector<int> SentTo(SourceMatrix.
NumMyCols(),-1);
1333 std::vector<int_type> ExportGID2(total_length2);
1335 ExportLID2.resize(total_length2);
1336 ExportPID2.resize(total_length2);
1338 int current=0, last_start=0, last_pid=ExportPIDs[0];
1339 for(i=0; i<NumExportIDs; i++){
1341 int row=ExportLIDs[i];
1342 int pid=ExportPIDs[i];
1344 if(i!=0 && pid>last_pid) {
1346 if(current!=last_start){
1347 int *lids = &ExportLID2[last_start];
1348 Epetra_Util::Sort(
true,current-last_start,&ExportGID2[last_start],0,0,1,&lids,0,0);
1355 else if(pid < last_pid) {
1356 throw std::runtime_error(
"build_type2_exports: ExportPIDs are not sorted!");
1359 for(j=rowptr[row]; j<rowptr[row+1]; j++) {
1362 if(IsOwned[col] && SentTo[col]!=pid){
1364 if(current>= total_length2)
throw std::runtime_error(
"build_type2_exports: More export ids than I thought!");
1366 ExportGID2[current] = (int_type) SourceMatrix.GCID64(col);
1367 ExportLID2[current] = SourceMatrix.
DomainMap().
LID(ExportGID2[current]);
1368 ExportPID2[current] = pid;
1375 int *lids = ExportLID2.size() > (std::size_t) last_start ? &ExportLID2[last_start] : 0;
1376 Epetra_Util::Sort(
true,current-last_start,ExportGID2.size() > (std::size_t) last_start ? &ExportGID2[last_start] : 0,0,0,1,&lids,0,0);
1379 total_length2=current;
1380 ExportLID2.resize(total_length2);
1381 ExportPID2.resize(total_length2);
1383 return total_length2;
1387 template<
typename int_type>
1388 void build_type1_exports_sort(std::vector<int> &ExportLID1, std::vector<int> &ExportPID1, std::vector<int_type>& ExportGID1,
int total_length1);
1392 int * companion[2] = {&ExportLID1[0],&ExportGID1[0]};
1398 int * companion = &ExportLID1[0];
1399 long long * companion64 = &ExportGID1[0];
1400 Epetra_Util::Sort(
true,total_length1,&ExportPID1[0],0,0,1,&companion,1,&companion64);
1403 template<
typename int_type>
1405 int i, total_length1=0;
1406 if(!Importer1)
return 0;
1407 total_length1 = Importer1->
NumSend();
1408 if(total_length1==0)
return 0;
1410 std::vector<int_type> ExportGID1(total_length1);
1411 ExportLID1.resize(total_length1);
1412 ExportPID1.resize(total_length1);
1413 const int * ExportLID1Base = Importer1->
ExportLIDs();
1414 const int * ExportPID1Base = Importer1->
ExportPIDs();
1416 for(i=0; i<total_length1; i++){
1417 ExportLID1[i] = ExportLID1Base[i];
1418 ExportPID1[i] = ExportPID1Base[i];
1419 ExportGID1[i] = (int_type) Importer1->
SourceMap().GID64(ExportLID1Base[i]);
1423 build_type1_exports_sort<int_type>(ExportLID1, ExportPID1, ExportGID1, total_length1);
1425 int StartCurrent, StartNext;
1426 StartCurrent = 0; StartNext = 1;
1427 while ( StartNext < total_length1 ) {
1428 if(ExportPID1[StartNext] == ExportPID1[StartNext-1]) StartNext++;
1430 int *new_companion = {&ExportLID1[StartCurrent]};
1431 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(ExportGID1[StartCurrent]),0,0,1,&new_companion, 0, 0);
1432 StartCurrent = StartNext; StartNext++;
1435 int *new_companion = {&ExportLID1[StartCurrent]};
1436 Epetra_Util::Sort(
true,StartNext-StartCurrent, &(ExportGID1[StartCurrent]),0,0,1,&new_companion, 0, 0);
1437 return total_length1;
1441 template<
typename ImportType,
typename int_type>
1442 int LightweightCrsMatrix::MakeExportLists(
const Epetra_CrsMatrix & SourceMatrix, ImportType & Importer2,
1443 std::vector<int> &ReverseRecvSizes,
const int_type *ReverseRecvBuffer,
1444 std::vector<int> & ExportPIDs, std::vector<int> & ExportLIDs) {
1446 int MyPID = SourceMatrix.
Comm().
MyPID();
1459 Epetra_MpiDistributor * Distor1 = (Importer1)?(dynamic_cast<Epetra_MpiDistributor*>(&Importer1->Distributor())):0;
1461 int Nsend1 = (Distor1)?(Distor1->
NumSends()):0;
1463 std::vector<int> ExportPID3;
1464 std::vector<int> ExportLID3;
1466 std::vector<int> ExportPID2;
1467 std::vector<int> ExportLID2;
1469 std::vector<int> ExportPID1;
1470 std::vector<int> ExportLID1;
1473 int Len1=build_type1_exports<int_type>(Importer1, ExportLID1, ExportPID1);
1474 int Len2=build_type2_exports<ImportType, int_type>(SourceMatrix, Importer2, ExportLID2, ExportPID2);
1478 #ifdef HAVE_EPETRAEXT_DEBUG
1482 bool test_passed=
true;
1483 for(i=1; i<Len1; i++) {
1484 if(ExportPID1[i] < ExportPID1[i-1] || (ExportPID1[i] == ExportPID1[i-1] &&
DomainMap_.
GID(ExportLID1[i]) <
DomainMap_.
GID(ExportLID1[i-1])))
1487 SourceMatrix.Comm().Barrier();
1489 printf(
"[%d] Type1 ERRORS = ",SourceMatrix.Comm().MyPID());
1490 for(
int i=0; i<Len1; i++)
1491 printf(
"(%2d,%2d,%2d) ",ExportLID1[i],
DomainMap_.
GID(ExportLID1[i]),ExportPID1[i]);
1494 throw std::runtime_error(
"Importer1 fails the sanity test");
1497 for(i=1; i<Len2; i++) {
1498 if(ExportPID2[i] < ExportPID2[i-1] || (ExportPID2[i] == ExportPID2[i-1] &&
DomainMap_.
GID(ExportLID2[i]) <
DomainMap_.
GID(ExportLID2[i-1])))
1502 SourceMatrix.Comm().Barrier();
1504 printf(
"[%d] Type2 ERRORS = ",SourceMatrix.Comm().MyPID());
1505 for(
int i=0; i<Len2; i++)
1506 printf(
"(%2d,%2d,%2d) ",ExportLID2[i],
DomainMap_.
GID(ExportLID2[i]),ExportPID2[i]);
1509 throw std::runtime_error(
"Importer2 fails the sanity test");
1512 for(i=1; i<Len3; i++) {
1513 if(ExportPID3[i] < ExportPID3[i-1] || (ExportPID3[i] == ExportPID3[i-1] &&
DomainMap_.
GID(ExportLID3[i]) <
DomainMap_.
GID(ExportLID3[i-1])))
1517 SourceMatrix.Comm().Barrier();
1519 printf(
"[%d] Type3 ERRORS = ",SourceMatrix.Comm().MyPID());
1520 for(
int i=0; i<Len3; i++)
1521 printf(
"(%2d,%2d,%2d) ",ExportLID3[i],
DomainMap_.
GID(ExportLID3[i]),ExportPID3[i]);
1524 throw std::runtime_error(
"Importer3 fails the sanity test");
1531 if(Importer1 && !Importer1->SourceMap().SameAs(
DomainMap_))
1532 throw std::runtime_error(
"ERROR: Map Mismatch Importer1");
1534 if(!Importer2.SourceMap().SameAs(SourceMatrix.RowMap()))
1535 throw std::runtime_error(
"ERROR: Map Mismatch Importer2");
1537 int_type InfGID = std::numeric_limits<int_type>::max();
1538 int InfPID = INT_MAX;
1540 int i1=0, i2=0, i3=0, current=0;
1542 int MyLen=Len1+Len2+Len3;
1543 ExportLIDs.resize(MyLen);
1544 ExportPIDs.resize(MyLen);
1546 while(i1 < Len1 || i2 < Len2 || i3 < Len3){
1547 int PID1 = (i1<Len1)?(ExportPID1[i1]):InfPID;
1548 int PID2 = (i2<Len2)?(ExportPID2[i2]):InfPID;
1549 int PID3 = (i3<Len3)?(ExportPID3[i3]):InfPID;
1551 int_type GID1 = (i1<Len1)?((int_type)
DomainMap_.GID64(ExportLID1[i1])):InfGID;
1552 int_type GID2 = (i2<Len2)?((int_type)
DomainMap_.GID64(ExportLID2[i2])):InfGID;
1553 int_type GID3 = (i3<Len3)?((int_type)
DomainMap_.GID64(ExportLID3[i3])):InfGID;
1555 int MIN_PID =
MIN3(PID1,PID2,PID3);
1556 int_type MIN_GID =
MIN3( ((PID1==MIN_PID)?GID1:InfGID), ((PID2==MIN_PID)?GID2:InfGID), ((PID3==MIN_PID)?GID3:InfGID));
1557 bool added_entry=
false;
1560 if(PID1 == MIN_PID && GID1 == MIN_GID){
1561 ExportLIDs[current] = ExportLID1[i1];
1562 ExportPIDs[current] = ExportPID1[i1];
1569 if(PID2 == MIN_PID && GID2 == MIN_GID){
1571 ExportLIDs[current] = ExportLID2[i2];
1572 ExportPIDs[current] = ExportPID2[i2];
1580 if(PID3 == MIN_PID && GID3 == MIN_GID){
1582 ExportLIDs[current] = ExportLID3[i3];
1583 ExportPIDs[current] = ExportPID3[i3];
1589 if(current!=MyLen) {
1590 ExportLIDs.resize(current);
1591 ExportPIDs.resize(current);
1598 template<
typename ImportType,
typename int_type>
1599 void LightweightCrsMatrix::Construct(
const Epetra_CrsMatrix & SourceMatrix, ImportType & RowImporter,
bool SortGhosts,
const char * label)
1603 #ifdef ENABLE_MMM_TIMINGS
1605 if(label) tpref = std::string(label);
1606 using Teuchos::TimeMonitor;
1607 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1"))));
1618 int MyPID = SourceMatrix.
Comm().
MyPID();
1621 std::vector<int> ReverseSendSizes;
1622 std::vector<int_type> ReverseSendBuffer;
1623 std::vector<int> ReverseRecvSizes;
1624 int_type * ReverseRecvBuffer=0;
1627 bool communication_needed = RowImporter.SourceMap().DistributedGlobal();
1636 if (!SourceMatrix.
RowMap().
SameAs(RowImporter.SourceMap()))
1637 throw "LightweightCrsMatrix: Fused copy constructor requires Importer.SourceMap() to match SourceMatrix.RowMap()";
1640 int NumSameIDs = RowImporter.NumSameIDs();
1641 int NumPermuteIDs = RowImporter.NumPermuteIDs();
1642 int NumRemoteIDs = RowImporter.NumRemoteIDs();
1643 int NumExportIDs = RowImporter.NumExportIDs();
1644 int* ExportLIDs = RowImporter.ExportLIDs();
1645 int* RemoteLIDs = RowImporter.RemoteLIDs();
1646 int* PermuteToLIDs = RowImporter.PermuteToLIDs();
1647 int* PermuteFromLIDs = RowImporter.PermuteFromLIDs();
1656 rowptr_.resize(N+1);
1660 std::vector<int> SourcePids;
1661 std::vector<int> TargetPids;
1670 if(rv)
throw "LightweightCrsMatrix: Fused copy constructor failed in CheckSizes()";
1676 int LenExports_ = 0;
1680 bool VarSizes =
false;
1681 if( NumExportIDs > 0) {
1682 Sizes_ =
new int[NumExportIDs];
1694 #ifdef ENABLE_MMM_TIMINGS
1695 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1.1 Forward Pack"))));
1700 NumExportIDs,ExportLIDs,
1701 LenExports_,Exports_,SizeOfPacket,
1702 Sizes_,VarSizes,SourcePids);
1703 if(rv)
throw "LightweightCrsMatrix: Fused copy constructor failed in PackAndPrepare()";
1706 #ifdef ENABLE_MMM_TIMINGS
1707 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1.2 Reverse"))));
1710 if (communication_needed) {
1713 const int * ExportPIDs = RowImporter.ExportPIDs();
1717 std::vector<int> SendSizes(MDistor->
NumSends()+1,0);
1718 for(
int i=0, curr_pid=0; i<NumExportIDs; i++) {
1719 if(i>0 && ExportPIDs[i] > ExportPIDs[i-1]) curr_pid++;
1720 SendSizes[curr_pid] +=Sizes_[i];
1723 if(i>0 && ExportPIDs[i] < ExportPIDs[i-1])
throw "ExportPIDs not sorted";
1726 #ifdef ENABLE_MMM_TIMINGS
1727 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1.2 Forward Send"))));
1730 std::vector<int> RecvSizes(MDistor->
NumReceives()+1);
1732 boundary_exchange_varsize<char>(*MpiComm,MPI_CHAR,MDistor->
NumSends(),MDistor->
ProcsTo(),SendSizes.size() ? &SendSizes[0] : 0,Exports_,
1733 MDistor->
NumReceives(),MDistor->
ProcsFrom(),RecvSizes.size() ? &RecvSizes[0] : 0,Imports_,SizeOfPacket,msg_tag);
1741 #ifdef ENABLE_MMM_TIMINGS
1742 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1.3 Reverse Pack"))));
1747 PackAndPrepareReverseComm<ImportType, int_type>(SourceMatrix,RowImporter,ReverseSendSizes,ReverseSendBuffer);
1749 #ifdef ENABLE_MMM_TIMINGS
1750 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-1.4 Reverse Send"))));
1755 ReverseRecvSizes.resize(MyDistor->
NumSends()+1);
1756 const int msg_tag2 = MpiComm->GetMpiTag ();
1757 MPI_Datatype data_type =
sizeof(int_type) == 4 ? MPI_INT : MPI_LONG_LONG;
1758 boundary_exchange_varsize<int_type> (*MpiComm, data_type, MyDistor->
NumReceives (),
1760 ReverseSendSizes.size() ? &ReverseSendSizes[0] : 0,
1761 ReverseSendBuffer.size() ? &ReverseSendBuffer[0] : 0,
1763 ReverseRecvSizes.size() ? &ReverseRecvSizes[0] : 0,
1764 ReverseRecvBuffer, 1, msg_tag2);
1769 if(rv)
throw "LightweightCrsMatrix: Fused copy constructor failed in Distor.Do";
1774 #ifdef ENABLE_MMM_TIMINGS
1775 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-2"))));
1783 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1784 if(
sizeof(int_type) ==
sizeof(
long long))
1787 vals_.resize(mynnz);
1792 SourcePids.assign(SourceMatrix.ColMap().NumMyElements(),-1);
1796 int * myrowptr = rowptr_.size() ? & rowptr_[0] : 0;
1797 double * myvals =
vals_.size() ? &
vals_[0] : 0;
1798 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1799 if(
sizeof(int_type) ==
sizeof(
int)) {
1801 Epetra_Import_Util::UnpackAndCombineIntoCrsArrays(SourceMatrix,NumSameIDs,NumRemoteIDs,RemoteLIDs,NumPermuteIDs,PermuteToLIDs,PermuteFromLIDs,LenImports_,Imports_,N,mynnz,MyPID,myrowptr,mycolind,myvals,SourcePids,TargetPids);
1805 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1806 if(
sizeof(int_type) ==
sizeof(
long long)) {
1808 Epetra_Import_Util::UnpackAndCombineIntoCrsArrays(SourceMatrix,NumSameIDs,NumRemoteIDs,RemoteLIDs,NumPermuteIDs,PermuteToLIDs,PermuteFromLIDs,LenImports_,Imports_,N,mynnz,MyPID,myrowptr,mycolind,myvals,SourcePids,TargetPids);
1812 throw "EpetraExt::LightweightCrsMatrix::Construct: sizeof(int_type) error.";
1817 #ifdef ENABLE_MMM_TIMINGS
1818 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-3"))));
1822 MakeColMapAndReindex<int_type>(TargetPids,getcolind<int_type>(),SortGhosts);
1828 MakeExportLists<ImportType, int_type>(SourceMatrix,RowImporter,ReverseRecvSizes,ReverseRecvBuffer,
ExportPIDs_,
ExportLIDs_);
1835 #ifdef ENABLE_MMM_TIMINGS
1836 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-4"))));
1843 #ifdef ENABLE_MMM_TIMINGS
1844 MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS C-5"))));
1848 delete [] ReverseRecvBuffer;
1865 DomainMap_(SourceMatrix.DomainMap())
1867 #ifdef ENABLE_MMM_TIMINGS
1869 if(label) tpref = std::string(label);
1870 using Teuchos::TimeMonitor;
1871 Teuchos::RCP<Teuchos::TimeMonitor> MM = Teuchos::rcp(
new TimeMonitor(*TimeMonitor::getNewTimer(tpref + std::string(
"EpetraExt: LWCRS Total"))));
1876 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1878 Construct<RemoteOnlyImport, int>(SourceMatrix,RowImporter,SortGhosts,label);
1882 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1884 Construct<RemoteOnlyImport, long long>(SourceMatrix,RowImporter,SortGhosts,label);
1888 throw "EpetraExt::LightweightCrsMatrix: ERROR, GlobalIndices type unknown.";
1898 DomainMap_(SourceMatrix.DomainMap())
1901 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1903 Construct<Epetra_Import, int>(SourceMatrix,RowImporter);
1907 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
1909 Construct<Epetra_Import, long long>(SourceMatrix,RowImporter);
1913 throw "EpetraExt::LightweightCrsMatrix: ERROR, GlobalIndices type unknown.";
1926 template <
class TransferType>
1928 if(!Transfer)
return;
1931 const Epetra_Comm & Comm = Transfer->SourceMap().Comm();
1933 int rows_send = Transfer->NumExportIDs();
1934 int rows_recv = Transfer->NumRemoteIDs();
1936 int round1_send = Transfer->NumExportIDs() *
sizeof(int);
1937 int round1_recv = Transfer->NumRemoteIDs() *
sizeof(int);
1938 int num_send_neighbors = Distor.
NumSends();
1940 int round2_send, round2_recv;
1943 int myPID = Comm.
MyPID();
1944 int NumProcs = Comm.
NumProc();
1951 int lstats[8] = {num_send_neighbors,num_recv_neighbors,rows_send,rows_recv,round1_send,round1_recv,round2_send,round2_recv};
1952 int gstats_min[8], gstats_max[8];
1954 double lstats_avg[8], gstats_avg[8];
1955 for(
int i=0; i<8; i++)
1956 lstats_avg[i] = ((
double)lstats[i])/NumProcs;
1958 Comm.
MinAll(lstats,gstats_min,8);
1959 Comm.
MaxAll(lstats,gstats_max,8);
1960 Comm.
SumAll(lstats_avg,gstats_avg,8);
1963 printf(
"%s Send Statistics[min/avg/max]: neigh=%d/%4.1f/%d rows=%d/%4.1f/%d round1=%d/%4.1f/%d round2=%d/%4.1f/%d\n", label.c_str(),
1964 (int)gstats_min[0],gstats_avg[0],(
int)gstats_max[0], (int)gstats_min[2],gstats_avg[2],(
int)gstats_max[2],
1965 (int)gstats_min[4],gstats_avg[4],(
int)gstats_max[4], (int)gstats_min[6],gstats_avg[6],(
int)gstats_max[6]);
1966 printf(
"%s Recv Statistics[min/avg/max]: neigh=%d/%4.1f/%d rows=%d/%4.1f/%d round1=%d/%4.1f/%d round2=%d/%4.1f/%d\n", label.c_str(),
1967 (int)gstats_min[1],gstats_avg[1],(
int)gstats_max[1], (int)gstats_min[3],gstats_avg[3],(
int)gstats_max[3],
1968 (int)gstats_min[5],gstats_avg[5],(
int)gstats_max[5], (int)gstats_min[7],gstats_avg[7],(
int)gstats_max[7]);
1988 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
1992 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
const int * LengthsFrom() const
int SumIntoGlobalValues(int_type GlobalRow, int NumEntries, double *Values, int_type *Indices)
LightweightCrsMatrix * importMatrix
RemoteOnlyImport(const Epetra_Import &Importer, LightweightMap &RemoteOnlyTargetMap)
Epetra_HashTable< long long > * LIDHash_LL_
Epetra_BlockMap * RowMapEP_
std::vector< int > targetMapToOrigRow
long long * MyGlobalElements64() const
virtual ~CrsWrapper_GraphBuilder()
void debug_print_distor(const char *label, const Epetra_Distributor *Distor, const Epetra_Comm &Comm)
virtual int SumIntoGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
bool GlobalIndicesLongLong() const
std::pair< int_type, int_type > Tget_col_range(const Epetra_CrsMatrix &mtx)
void MyGlobalElementsPtr(int *&MyGlobalElementList) const
bool SameAs(const Epetra_BlockMap &Map) const
int MyGlobalElements(int *MyGlobalElementList) const
LightweightMap * RowMapLW_
void pack_outgoing_rows(const Epetra_CrsMatrix &mtx, const std::vector< int > &proc_col_ranges, std::vector< int > &send_rows, std::vector< int > &rows_per_send_proc)
int EPETRA_LIB_DLL_EXPORT UnpackWithOwningPIDsCount(const Epetra_CrsMatrix &SourceMatrix, int NumSameIDs, int NumRemoteIDs, const int *RemoteLIDs, int NumPermuteIDs, const int *PermuteToLIDs, const int *PermuteFromLIDs, int LenImports, char *Imports)
void debug_compare_import(const Epetra_Import *Import1, const Epetra_Import *Import2)
const Epetra_Map * rowMap
bool ConstantElementSize() const
const Epetra_Map & RowMatrixRowMap() const
long long GID64(int LID) const
std::vector< int > colind_
void printMultiplicationStatistics(Epetra_Import *Transfer, const std::string &label)
std::vector< int > ExportPIDs_
bool GlobalIndicesInt() const
int EPETRA_LIB_DLL_EXPORT PackAndPrepareWithOwningPIDs(const Epetra_CrsMatrix &SourceMatrix, int NumExportIDs, int *ExportLIDs, int &LenExports, char *&Exports, int &SizeOfPacket, int *Sizes, bool &VarSizes, std::vector< int > &SourcePids)
virtual int MinAll(double *PartialMins, double *GlobalMins, int Count) const =0
const Epetra_Map & ColMap() const
virtual void Barrier() const =0
const Epetra_CrsMatrix * origMatrix
void MakeColMapAndReindexSort(int &NumRemoteColGIDs, GO *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
virtual int MyPID() const =0
void build_type1_exports_sort(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< int_type > &ExportGID1, int total_length1)
static int SortCrsEntries(int NumRows, const int *CRS_rowptr, int *CRS_colind, double *CRS_vals)
void build_type1_exports_sort< int >(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< int > &ExportGID1, int total_length1)
virtual int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const =0
const Epetra_Map & RowMap() const
virtual int SumAll(double *PartialSums, double *GlobalSums, int Count) const =0
int NumMyElements() const
int EPETRA_LIB_DLL_EXPORT UnpackAndCombineIntoCrsArrays(const Epetra_CrsMatrix &SourceMatrix, int NumSameIDs, int NumRemoteIDs, const int *RemoteLIDs, int NumPermuteIDs, const int *PermuteToLIDs, const int *PermuteFromLIDs, int LenImports, char *Imports, int TargetNumRows, int TargetNumNonzeros, int MyTargetPID, int *CSR_rowptr, int *CSR_colind, double *CSR_values, const std::vector< int > &SourcePids, std::vector< int > &TargetPids)
int InsertGlobalValues(int GlobalRow, int NumEntries, double *Values, int *Indices)
std::pair< long long, long long > get_col_range< long long >(const Epetra_Map &emap)
std::vector< int > targetMapToImportRow
const Epetra_Import * Importer() const
const Epetra_BlockMap & TargetMap() const
int NumMyElements() const
int MaxNumEntries() const
LightweightMap & operator=(const LightweightMap &map)
void build_type3_exports_sort< int >(std::vector< int > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
void build_type1_exports_sort< long long >(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< long long > &ExportGID1, int total_length1)
virtual ~CrsWrapper_Epetra_CrsMatrix()
void build_type3_exports_sort(std::vector< int_type > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
const Epetra_BlockMap & SourceMap() const
int build_type2_exports(const Epetra_CrsMatrix &SourceMatrix, ImportType &MyImporter, std::vector< int > &ExportLID2, std::vector< int > &ExportPID2)
void TPrintMultiplicationStatistics(TransferType *Transfer, const std::string &label)
int SumIntoGlobalValues(int GlobalRow, int NumEntries, double *Values, int *Indices)
const Epetra_Map & RowMap() const
std::vector< double > vals_
CrsWrapper_Epetra_CrsMatrix(Epetra_CrsMatrix &epetracrsmatrix)
const Epetra_Comm & Comm() const
std::vector< int > MyGlobalElements_int_
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
const int * ProcsTo() const
const int * LengthsTo() const
int NumPermuteIDs() const
int * MyGlobalElements() const
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
void MakeColMapAndReindexSort< long long >(int &NumRemoteColGIDs, long long *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
int build_type3_exports(int MyPID, int Nrecv, Epetra_BlockMap &DomainMap, std::vector< int > &ReverseRecvSizes, const int_type *ReverseRecvBuffer, std::vector< int > &ExportLID3, std::vector< int > &ExportPID3)
const int * ProcsFrom() const
virtual int NumProc() const =0
void MakeColMapAndReindexSort< int >(int &NumRemoteColGIDs, int *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
const LightweightMap & TargetMap() const
void Tpack_outgoing_rows(const Epetra_CrsMatrix &mtx, const std::vector< int_type > &proc_col_ranges, std::vector< int_type > &send_rows, std::vector< int > &rows_per_send_proc)
CrsWrapper_GraphBuilder(const Epetra_Map &emap)
const Epetra_Map & DomainMap() const
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)
virtual ~CrsMatrixStruct()
bool GlobalIndicesInt() const
Epetra_HashTable< int > * LIDHash_int_
std::vector< long long > MyGlobalElements_LL_
int build_type1_exports(const Epetra_Import *Importer1, std::vector< int > &ExportLID1, std::vector< int > &ExportPID1)
LightweightCrsMatrix(const Epetra_CrsMatrix &A, RemoteOnlyImport &RowImporter, bool SortGhosts=false, const char *label=0)
std::map< int_type, std::set< int_type > * > & get_graph()
const Epetra_CrsGraph & Graph() const
void build_type3_exports_sort< long long >(std::vector< long long > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
std::vector< int > ColMapOwningPIDs_
std::vector< int > ExportLIDs_
std::vector< int > rowptr_
const Epetra_Map * colMap
const Epetra_BlockMap * importColMap
void insert_matrix_locations(CrsWrapper_GraphBuilder< int_type > &graphbuilder, Epetra_CrsMatrix &C)
int dumpCrsMatrixStruct(const CrsMatrixStruct &M)
int ExtractGlobalRowView(int GlobalRow, int &NumIndices, int *&Indices) const
const Epetra_Comm & Comm() const
int InsertGlobalValues(int_type GlobalRow, int NumEntries, double *Values, int_type *Indices)
std::vector< long long > colind_LL_
bool GlobalIndicesLongLong() const
std::pair< int, int > get_col_range< int >(const Epetra_Map &emap)
int ExtractCrsDataPointers(int *&IndexOffset, int *&Indices, double *&Values_in) const
static int GetPids(const Epetra_Import &Importer, std::vector< int > &pids, bool use_minus_one_for_local)
void GetLastDoStatistics(int &bytes_sent, int &bytes_recvd) const