EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_Zoltan_CrsGraph.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_config.h"
00030 
00031 #include <EpetraExt_Zoltan_CrsGraph.h>
00032 
00033 #include <EpetraExt_Transpose_CrsGraph.h>
00034 
00035 #include <EpetraExt_ZoltanQuery.h>
00036 #include <Zoltan_LoadBalance.h>
00037 
00038 #include <Epetra_CrsGraph.h>
00039 #include <Epetra_Map.h>
00040 #include <Epetra_Import.h>
00041 
00042 #include <Epetra_MpiComm.h>
00043 
00044 #include <vector>
00045 #include <set>
00046 
00047 using std::vector;
00048 using std::set;
00049 
00050 namespace EpetraExt {
00051 
00052 Zoltan_CrsGraph::
00053 ~Zoltan_CrsGraph()
00054 {
00055   if( newObj_ ) delete newObj_;
00056 
00057   if( NewRowMap_ ) delete NewRowMap_;
00058 }
00059 
00060 Zoltan_CrsGraph::NewTypeRef
00061 Zoltan_CrsGraph::
00062 operator()( OriginalTypeRef orig )
00063 {
00064   origObj_ = &orig;
00065 
00066   int err;
00067 
00068   //Setup Load Balance Object
00069   float version;
00070   char * dummy = 0;
00071   Zoltan::LoadBalance LB( 0, &dummy, &version );
00072   err = LB.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() );
00073   if( err == ZOLTAN_OK ) err = LB.Set_Param( "LB_METHOD", "GRAPH" );
00074 #ifdef HAVE_LIBPARMETIS
00075   if( err == ZOLTAN_OK ) err = LB.Set_Param( "GRAPH_PACKAGE", "PARMETIS" );
00076   if( err == ZOLTAN_OK ) err = LB.Set_Param( "PARMETIS_METHOD", partitionMethod_ );
00077 #endif
00078 
00079   //Setup Query Object
00080   CrsGraph_Transpose transposeTransform;
00081   Epetra_CrsGraph & TransGraph = transposeTransform( orig );
00082   ZoltanQuery Query( orig, &TransGraph );
00083   if( err == ZOLTAN_OK ) err = LB.Set_QueryObject( &Query );
00084 
00085   if( err != ZOLTAN_OK )
00086   { cout << "Setup of Zoltan Load Balancing Objects FAILED!\n"; exit(0); }
00087 
00088   //Generate Load Balance
00089   int changes;
00090   int num_gid_entries, num_lid_entries;
00091   int num_import;
00092   ZOLTAN_ID_PTR import_global_ids, import_local_ids;
00093   int * import_procs;
00094   int num_export;
00095   ZOLTAN_ID_PTR export_global_ids, export_local_ids;
00096   int * export_procs;
00097 
00098   orig.Comm().Barrier();
00099   err = LB.Balance( &changes,
00100                      &num_gid_entries, &num_lid_entries,
00101                      &num_import, &import_global_ids, &import_local_ids, &import_procs,
00102                      &num_export, &export_global_ids, &export_local_ids, &export_procs );
00103   LB.Evaluate( 1, 0, 0, 0, 0, 0, 0 );
00104   orig.Comm().Barrier();
00105 
00106   //Generate New Element List
00107   int numMyElements = orig.RowMap().NumMyElements();
00108   vector<int> elementList( numMyElements );
00109   orig.RowMap().MyGlobalElements( &elementList[0] );
00110 
00111   int newNumMyElements = numMyElements - num_export + num_import;
00112   vector<int> newElementList( newNumMyElements );
00113 
00114   set<int> gidSet;
00115   for( int i = 0; i < num_export; ++i )
00116     gidSet.insert( export_global_ids[i] );
00117 
00118   //Add unmoved indices to new list
00119   int loc = 0;
00120   for( int i = 0; i < numMyElements; ++i )
00121     if( !gidSet.count( elementList[i] ) )
00122       newElementList[loc++] = elementList[i];
00123   
00124   //Add imports to end of list
00125   for( int i = 0; i < num_import; ++i )
00126     newElementList[loc+i] = import_global_ids[i];
00127 
00128   //Free Zoltan Data
00129   if( err == ZOLTAN_OK )
00130     err = LB.Free_Data( &import_global_ids, &import_local_ids, &import_procs,
00131                          &export_global_ids, &export_local_ids, &export_procs );
00132 
00133   //Create Import Map
00134   NewRowMap_ = new Epetra_Map( orig.RowMap().NumGlobalElements(),
00135                                            newNumMyElements,
00136                                            &newElementList[0],
00137                                            orig.RowMap().IndexBase(),
00138                                            orig.RowMap().Comm() );
00139 
00140   //Create Importer
00141   Epetra_Import Importer( *NewRowMap_, orig.RowMap() );
00142 
00143   //Create New Graph
00144   Epetra_CrsGraph * NewGraph = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 );
00145   NewGraph->Import( orig, Importer, Insert );
00146   NewGraph->FillComplete();
00147 
00148   Zoltan::LoadBalance LB2( 0, &dummy, &version );
00149   err = LB2.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() );
00150   if( err == ZOLTAN_OK ) err = LB2.Set_Param( "LB_METHOD", "GRAPH" );
00151 #ifdef HAVE_LIBPARMETIS
00152   if( err == ZOLTAN_OK ) err = LB2.Set_Param( "GRAPH_PACKAGE", "PARMETIS" );
00153   if( err == ZOLTAN_OK ) err = LB2.Set_Param( "PARMETIS_METHOD", partitionMethod_ );
00154 #endif
00155   CrsGraph_Transpose transTrans;
00156   Epetra_CrsGraph & trans2 = transTrans( *NewGraph );
00157   ZoltanQuery query( *NewGraph, &trans2 );
00158   if( err == ZOLTAN_OK ) err = LB2.Set_QueryObject( &query );
00159   //err = LB2.Balance( &changes,
00160   //                   &num_gid_entries, &num_lid_entries,
00161   //                   &num_import, &import_global_ids, &import_local_ids, &import_procs,
00162   //                   &num_export, &export_global_ids, &export_local_ids, &export_procs );
00163   LB2.Evaluate( 1, 0, 0, 0, 0, 0, 0 );
00164 
00165   newObj_ = NewGraph;
00166 
00167   return *NewGraph;
00168 }
00169 
00170 } // namespace EpetraExt
00171 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines