Epetra Package Browser (Single Doxygen Collection) Development
Epetra_OffsetIndex.cpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 // 
00004 //               Epetra: Linear Algebra Services Package 
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00038 // 
00039 // ************************************************************************
00040 //@HEADER
00041 
00042 #include "Epetra_OffsetIndex.h"
00043 #include "Epetra_CrsGraph.h"
00044 #include "Epetra_Import.h"
00045 #include "Epetra_Export.h"
00046 #include "Epetra_Distributor.h"
00047 #include "Epetra_Comm.h"
00048 
00049 //==============================================================================
00050 // Epetra_OffsetIndex constructor from Importer
00051 Epetra_OffsetIndex::Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph,
00052                                         const Epetra_CrsGraph & TargetGraph,
00053                                         Epetra_Import & Importer )
00054   : Epetra_Object("Epetra::OffsetIndex"),
00055     NumSame_(0),
00056     SameOffsets_(0),
00057     NumPermute_(0),
00058     PermuteOffsets_(0),
00059     NumExport_(0),
00060     NumRemote_(0),
00061     RemoteOffsets_(0),
00062     DataOwned_(true)
00063 {
00064   NumSame_ = Importer.NumSameIDs();
00065 
00066   NumPermute_ = Importer.NumPermuteIDs();
00067   int * PermuteLIDs = Importer.PermuteToLIDs();
00068 
00069   NumExport_ = Importer.NumExportIDs();
00070   int * ExportLIDs = Importer.ExportLIDs();
00071 
00072   NumRemote_ = Importer.NumRemoteIDs();
00073   int * RemoteLIDs = Importer.RemoteLIDs();
00074 
00075   GenerateLocalOffsets_( SourceGraph, TargetGraph,
00076                          PermuteLIDs );
00077 
00078   GenerateRemoteOffsets_( SourceGraph, TargetGraph,
00079                           ExportLIDs, RemoteLIDs,
00080                           Importer.Distributor() );
00081 }
00082 
00083 //==============================================================================
00084 // Epetra_OffsetIndex constructor from Exporter
00085 Epetra_OffsetIndex::Epetra_OffsetIndex( const Epetra_CrsGraph & SourceGraph,
00086                                         const Epetra_CrsGraph & TargetGraph,
00087                                         Epetra_Export & Exporter )
00088   : Epetra_Object("Epetra::OffsetIndex"),
00089     NumSame_(0),
00090     SameOffsets_(0),
00091     NumPermute_(0),
00092     PermuteOffsets_(0),
00093     NumExport_(0),
00094     NumRemote_(0),
00095     RemoteOffsets_(0),
00096     DataOwned_(true)
00097 {
00098   NumSame_ = Exporter.NumSameIDs();
00099 
00100   NumPermute_ = Exporter.NumPermuteIDs();
00101   int * PermuteLIDs = Exporter.PermuteToLIDs();
00102 
00103   NumExport_ = Exporter.NumExportIDs();
00104   int * ExportLIDs = Exporter.ExportLIDs();
00105 
00106   NumRemote_ = Exporter.NumRemoteIDs();
00107   int * RemoteLIDs = Exporter.RemoteLIDs();
00108 
00109   GenerateLocalOffsets_( SourceGraph, TargetGraph,
00110                          PermuteLIDs );
00111 
00112   GenerateRemoteOffsets_( SourceGraph, TargetGraph,
00113                           ExportLIDs, RemoteLIDs,
00114                           Exporter.Distributor() );
00115 }
00116 
00117 //==============================================================================
00118 // Epetra_OffsetIndex copy constructor 
00119 Epetra_OffsetIndex::Epetra_OffsetIndex(const Epetra_OffsetIndex& Indexor)
00120   : Epetra_Object(Indexor),
00121     NumSame_(Indexor.NumSame_),
00122     SameOffsets_(Indexor.SameOffsets_),
00123     NumPermute_(Indexor.NumPermute_),
00124     PermuteOffsets_(Indexor.PermuteOffsets_),
00125     NumExport_(0),
00126     NumRemote_(Indexor.NumRemote_),
00127     RemoteOffsets_(Indexor.RemoteOffsets_),
00128     DataOwned_(false)
00129 {
00130 }
00131 
00132 //==============================================================================
00133 // Epetra_OffsetIndex destructor
00134 Epetra_OffsetIndex::~Epetra_OffsetIndex()
00135 {
00136   if( DataOwned_ )
00137   {
00138     for( int i = 0; i < NumSame_; ++i )
00139       if( SameOffsets_[i] ) delete [] SameOffsets_[i];
00140     delete [] SameOffsets_;
00141     for( int i = 0; i < NumPermute_; ++i )
00142       if( PermuteOffsets_[i] ) delete [] PermuteOffsets_[i];
00143     delete [] PermuteOffsets_;
00144     for( int i = 0; i < NumRemote_; ++i )
00145       if( RemoteOffsets_[i] ) delete [] RemoteOffsets_[i];
00146     delete [] RemoteOffsets_;
00147   }
00148 }
00149 
00150 //==============================================================================
00151 void Epetra_OffsetIndex::GenerateLocalOffsets_( const Epetra_CrsGraph & SourceGraph,
00152                                                 const Epetra_CrsGraph & TargetGraph,
00153                                                 const int * PermuteLIDs )
00154 {
00155   const int GlobalMaxNumSourceIndices = SourceGraph.GlobalMaxNumIndices();
00156 
00157   int NumSourceIndices;
00158   int * SourceIndices = 0;
00159   if( GlobalMaxNumSourceIndices>0 ) SourceIndices = new int[GlobalMaxNumSourceIndices];
00160 
00161   //setup Same Offsets
00162   SameOffsets_ = new int*[NumSame_];
00163   for( int i = 0; i < NumSame_; ++i ) SameOffsets_[i] = 0;
00164 
00165   for( int i = 0; i < NumSame_; ++i ) {
00166     int GID = SourceGraph.GRID(i);
00167     SourceGraph.ExtractGlobalRowCopy( GID,
00168                                       GlobalMaxNumSourceIndices,
00169                                       NumSourceIndices,
00170                                       SourceIndices );
00171 
00172     if( NumSourceIndices > 0 ) SameOffsets_[i] = new int[NumSourceIndices];
00173 
00174     int Loc = 0;
00175     int Start = 0;
00176     for( int j = 0; j < NumSourceIndices; ++j ) {
00177       Start = Loc;
00178       if( TargetGraph.FindGlobalIndexLoc(i,SourceIndices[j],Start,Loc) )
00179         SameOffsets_[i][j] = Loc;
00180       else
00181         SameOffsets_[i][j] = -1;
00182     }
00183   }
00184 
00185   //do also for permuted ids
00186   PermuteOffsets_ = new int*[NumPermute_];
00187   for( int i = 0; i < NumPermute_; ++i ) PermuteOffsets_[i] = 0;
00188 
00189   for( int i = 0; i < NumPermute_; ++i ) {
00190     int GID = SourceGraph.GRID(PermuteLIDs[i]);
00191     SourceGraph.ExtractGlobalRowCopy( GID,
00192                                       GlobalMaxNumSourceIndices,
00193                                       NumSourceIndices,
00194                                       SourceIndices );
00195 
00196     if( NumSourceIndices > 0 ) PermuteOffsets_[i] = new int[NumSourceIndices];
00197 
00198     int Loc = 0;
00199     int Start = 0;
00200     for( int j = 0; j < NumSourceIndices; ++j ) {
00201       Start = Loc;
00202       if( TargetGraph.FindGlobalIndexLoc(PermuteLIDs[i],SourceIndices[j],Start,Loc) )
00203         PermuteOffsets_[i][j] = Loc;
00204       else
00205         PermuteOffsets_[i][j] = -1;
00206     }
00207   }
00208 
00209   if( GlobalMaxNumSourceIndices>0 ) delete [] SourceIndices;
00210 }
00211 
00212 //==============================================================================
00213 void Epetra_OffsetIndex::GenerateRemoteOffsets_( const Epetra_CrsGraph & SourceGraph,
00214                                                  const Epetra_CrsGraph & TargetGraph,
00215                                                  const int * ExportLIDs,
00216                                                  const int * RemoteLIDs,
00217                                                  Epetra_Distributor & Distor )
00218 {
00219   int numProcs = SourceGraph.RowMap().Comm().NumProc();
00220   if (numProcs < 2) {
00221     return;
00222   }
00223 
00224   const int GlobalMaxNumIndices = SourceGraph.GlobalMaxNumIndices();
00225 
00226   int NumIndices;
00227   int * Indices = 0;
00228   if( GlobalMaxNumIndices>0 ) Indices = new int[GlobalMaxNumIndices];
00229 
00230   //Pack Source Rows
00231   int * Sizes = 0;
00232   if( NumExport_ > 0 ) Sizes = new int[NumExport_];
00233   int TotalSize = 0;
00234   for( int i = 0; i < NumExport_; ++i ) {
00235     Sizes[i] = SourceGraph.NumMyIndices(ExportLIDs[i]) + 1;
00236     TotalSize += Sizes[i];
00237   }
00238 
00239   int * SourceArray = new int[TotalSize+1];
00240   int Loc = 0;
00241   for( int i = 0; i < NumExport_; ++i ) {
00242     int GID = SourceGraph.GRID(ExportLIDs[i]);
00243     SourceArray[Loc] = Sizes[i]-1;
00244     SourceGraph.ExtractGlobalRowCopy( GID,
00245                                       GlobalMaxNumIndices,
00246                                       NumIndices,
00247                                       &(SourceArray[Loc+1]) );
00248     Loc += Sizes[i];
00249   }
00250 
00251   //Push to Target
00252   char * cRecvArray = 0;
00253   int * RecvArray = 0;
00254   int RecvArraySize = 0;
00255   Distor.Do( reinterpret_cast<char *>(SourceArray),
00256              (int)sizeof(int),
00257              Sizes,
00258              RecvArraySize,
00259              cRecvArray );
00260   RecvArray = reinterpret_cast<int*>(cRecvArray);
00261 
00262   //Construct RemoteOffsets
00263   if( NumRemote_ > 0 ) RemoteOffsets_ = new int*[NumRemote_];
00264   for( int i = 0; i < NumRemote_; ++i ) RemoteOffsets_[i] = 0;
00265 
00266   Loc = 0;
00267   for( int i = 0; i < NumRemote_; ++i ) {
00268     NumIndices = RecvArray[Loc];
00269     RemoteOffsets_[i] = new int[NumIndices];
00270     ++Loc;
00271     int FLoc = 0;
00272     int Start = 0;
00273     for( int j = 0; j < NumIndices; ++j ) {
00274       Start = FLoc;
00275       if( TargetGraph.FindGlobalIndexLoc(RemoteLIDs[i],RecvArray[Loc],Start,FLoc) )
00276         RemoteOffsets_[i][j] = FLoc;
00277       else
00278         RemoteOffsets_[i][j] = -1;
00279       ++Loc;
00280     }
00281   }
00282 
00283   if( GlobalMaxNumIndices>0 ) delete [] Indices;
00284   if( Sizes ) delete [] Sizes;
00285   if( SourceArray ) delete [] SourceArray;
00286   if( RecvArraySize ) delete [] cRecvArray;
00287 }
00288 
00289 //=============================================================================
00290 void Epetra_OffsetIndex::Print(ostream & os) const
00291 {
00292   os << "Number of Same IDs = " << NumSame_ << endl;
00293   os << "Number of Permute IDs = " << NumPermute_ << endl;
00294   os << "Number of Remote IDs = " << NumRemote_ << endl;
00295   
00296   return;
00297 }
00298 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines