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 
  218template<
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>;
 
 
  233template<
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) {
 
 
  245template<
typename int_type>
 
  251template<
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;
 
 
  272template<
typename int_type>
 
  276  return InsertGlobalValues(GlobalRow, NumEntries, Values, Indices);
 
 
  279template<
typename int_type>
 
  280std::map<int_type,std::set<int_type>*>&
 
  286template<
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;
 
 
  318template<
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 
  403    throw "EpetraExt::get_col_range<int>: Unknown Global Indices for Epetra_Map";
 
 
  407#ifndef EPETRA_NO_64BIT_GLOBAL_INDICES 
  412    return std::make_pair(emap.MinMyGID64(),emap.MaxMyGID64());
 
  414    throw "EpetraExt::get_col_range<long long>: Unknown Global Indices for Epetra_Map";
 
  418template<
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 
  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 
  460    return Tget_col_range<long long>(mtx);
 
  462    throw "EpetraExt::get_col_range<long long>: Unknown Global Indices for Epetra_CrsMatrix";
 
  471template <
typename MyType>
 
  472void 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]);
 
  525template <
typename MyType>
 
  526void 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 
  577void 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 
  594void 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;
 
 
  666void 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);
 
 
  935int 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++){
 
 1089      if(ID < numDomainElements){
 
 1095        colind_[j] =  NumLocalColGIDs + ReverseRemotePermuteIDs[
colind_[j]-numDomainElements];
 
 1109static 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));
 
 1115template<
typename ImportType, 
typename int_type>
 
 1116int 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;
 
 1198template<
typename int_type>
 
 1204  int * companion = &ExportGID3[0];
 
 
 1211  long long * companion = &ExportGID3[0];
 
 
 1215template<
typename int_type>
 
 1216int 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;
 
 
 1298template<
typename ImportType, 
typename int_type>
 
 1300  int total_length2=0;
 
 1305  int    *rowptr, *colind;
 
 1310  int NumExportIDs                      = MyImporter.NumExportIDs();
 
 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;
 
 
 1387template<
typename int_type>
 
 1388void 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);
 
 
 1403template<
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;
 
 
 1441template<
typename ImportType, 
typename int_type>
 
 1442int 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();
 
 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])))
 
 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])))
 
 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])))
 
 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");
 
 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);
 
 1598template<
typename ImportType, 
typename int_type>
 
 1599void 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();
 
 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,
 
 1762                                           MyDistor->NumSends (), MyDistor->ProcsTo (),
 
 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);
 
 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.";
 
 
 1926template <
class TransferType>
 
 1928  if(!Transfer) 
return;  
 
 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 
virtual ~CrsMatrixStruct()
 
const Epetra_CrsMatrix * origMatrix
 
const Epetra_Map * rowMap
 
std::vector< int > targetMapToImportRow
 
const Epetra_Map * colMap
 
LightweightCrsMatrix * importMatrix
 
const Epetra_BlockMap * importColMap
 
std::vector< int > targetMapToOrigRow
 
CrsWrapper_Epetra_CrsMatrix(Epetra_CrsMatrix &epetracrsmatrix)
 
const Epetra_Map & RowMap() const
 
int SumIntoGlobalValues(int GlobalRow, int NumEntries, double *Values, int *Indices)
 
virtual ~CrsWrapper_Epetra_CrsMatrix()
 
int InsertGlobalValues(int GlobalRow, int NumEntries, double *Values, int *Indices)
 
std::map< int_type, std::set< int_type > * > & get_graph()
 
virtual ~CrsWrapper_GraphBuilder()
 
int InsertGlobalValues(int_type GlobalRow, int NumEntries, double *Values, int_type *Indices)
 
int SumIntoGlobalValues(int_type GlobalRow, int NumEntries, double *Values, int_type *Indices)
 
CrsWrapper_GraphBuilder(const Epetra_Map &emap)
 
Epetra_BlockMap * RowMapEP_
 
std::vector< double > vals_
 
std::vector< int > ExportPIDs_
 
LightweightMap * RowMapLW_
 
std::vector< long long > colind_LL_
 
std::vector< int > ColMapOwningPIDs_
 
LightweightCrsMatrix(const Epetra_CrsMatrix &A, RemoteOnlyImport &RowImporter, bool SortGhosts=false, const char *label=0)
 
std::vector< int > colind_
 
std::vector< int > ExportLIDs_
 
std::vector< int > rowptr_
 
std::vector< long long > MyGlobalElements_LL_
 
Epetra_HashTable< int > * LIDHash_int_
 
Epetra_HashTable< long long > * LIDHash_LL_
 
std::vector< int > MyGlobalElements_int_
 
bool GlobalIndicesInt() const
 
LightweightMap & operator=(const LightweightMap &map)
 
long long GID64(int LID) const
 
long long * MyGlobalElements64() const
 
int * MyGlobalElements() const
 
bool GlobalIndicesLongLong() const
 
void MyGlobalElementsPtr(int *&MyGlobalElementList) const
 
int NumMyElements() const
 
const LightweightMap & TargetMap() const
 
RemoteOnlyImport(const Epetra_Import &Importer, LightweightMap &RemoteOnlyTargetMap)
 
int MyGlobalElements(int *MyGlobalElementList) const
 
bool SameAs(const Epetra_BlockMap &Map) const
 
bool GlobalIndicesInt() const
 
const Epetra_Comm & Comm() const
 
bool ConstantElementSize() const
 
int NumMyElements() const
 
bool GlobalIndicesLongLong() const
 
virtual int MaxAll(double *PartialMaxs, double *GlobalMaxs, int Count) const=0
 
virtual int NumProc() const=0
 
virtual int MinAll(double *PartialMins, double *GlobalMins, int Count) const=0
 
virtual int MyPID() const=0
 
virtual void Barrier() const=0
 
virtual int SumAll(double *PartialSums, double *GlobalSums, int Count) const=0
 
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
 
int ExtractGlobalRowView(int GlobalRow, int &NumIndices, int *&Indices) const
 
virtual int SumIntoGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
 
const Epetra_Map & RowMap() const
 
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
 
const Epetra_CrsGraph & Graph() const
 
const Epetra_Comm & Comm() const
 
int ExtractCrsDataPointers(int *&IndexOffset, int *&Indices, double *&Values_in) const
 
const Epetra_Map & ColMap() const
 
int MaxNumEntries() const
 
const Epetra_Map & DomainMap() const
 
const Epetra_Import * Importer() const
 
const Epetra_Map & RowMatrixRowMap() const
 
int NumPermuteIDs() const
 
const Epetra_BlockMap & SourceMap() const
 
const Epetra_BlockMap & TargetMap() const
 
const int * ProcsFrom() const
 
const int * ProcsTo() const
 
const int * LengthsTo() const
 
const int * LengthsFrom() const
 
void GetLastDoStatistics(int &bytes_sent, int &bytes_recvd) const
 
static int SortCrsEntries(int NumRows, const int *CRS_rowptr, int *CRS_colind, double *CRS_vals)
 
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)
 
static int GetPids(const Epetra_Import &Importer, std::vector< int > &pids, bool use_minus_one_for_local)
 
EpetraExt::BlockCrsMatrix: A class for constructing a distributed block matrix.
 
void insert_matrix_locations(CrsWrapper_GraphBuilder< int_type > &graphbuilder, Epetra_CrsMatrix &C)
 
void debug_compare_import(const Epetra_Import *Import1, const Epetra_Import *Import2)
 
void debug_print_distor(const char *label, const Epetra_Distributor *Distor, const Epetra_Comm &Comm)
 
void build_type1_exports_sort< int >(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< int > &ExportGID1, int total_length1)
 
std::pair< int_type, int_type > Tget_col_range(const Epetra_CrsMatrix &mtx)
 
int build_type1_exports(const Epetra_Import *Importer1, std::vector< int > &ExportLID1, std::vector< int > &ExportPID1)
 
std::pair< int, int > get_col_range< int >(const Epetra_Map &emap)
 
void build_type1_exports_sort< long long >(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< long long > &ExportGID1, int total_length1)
 
void build_type1_exports_sort(std::vector< int > &ExportLID1, std::vector< int > &ExportPID1, std::vector< int_type > &ExportGID1, int total_length1)
 
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)
 
void TPrintMultiplicationStatistics(TransferType *Transfer, const std::string &label)
 
int build_type2_exports(const Epetra_CrsMatrix &SourceMatrix, ImportType &MyImporter, std::vector< int > &ExportLID2, std::vector< int > &ExportPID2)
 
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)
 
void printMultiplicationStatistics(Epetra_Import *Transfer, const std::string &label)
 
void MakeColMapAndReindexSort< int >(int &NumRemoteColGIDs, int *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
 
void build_type3_exports_sort< long long >(std::vector< long long > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
 
void MakeColMapAndReindexSort(int &NumRemoteColGIDs, GO *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
 
std::pair< long long, long long > get_col_range< long long >(const Epetra_Map &emap)
 
void build_type3_exports_sort< int >(std::vector< int > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
 
void MakeColMapAndReindexSort< long long >(int &NumRemoteColGIDs, long long *&RemoteColindices, std::vector< int > &RemotePermuteIDs, std::vector< int > &RemoteOwningPIDs, bool SortGhostsAssociatedWithEachProcessor_)
 
int dumpCrsMatrixStruct(const CrsMatrixStruct &M)
 
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)
 
void build_type3_exports_sort(std::vector< int_type > &ExportGID3, std::vector< int > &ExportPID3, int total_length3)
 
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)
 
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 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)