EpetraExt Development
EpetraExt_ZoltanQuery.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_ZoltanQuery.h>
00030 
00031 #include <Epetra_CrsGraph.h>
00032 #include <Epetra_BlockMap.h>
00033 #include <Epetra_Comm.h>
00034 
00035 #include <algorithm>
00036 
00037 EpetraExt::ZoltanQuery::ZoltanQuery( const Epetra_CrsGraph & graph,
00038                                      const Epetra_CrsGraph * tgraph,
00039                                      bool localEdgesOnly )
00040 : graph_(graph),
00041   tgraph_(tgraph),
00042   localEdgesOnly_(localEdgesOnly)
00043 {
00044   int numMyRows = graph_.NumMyRows();
00045   int maxRows;
00046   graph_.Comm().MaxAll( &numMyRows, &maxRows, 1 );
00047 
00048   LBProc_.resize( numMyRows );
00049 
00050   int numIndices;
00051   int maxNumIndices = graph_.MaxNumIndices();
00052   std::vector<int> indexList( maxNumIndices );
00053   for( int i = 0; i < numMyRows; ++i )
00054   {
00055     graph_.ExtractGlobalRowCopy( graph_.GRID(i),
00056                                  maxNumIndices,
00057                                  numIndices,
00058                                  &indexList[0] );
00059     LBProc_[i].resize( numIndices );
00060     graph_.RowMap().RemoteIDList( numIndices, &indexList[0], &LBProc_[i][0], 0 );
00061   }
00062 
00063   for( int i = numMyRows; i < maxRows; ++i )
00064     graph_.RowMap().RemoteIDList( numIndices, &indexList[0], &LBProc_[numMyRows-1][0], 0 );
00065 
00066   if( tgraph_ )
00067   {
00068     LBProc_Trans_.resize( numMyRows );
00069 
00070     maxNumIndices = tgraph_->MaxNumIndices();
00071     indexList.resize(maxNumIndices);
00072     for( int i = 0; i < numMyRows; ++i )
00073     {
00074       tgraph_->ExtractGlobalRowCopy( tgraph_->GRID(i),
00075                                      maxNumIndices,
00076                                      numIndices,
00077                                      &indexList[0] );
00078       LBProc_Trans_[i].resize( numIndices );
00079       tgraph_->RowMap().RemoteIDList( numIndices, &indexList[0], &LBProc_Trans_[i][0], 0 );
00080     }
00081 
00082     for( int i = numMyRows; i < maxRows; ++i )
00083       tgraph_->RowMap().RemoteIDList( numIndices, &indexList[0], &LBProc_Trans_[numMyRows-1][0], 0 );
00084   }
00085 
00086   graph_.Comm().Barrier();
00087 }
00088 
00089 //General Functions
00090 int EpetraExt::ZoltanQuery::Number_Objects        ( void * data,
00091                                                     int * ierr )
00092 {
00093   *ierr = ZOLTAN_OK;
00094 
00095   return graph_.NumMyRows();
00096 }
00097 
00098 void EpetraExt::ZoltanQuery::Object_List  ( void * data,
00099                                         int num_gid_entries,
00100                                         int num_lid_entries,
00101                                         ZOLTAN_ID_PTR global_ids,
00102                                         ZOLTAN_ID_PTR local_ids,
00103                                         int weight_dim,
00104                                         float * object_weights,
00105                                         int * ierr )
00106 {
00107   *ierr = ZOLTAN_OK;
00108 
00109   int rows = graph_.NumMyRows();
00110 
00111   graph_.RowMap().MyGlobalElements( ((int *) global_ids) );
00112 
00113   int Index = graph_.RowMap().IndexBase();
00114   for( int i = 0; i < rows; i++, Index++ )
00115     local_ids[i] = Index;
00116 }
00117 
00118 //Graph Based Functions
00119 int EpetraExt::ZoltanQuery::Number_Edges  ( void * data,
00120                                         int num_gid_entities,
00121                                         int num_lid_entities,
00122                                         ZOLTAN_ID_PTR global_id,
00123                                         ZOLTAN_ID_PTR local_id,
00124                                         int * ierr )
00125 {
00126   int LocalRow = graph_.LRID( *global_id );
00127 
00128   if( LocalRow != -1 && LocalRow == *local_id )
00129   {
00130     *ierr = ZOLTAN_OK;
00131 
00132     int NumIndices = graph_.NumMyIndices( LocalRow );
00133     int IndiceCountReturn;
00134 
00135     std::vector<int> nbr_edges( NumIndices );
00136     int flag = graph_.ExtractGlobalRowCopy( ((int) *global_id),
00137                                          NumIndices,
00138                                          IndiceCountReturn,
00139                                          &(nbr_edges[0]) );
00140     assert( flag == 0 );
00141     assert( NumIndices == IndiceCountReturn );
00142     std::sort( nbr_edges.begin(), nbr_edges.end() );
00143 
00144     bool self = false;
00145     for(int i = 0; i < NumIndices; ++i )
00146       if( nbr_edges[i] == ((int) *global_id) )
00147       { self = true; break; }
00148 
00149     int nonLocalEdges = 0;
00150     if( localEdgesOnly_ )
00151       for( int i = 0; i < NumIndices; ++i )
00152         if( !graph_.MyGRID(nbr_edges[i]) ) ++nonLocalEdges;
00153 
00154     if( tgraph_ )
00155     {
00156       int tNumIndices = tgraph_->NumMyIndices( LocalRow );
00157       std::vector<int> t_nbr_edges( tNumIndices );
00158 
00159       flag = tgraph_->ExtractGlobalRowCopy( ((int) *global_id),
00160                                            tNumIndices,
00161                                            IndiceCountReturn,
00162                                            &(t_nbr_edges[0]) );
00163       assert( flag == 0 );
00164       assert( tNumIndices == IndiceCountReturn );
00165 
00166       for( int i = 0; i < tNumIndices; ++i )
00167         if( !std::binary_search( nbr_edges.begin(), nbr_edges.end(), t_nbr_edges[i] ) )
00168         {
00169           ++NumIndices;
00170           if( localEdgesOnly_ && !graph_.MyGRID(t_nbr_edges[i]) ) ++nonLocalEdges;
00171         }
00172     }
00173 
00174 //std::cout << "Indices Cnt: " << ((int)*global_id) << " " << ((int)*local_id) << " " << NumIndices-(self?1:0)-nonLocalEdges  << std::endl;
00175     return NumIndices - (self?1:0) - nonLocalEdges;
00176 
00177   }
00178   else
00179   {
00180     *ierr = ZOLTAN_FATAL;
00181     return -1;
00182   }
00183 }
00184 
00185 void EpetraExt::ZoltanQuery::Edge_List    ( void * data,
00186                                         int num_gid_entities,
00187                                         int num_lid_entities,
00188                                         ZOLTAN_ID_PTR global_id,
00189                                         ZOLTAN_ID_PTR local_id,
00190                                         ZOLTAN_ID_PTR neighbor_global_ids,
00191                                         int * neighbor_procs,
00192                                         int weight_dim,
00193                                         float * edge_weights,
00194                                         int * ierr )
00195 {
00196   int NumIndices = graph_.NumMyIndices( ((int) *local_id) );
00197 
00198   int IndiceCountReturn;
00199 
00200   if( NumIndices != -1 )
00201   {
00202     std::vector<int> nbr_edges( NumIndices );
00203     int flag = graph_.ExtractGlobalRowCopy( ((int) *global_id), 
00204                                          NumIndices,
00205                                          IndiceCountReturn,
00206                                          &(nbr_edges[0]) );
00207     assert( flag == 0 );
00208     assert( NumIndices == IndiceCountReturn );
00209 
00210     int ii = 0;
00211     for( int i = 0; i < NumIndices; ++i )
00212       if( nbr_edges[ i ] != ((int) *global_id) )
00213         if( !localEdgesOnly_ || graph_.MyGRID(nbr_edges[i]) )
00214         {
00215           neighbor_global_ids[ ii ] = nbr_edges[ i ];
00216           neighbor_procs[ ii ] = LBProc_[(int) *local_id][ i ];
00217           ++ii;
00218         }
00219 
00220     if( tgraph_ )
00221     {
00222       std::sort( nbr_edges.begin(), nbr_edges.end() );
00223 
00224       int tNumIndices = tgraph_->NumMyIndices( ((int) *local_id) );
00225       std::vector<int> t_nbr_edges( tNumIndices );
00226 
00227       flag = tgraph_->ExtractGlobalRowCopy( ((int) *global_id),
00228                                            tNumIndices,
00229                                            IndiceCountReturn,
00230                                            &(t_nbr_edges[0]) );
00231       assert( flag == 0 );
00232       assert( tNumIndices == IndiceCountReturn );
00233 
00234       for( int i = 0; i < tNumIndices; ++i )
00235         if( !std::binary_search( nbr_edges.begin(), nbr_edges.end(), t_nbr_edges[i] ) )
00236           if( !localEdgesOnly_ || graph_.MyGRID(t_nbr_edges[i]) )
00237           {
00238             neighbor_global_ids[ii] = t_nbr_edges[i];
00239             neighbor_procs[ii] = LBProc_Trans_[(int) *local_id][i];
00240             ++ii;
00241           }
00242     }
00243 
00244 
00245 /*
00246 std::cout << "Edge List: " << ((int) *global_id) << " " << ((int) *local_id) << std::endl;
00247 std::cout << "NumIndices: " << NumIndices << " " << "ii: " << ii << std::endl;
00248 for( int i = 0; i < ii; ++i )
00249   std::cout << " " << ((int *) neighbor_global_ids)[i] << " " <<
00250         neighbor_procs[i] << std::endl;
00251 std::cout << std::endl;
00252 */
00253 
00254     *ierr = ZOLTAN_OK;
00255   }
00256   else
00257     *ierr = ZOLTAN_FATAL;
00258 
00259 }
00260 
00261 int EpetraExt::ZoltanQuery::Number_HG_Edges ( void * data,
00262             int * ierr )
00263 {
00264   int num = graph_.NumMyRows();
00265   std::cout << "NRows: " << num << std::endl;
00266 
00267   *ierr = ZOLTAN_OK;
00268   return num;
00269 }
00270 
00271 int EpetraExt::ZoltanQuery::Number_HG_Pins ( void * data,
00272                  int * ierr )
00273 {
00274   int num = graph_.NumMyEntries();
00275   std::cout << "NNZ: " << num << std::endl;
00276 
00277   *ierr = ZOLTAN_OK;
00278   return num;
00279 }
00280 
00281 int EpetraExt::ZoltanQuery::HG_Edge_List   ( void * data,
00282                                          int num_gid_entries,
00283                                          int ewgt_dim,
00284                                          int nedge,
00285                                          int maxsize,
00286                                          int * edge_sizes,
00287                                          ZOLTAN_ID_PTR edge_verts,
00288                                          int * edge_procs,
00289                                          float * edge_weights )
00290 
00291 {
00292   int NumHEs = graph_.NumMyRows();
00293   int maxEntries = graph_.MaxNumIndices();
00294 
00295   int numIndices;
00296   std::vector<int> indices( maxEntries );
00297 
00298   std::cout << "nedge: " << nedge << std::endl;
00299   std::cout << "maxsize: " << maxsize << std::endl;
00300 
00301   int loc = 0;
00302   for( int i = 0; i < NumHEs; ++i )
00303   {
00304     int flag = graph_.ExtractGlobalRowCopy( graph_.GRID(i), maxEntries, numIndices, &indices[0] );
00305     assert( flag == 0 );
00306 
00307     edge_sizes[i] = numIndices;
00308     for( int j = 0; j < numIndices; ++j )
00309     {
00310       edge_verts[loc] = indices[j];
00311       edge_procs[loc] = LBProc_[i][j];
00312       ++loc;
00313     }
00314   }
00315 
00316   std::cout << "last_loc: " << loc << std::endl;
00317 
00318   return ZOLTAN_OK;
00319 }
00320 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines