Epetra Package Browser (Single Doxygen Collection) Development
Epetra_DistObject.cpp
Go to the documentation of this file.
00001 
00002 //@HEADER
00003 // ************************************************************************
00004 //
00005 //               Epetra: Linear Algebra Services Package
00006 //                 Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ************************************************************************
00041 //@HEADER
00042 
00043 #include "Epetra_DistObject.h"
00044 #include "Epetra_Comm.h"
00045 #include "Epetra_Import.h"
00046 #include "Epetra_Export.h"
00047 #include "Epetra_Distributor.h"
00048 
00049 
00050 
00051 //=============================================================================
00052 // Constructor
00053 
00054 Epetra_DistObject::Epetra_DistObject(const Epetra_BlockMap& map)
00055   : Epetra_Object("Epetra::DistObject"),
00056     Map_(map),
00057     Comm_(&Map_.Comm()),
00058     DistributedGlobal_(map.DistributedGlobal()),
00059     Exports_(0),
00060     Imports_(0),
00061     LenExports_(0),
00062     LenImports_(0),
00063     Sizes_(0)
00064 {}
00065 
00066 //=============================================================================
00067 // Constructor (label given)
00068 
00069 Epetra_DistObject::Epetra_DistObject(const Epetra_BlockMap& map, const char* const label)
00070   : Epetra_Object(label),
00071     Map_(map),
00072     Comm_(&Map_.Comm()),
00073     DistributedGlobal_(map.DistributedGlobal()),
00074     Exports_(0),
00075     Imports_(0),
00076     LenExports_(0),
00077     LenImports_(0),
00078     Sizes_(0)
00079 {}
00080 
00081 //=============================================================================
00082 // Copy Constructor
00083 
00084 Epetra_DistObject::Epetra_DistObject(const Epetra_DistObject& Source)
00085   : Epetra_Object(Source),
00086     Map_(Source.Map_),
00087     Comm_(&Map_.Comm()),
00088     DistributedGlobal_(Source.DistributedGlobal_),
00089     Exports_(0),
00090     Imports_(0),
00091     LenExports_(0),
00092     LenImports_(0),
00093     Sizes_(0)
00094 {}
00095 
00096 //=============================================================================
00097 Epetra_DistObject::~Epetra_DistObject(){
00098 
00099 
00100   if (LenExports_!=0) {
00101     delete[] Exports_;
00102     Exports_ = 0;
00103     LenExports_ = 0;
00104   }
00105   if (LenImports_!=0) {
00106     delete[] Imports_;
00107     Imports_ = 0;
00108     LenImports_ = 0;
00109   }
00110 
00111   if (Sizes_!=0) delete [] Sizes_;
00112   Sizes_ = 0;
00113 }
00114 
00115 //=============================================================================
00116 int Epetra_DistObject::Import(const Epetra_SrcDistObject& A,
00117             const Epetra_Import& Importer,
00118             Epetra_CombineMode CombineMode,
00119                               const Epetra_OffsetIndex * Indexor)
00120 {
00121 
00122   if (!Map_.SameAs(Importer.TargetMap())) EPETRA_CHK_ERR(-2);
00123   if (!A.Map().SameAs(Importer.SourceMap())) EPETRA_CHK_ERR(-3);
00124 
00125   int NumSameIDs = Importer.NumSameIDs();
00126   int NumPermuteIDs = Importer.NumPermuteIDs();
00127   int NumRemoteIDs = Importer.NumRemoteIDs();
00128   int NumExportIDs = Importer.NumExportIDs();
00129   int* ExportLIDs = Importer.ExportLIDs();
00130   int* RemoteLIDs = Importer.RemoteLIDs();
00131   int* PermuteToLIDs = Importer.PermuteToLIDs();
00132   int* PermuteFromLIDs = Importer.PermuteFromLIDs();
00133 
00134   EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs,
00135           PermuteToLIDs, PermuteFromLIDs, RemoteLIDs, ExportLIDs,
00136           LenExports_, Exports_, LenImports_, Imports_, Importer.Distributor(),
00137           false, Indexor));
00138   return(0);
00139 }
00140 
00141 //=============================================================================
00142 int Epetra_DistObject::Export(const Epetra_SrcDistObject& A,
00143             const Epetra_Export& Exporter,
00144             Epetra_CombineMode CombineMode,
00145                               const Epetra_OffsetIndex * Indexor)
00146 {
00147 
00148   if (!Map_.SameAs(Exporter.TargetMap())) EPETRA_CHK_ERR(-2);
00149   if (!A.Map().SameAs(Exporter.SourceMap())) EPETRA_CHK_ERR(-3);
00150 
00151   int NumSameIDs = Exporter.NumSameIDs();
00152   int NumPermuteIDs = Exporter.NumPermuteIDs();
00153   int NumRemoteIDs = Exporter.NumRemoteIDs();
00154   int NumExportIDs = Exporter.NumExportIDs();
00155   int* ExportLIDs = Exporter.ExportLIDs();
00156   int* RemoteLIDs = Exporter.RemoteLIDs();
00157   int* PermuteToLIDs = Exporter.PermuteToLIDs();
00158   int* PermuteFromLIDs = Exporter.PermuteFromLIDs();
00159 
00160   EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs,
00161           PermuteToLIDs, PermuteFromLIDs, RemoteLIDs, ExportLIDs,
00162           LenExports_, Exports_,LenImports_, Imports_, Exporter.Distributor(),
00163           false, Indexor));
00164   return(0);
00165 }
00166 
00167 //=============================================================================
00168 int Epetra_DistObject::Import(const Epetra_SrcDistObject& A,
00169             const Epetra_Export& Exporter,
00170             Epetra_CombineMode CombineMode,
00171                               const Epetra_OffsetIndex * Indexor)
00172 {
00173 
00174   if (!Map_.SameAs(Exporter.SourceMap())) EPETRA_CHK_ERR(-2);
00175   if (!A.Map().SameAs(Exporter.TargetMap())) EPETRA_CHK_ERR(-3);
00176 
00177   int NumSameIDs = Exporter.NumSameIDs();
00178   int NumPermuteIDs = Exporter.NumPermuteIDs();
00179   int NumRemoteIDs = Exporter.NumExportIDs();
00180   int NumExportIDs = Exporter.NumRemoteIDs();
00181   int* ExportLIDs = Exporter.RemoteLIDs();
00182   int* RemoteLIDs = Exporter.ExportLIDs();
00183   int* PermuteToLIDs = Exporter.PermuteFromLIDs();
00184   int* PermuteFromLIDs = Exporter.PermuteToLIDs();
00185 
00186   EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs,
00187           PermuteToLIDs, PermuteFromLIDs, RemoteLIDs, ExportLIDs,
00188           LenImports_, Imports_, LenExports_, Exports_, Exporter.Distributor(),
00189           true, Indexor));
00190   return(0);
00191 }
00192 
00193 //=============================================================================
00194 int Epetra_DistObject::Export(const Epetra_SrcDistObject& A,
00195             const Epetra_Import& Importer,
00196             Epetra_CombineMode CombineMode,
00197                               const Epetra_OffsetIndex * Indexor)
00198 {
00199 
00200   if (!Map_.SameAs(Importer.SourceMap())) EPETRA_CHK_ERR(-2);
00201   if (!A.Map().SameAs(Importer.TargetMap())) EPETRA_CHK_ERR(-3);
00202 
00203   int NumSameIDs = Importer.NumSameIDs();
00204   int NumPermuteIDs = Importer.NumPermuteIDs();
00205   int NumRemoteIDs = Importer.NumExportIDs();
00206   int NumExportIDs = Importer.NumRemoteIDs();
00207   int* ExportLIDs = Importer.RemoteLIDs();
00208   int* RemoteLIDs = Importer.ExportLIDs();
00209   int* PermuteToLIDs = Importer.PermuteFromLIDs();
00210   int* PermuteFromLIDs = Importer.PermuteToLIDs();
00211 
00212   EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs,
00213           PermuteToLIDs, PermuteFromLIDs,  RemoteLIDs, ExportLIDs,
00214           LenImports_, Imports_, LenExports_, Exports_,
00215           Importer.Distributor(), true, Indexor));
00216   return(0);
00217 }
00218 
00219 //=============================================================================
00220 int Epetra_DistObject::DoTransfer(const Epetra_SrcDistObject& A,
00221           Epetra_CombineMode CombineMode,
00222           int NumSameIDs,
00223           int NumPermuteIDs,
00224           int NumRemoteIDs,
00225           int NumExportIDs,
00226           int* PermuteToLIDs,
00227           int* PermuteFromLIDs,
00228           int* RemoteLIDs,
00229           int* ExportLIDs,
00230           int& LenExports,
00231           char*& Exports,
00232           int& LenImports,
00233           char*& Imports,
00234           Epetra_Distributor& Distor,
00235           bool DoReverse,
00236                                   const Epetra_OffsetIndex * Indexor)
00237 {
00238 
00239   EPETRA_CHK_ERR(CheckSizes(A));
00240 
00241   if (NumSameIDs + NumPermuteIDs > 0) {
00242     EPETRA_CHK_ERR(CopyAndPermute(A, NumSameIDs, NumPermuteIDs, PermuteToLIDs, PermuteFromLIDs,Indexor));
00243   }
00244 
00245   if (CombineMode==Zero)
00246     return(0); // All done if CombineMode only involves copying and permuting
00247 
00248   int SizeOfPacket;
00249   bool VarSizes = false;
00250   if( NumExportIDs > 0) {
00251     delete [] Sizes_;
00252     Sizes_ = new int[NumExportIDs];
00253   }
00254   EPETRA_CHK_ERR(PackAndPrepare(A, NumExportIDs, ExportLIDs,
00255                  LenExports, Exports, SizeOfPacket, Sizes_, VarSizes, Distor));
00256 
00257   if ((DistributedGlobal_ && DoReverse) || (A.Map().DistributedGlobal() && !DoReverse)) {
00258     if (DoReverse) {
00259       // Do the exchange of remote data
00260       if( VarSizes ) {
00261         EPETRA_CHK_ERR(Distor.DoReverse(Exports, SizeOfPacket, Sizes_, LenImports, Imports));
00262       }
00263       else {
00264         EPETRA_CHK_ERR(Distor.DoReverse(Exports, SizeOfPacket, LenImports, Imports));
00265       }
00266     }
00267     else {
00268       // Do the exchange of remote data
00269       if( VarSizes ) {
00270         EPETRA_CHK_ERR(Distor.Do(Exports, SizeOfPacket, Sizes_, LenImports, Imports));
00271       }
00272       else {
00273         EPETRA_CHK_ERR(Distor.Do(Exports, SizeOfPacket, LenImports, Imports));
00274       }
00275     }
00276     EPETRA_CHK_ERR(UnpackAndCombine(A, NumRemoteIDs, RemoteLIDs, LenImports, Imports, SizeOfPacket, Distor, CombineMode, Indexor));
00277   }
00278 
00279   return(0);
00280 }
00281 
00282 //=============================================================================
00283 void Epetra_DistObject::Print(std::ostream& os) const {
00284   int MyPID = Comm().MyPID();
00285   int NumProc = Comm().NumProc();
00286 
00287   for (int iproc=0; iproc < NumProc; iproc++) {
00288     if (MyPID==iproc) {
00289       Comm().PrintInfo(os);
00290       os << "Length of Export buffer (in chars) = " << LenExports_ << std::endl;
00291       os << "Length of Import buffer (in chars) = " << LenImports_ << std::endl;
00292       os << std::flush;
00293     }
00294   }
00295   return;
00296 }
00297 
00298 //------------------------------------------------------------------------------
00299 Epetra_DistObject& Epetra_DistObject::operator=(const Epetra_DistObject& src)
00300 {
00301   (void)src;
00302   //not currently supported
00303   bool throw_error = true;
00304   if (throw_error) {
00305     throw ReportError("Epetra_DistObject::operator= is not supported.",-1);
00306   }
00307 
00308   return(*this);
00309 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines