00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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
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
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
00247
00248
00249
00250
00251
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