EpetraExt_ZoltanMpiDistributor.cpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00005 //                 Copyright (2001) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "EpetraExt_ZoltanMpiDistributor.h"
00030 #include "EpetraExt_ZoltanMpiComm.h"
00031 
00032 
00033 //==============================================================================
00034 // constructor
00035 EpetraExt::ZoltanMpiDistributor::ZoltanMpiDistributor(const EpetraExt::ZoltanMpiComm &Comm)
00036  : Epetra_Object("EpetraExt::ZoltanMpiDistributor"),
00037    plan_(0),
00038    comm_(Comm.GetMpiComm()),  
00039    tag_(Comm.GetMpiTag()),
00040    epComm_(&Comm)
00041 {
00042 }
00043 
00044 //==============================================================================
00045 // constructor
00046 EpetraExt::ZoltanMpiDistributor::ZoltanMpiDistributor( const EpetraExt::ZoltanMpiDistributor &Distributor)
00047  : Epetra_Object("EpetraExt::ZoltanMpiDistributor"),
00048    plan_(0),
00049    comm_(Distributor.comm_),  
00050    tag_(Distributor.tag_),
00051    epComm_(Distributor.epComm_)
00052 {
00053   EPETRA_CHK_ERR(Zoltan_Comm_Create_Copy (&plan_, Distributor.plan_));
00054 }
00055 
00056 //==============================================================================
00057 // destructor
00058 EpetraExt::ZoltanMpiDistributor::~ZoltanMpiDistributor()
00059 {
00060   Zoltan_Comm_Destroy(&plan_);
00061 }
00062 
00063 //==============================================================================
00064 // CreateFromSends Method
00065 // - create communication plan given a known list of procs to send to
00066 int EpetraExt::ZoltanMpiDistributor::CreateFromSends (
00067  const int  &NumExportIDs,
00068  const int  *ExportPIDs,
00069  const bool &Deterministic,
00070  int        &NumRemoteIDs)
00071 {
00072   EPETRA_CHK_ERR (Zoltan_Comm_Create (&plan_, (int) NumExportIDs,
00073      (int*) ExportPIDs, comm_, tag_, &NumRemoteIDs));            
00074   return 0;
00075 }
00076 
00077 //==============================================================================
00078 // CreateFromRecvs Method
00079 // - create communication plan given a known list of procs to recv from
00080 int EpetraExt::ZoltanMpiDistributor::CreateFromRecvs (
00081  const int  &NumRemoteIDs,
00082  const int  *RemoteGIDs,
00083  const int  *RemotePIDs,
00084  const bool &Deterministic,
00085  int  &NumExportIDs,
00086  int *&ExportGIDs,
00087  int *&ExportPIDs)
00088 {
00089     int i, myproc, nprocs;
00090     MPI_Comm_rank (comm_, &myproc);
00091     MPI_Comm_size (comm_, &nprocs);
00092     
00093     ZoltanMpiDistributor tmpdist (*epComm_);
00094     
00095     int *proclist = 0, *imports = 0;
00096     if (NumRemoteIDs > 0)  {
00097        proclist = new int [NumRemoteIDs];
00098        imports  = new int [2 * NumRemoteIDs];
00099        for (i = 0; i < NumRemoteIDs; i++)  {
00100           proclist[i]     = RemotePIDs[i];
00101           imports [2*i]   = RemoteGIDs[i];
00102           imports [2*i+1] = myproc;
00103           }
00104        }
00105        
00106     EPETRA_CHK_ERR (Zoltan_Comm_Create (&tmpdist.plan_, (int) NumRemoteIDs,
00107      proclist, tmpdist.comm_, tmpdist.tag_, &NumExportIDs));
00108      
00109     int *exports = 0; 
00110     if (NumExportIDs > 0)  {
00111        exports    = new int [2 * NumExportIDs];
00112        ExportGIDs = new int [NumExportIDs];
00113        ExportPIDs = new int [NumExportIDs];
00114        }
00115     else  {
00116        ExportGIDs = 0;
00117        ExportPIDs = 0;
00118        }       
00119     
00120     EPETRA_CHK_ERR (Zoltan_Comm_Do (tmpdist.plan_, tmpdist.tag_,
00121      (char*) imports, 2*sizeof(int), (char*) exports));
00122      
00123     for (i = 0; i < NumExportIDs; i++)  {
00124        ExportGIDs[i] = exports[2*i];
00125        ExportPIDs[i] = exports[2*i+1];
00126        }
00127 
00128     EPETRA_CHK_ERR (Zoltan_Comm_Create (&plan_, (int) NumExportIDs,
00129      (int*) ExportPIDs, comm_, tag_, (int*) NumRemoteIDs));
00130      
00131     if (proclist)  delete [] proclist;
00132     if (imports)   delete [] imports;
00133     if (exports)   delete [] exports;       
00134     return 0; 
00135 }
00136 
00137 //==============================================================================
00138 // Do method
00139 int EpetraExt::ZoltanMpiDistributor::Do (
00140  char      *exports,
00141  int       size,
00142  int       &len_imports,
00143  char      *imports)
00144 {
00145     EPETRA_CHK_ERR (Zoltan_Comm_Do_Post (plan_,tag_,exports,size,imports));
00146     EPETRA_CHK_ERR (Zoltan_Comm_Do_Wait (plan_,tag_,exports,size,imports));
00147     return 0;
00148 }
00149 
00150 //==============================================================================
00151 // DoReverse method
00152 int EpetraExt::ZoltanMpiDistributor::DoReverse (
00153  char      *exports,
00154  int       size,
00155  int       &len_imports,
00156  char      *imports)
00157 {
00158     EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Post (plan_, tag_, exports,
00159      size, 0, imports));
00160     EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Wait (plan_, tag_, exports,
00161      size, 0, imports));
00162     return 0;
00163 }
00164     
00165 //==============================================================================
00166 // Do_Posts Method
00167 int EpetraExt::ZoltanMpiDistributor::DoPosts (
00168  char      *exports,
00169  int       size,
00170  int       &len_imports,
00171  char      *imports)
00172 {
00173     EPETRA_CHK_ERR (Zoltan_Comm_Do_Post (plan_, tag_, exports, size, imports));   
00174     return 0;               
00175 }
00176     
00177 //==============================================================================
00178 // Do_Waits Method
00179 int EpetraExt::ZoltanMpiDistributor::DoWaits ()
00180 {
00181     EPETRA_CHK_ERR (Zoltan_Comm_Do_Wait (plan_, tag_, 0, 0, imports));
00182     return 0;
00183 }
00184 
00185 //==============================================================================--------------------------------------------
00186 // DoReverse_Posts Method
00187 int EpetraExt::ZoltanMpiDistributor::DoReversePosts (
00188  char      *exports,
00189  int       size,
00190  int       &len_imports,
00191  char      *imports)
00192 {
00193     EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Post (plan_, tag_, exports, size, 0, imports));
00194     return 0;
00195 }
00196 
00197 //==============================================================================
00198 // DoReverse_Waits Method
00199 int EpetraExt::ZoltanMpiDistributor::DoReverseWaits ()
00200 {
00201     EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Wait (plan_, tag_, 0, 0, 0, 0));
00202     return 0; 
00203 }
00204 
00205 //==============================================================================
00206 // Resize Method 
00207 int EpetraExt::ZoltanMpiDistributor::Resize (
00208  int *sizes)
00209 {
00210     int * sum_recv_sizes = 0;
00211     EPETRA_CHK_ERR (Zoltan_Comm_Resize (plan_, sizes, tag_, sum_recv_sizes));
00212     return 0;
00213 }
00214 
00215 //==============================================================================
00216 // Do method with variable size objects
00217 int EpetraExt::ZoltanMpiDistributor::Do (
00218  char       *exports,
00219  int        obj_size,
00220  int       *&sizes,
00221  int        &len_imports,
00222  char       *imports)
00223 {
00224     int junk;
00225     EPETRA_CHK_ERR (Zoltan_Comm_Resize  (plan_, (int*) sizes, tag_, &junk));
00226     EPETRA_CHK_ERR (Zoltan_Comm_Do_Post (plan_, tag_, exports, 1, imports));
00227     EPETRA_CHK_ERR (Zoltan_Comm_Do_Wait (plan_, tag_, exports, 1, imports));
00228     return 0;      
00229 }
00230 
00231 //==============================================================================
00232 // DoReverse method with variable size objects
00233 int EpetraExt::ZoltanMpiDistributor::DoReverse (
00234  char       *exports,
00235  int        obj_size,
00236  int       *&sizes,
00237  int        &len_imports,
00238  char       *imports)
00239 {
00240    EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Post (plan_, tag_, exports, 1, sizes, imports));
00241    EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Wait (plan_, tag_, exports, 1, sizes, imports));
00242    return 0;      
00243 }
00244    
00245 //==============================================================================
00246 // Do_Posts Method with variable size objects
00247 int EpetraExt::ZoltanMpiDistributor::DoPosts (
00248  char       *exports,
00249  int        obj_size,
00250  int       *&sizes,
00251  int        &len_imports,
00252  char       *imports)
00253 {
00254     int junk;
00255     EPETRA_CHK_ERR (Zoltan_Comm_Resize  (plan_, (int*) sizes, tag_, &junk));
00256     EPETRA_CHK_ERR (Zoltan_Comm_Do_Post (plan_, tag_, exports, 1, imports));
00257     return 0;      
00258 }
00259 
00260 //==============================================================================
00261 // DoReverse_Posts Method with variable size objects
00262 int EpetraExt::ZoltanMpiDistributor::DoReversePosts (
00263  char       *exports,
00264  int        obj_size,
00265  int       *&sizes,
00266  int        &len_imports,
00267  char       *imports)
00268 {
00269     EPETRA_CHK_ERR (Zoltan_Comm_Do_Reverse_Post (plan_, tag_, exports, 1, sizes, imports));
00270     return 0;      
00271 }
00272 
00273 //==============================================================================
00274 // Print method
00275 void EpetraExt::ZoltanMpiDistributor::Print( ostream & os) const
00276 {
00277   int i, j;
00278   int nsends, *send_procs, *send_lengths, send_nvals, send_max_size, *send_list;
00279   int nrecvs, *recv_procs, *recv_lengths, recv_nvals, recv_total_size;
00280   int *recv_list, self_msg;
00281   
00282   Zoltan_Comm_Info (plan_, &nsends, 0, 0, &send_nvals, &send_max_size, 0,
00283    &nrecvs, 0, 0, &recv_nvals, &recv_total_size, 0, &self_msg);
00284 
00285   send_procs   = new int [nsends];
00286   send_lengths = new int [nsends];
00287   send_list    = new int [send_nvals];
00288   recv_procs   = new int [nrecvs];
00289   recv_lengths = new int [nrecvs];
00290   recv_list    = new int [recv_nvals];
00291 
00292   Zoltan_Comm_Info (plan_, 0, send_procs, send_lengths, 0, 0, send_list, 0,
00293   recv_procs, recv_lengths, 0, 0, recv_list, 0);
00294 
00295   os << "nsends: " << nsends << endl;
00296   os << "procs_to: ";
00297   for( i = 0; i < nsends; i++ )
00298     os << " " << send_procs[i];
00299   os << endl;
00300   os<< "lengths_to: ";
00301   for( i = 0; i < nsends; i++ )
00302     os << " " << send_lengths[i];
00303   os << endl;
00304   os << "indices_to: ";
00305 //  int k = 0;
00306 //  for( i = 0; i < nsends; i++ )
00307 //  {
00308 //    for( j = 0; j < send_lengths[i]; j++ )
00309 //      os << " " << plan_->indices_to[j+k];
00310 //    k += send_lengths[i];
00311 //  }
00312   os << endl;
00313   os << "nrecvs: " << nrecvs << endl;
00314   os << "procs_from: ";
00315   for( i = 0; i < nrecvs; i++ )
00316     os << " " << recv_procs[i];
00317   os << endl;
00318   os << "lengths_from: ";
00319   for( i = 0; i < nrecvs; i++ )
00320     os << " " << recv_lengths[i];
00321   os << endl;
00322 /*
00323   os << "indices_from: ";
00324   k = 0;
00325   for( i = 0; i < nrecvs; i++ )
00326   {
00327     for( j = 0; j < recv_lengths[i]; j++ )
00328       os << " " << plan_->indices_from[j+k];
00329     k += recv_lengths[i];
00330   }
00331 */
00332   os << "self_msg: " << self_msg << endl;
00333   os << "max_send_length: " << send_max_size << endl;
00334   os << "total_recv_length: " << recv_total_size << endl;
00335   os << endl;
00336 
00337   delete [] send_procs;
00338   delete [] send_lengths;
00339   delete [] send_list;
00340   delete [] recv_procs;
00341   delete [] recv_lengths;
00342   delete [] recv_list;
00343   
00344   return;
00345 }
00346 

Generated on Wed May 12 21:24:46 2010 for EpetraExt by  doxygen 1.4.7