42 if( MB_SUCCESS != result ) return result
60 const bool use_coords,
71 myZZ( NULL ), myNumPts( 0 ), argcArg( argc ), argvArg( argv )
81 const char* other_method,
82 const bool write_as_sets,
83 const bool write_as_tags )
85 if( !strcmp( zmethod,
"RR" ) && !strcmp( zmethod,
"RCB" ) && !strcmp( zmethod,
"RIB" ) &&
86 !strcmp( zmethod,
"HSFC" ) && !strcmp( zmethod,
"Hypergraph" ) && !strcmp( zmethod,
"PHG" ) &&
87 !strcmp( zmethod,
"PARMETIS" ) && !strcmp( zmethod,
"OCTPART" ) )
89 std::cout <<
"ERROR node " << mbpc->proc_config().proc_rank() <<
": Method must be "
90 <<
"RR, RCB, RIB, HSFC, Hypergraph (PHG), PARMETIS, or OCTPART" << std::endl;
94 std::vector< double > pts;
95 std::vector< int > ids;
96 std::vector< int > adjs,
length;
103 if( mbpc->proc_config().proc_rank() == 0 )
119 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
121 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
123 else if( !strcmp( zmethod,
"RIB" ) )
125 else if( !strcmp( zmethod,
"HSFC" ) )
127 else if( !strcmp( zmethod,
"Hypergraph" ) || !strcmp( zmethod,
"PHG" ) )
128 if( NULL == other_method )
132 else if( !strcmp( zmethod,
"PARMETIS" ) )
134 if( NULL == other_method )
139 else if( !strcmp( zmethod,
"OCTPART" ) )
141 if( NULL == other_method )
162 ZOLTAN_ID_PTR importGlobalIds;
163 ZOLTAN_ID_PTR importLocalIds;
167 ZOLTAN_ID_PTR exportGlobalIds;
168 ZOLTAN_ID_PTR exportLocalIds;
172 int rc =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, numImport, importGlobalIds, importLocalIds,
173 importProcs, importToPart, numExport, exportGlobalIds, exportLocalIds, exportProcs,
191 mbFinalizePoints( (
int)ids.size(), numExport, exportLocalIds, exportProcs, &assignment );
193 if( mbpc->proc_config().proc_rank() == 0 )
195 result =
write_partition( mbpc->proc_config().proc_size(), elems, assignment, write_as_sets, write_as_tags );
199 free( (
int*)assignment );
204 myZZ->LB_Free_Part( &importGlobalIds, &importLocalIds, &importProcs, &importToPart );
205 myZZ->LB_Free_Part( &exportGlobalIds, &exportLocalIds, &exportProcs, &exportToPart );
219 std::vector< double >& y,
220 std::vector< double >& z,
221 std::vector< int >& ids,
223 std::vector< int >& dest )
226 int nprocs = mbpc->proc_config().proc_size();
227 int rank = mbpc->proc_config().proc_rank();
230 std::vector< double > pts;
231 pts.resize( x.size() * 3 );
232 for(
size_t i = 0; i < x.size(); i++ )
235 pts[3 * i + 1] = y[i];
236 pts[3 * i + 2] = z[i];
251 if( rank == 0 ) std::cout <<
"Initializing zoltan..." << std::endl;
256 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
258 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
260 else if( !strcmp( zmethod,
"RIB" ) )
262 else if( !strcmp( zmethod,
"HSFC" ) )
267 snprintf( buff, 10,
"%d", nprocs );
268 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
269 if( ZOLTAN_OK != retval )
return MB_FAILURE;
272 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"ALL" );
273 if( ZOLTAN_OK != retval )
return MB_FAILURE;
288 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
292 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
293 int *assign_procs, *assign_parts;
296 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " << nprocs
297 <<
" processors..." << std::endl;
299 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
300 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
301 assign_procs, assign_parts );
303 if( ZOLTAN_OK != retval )
return MB_FAILURE;
307 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
312 for(
int i = 0; i < num_export; i++ )
313 dest[export_local_ids[i]] = assign_procs[i];
316 retval =
myZZ->LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
317 if( ZOLTAN_OK != retval )
return MB_FAILURE;
318 retval =
myZZ->LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
319 if( ZOLTAN_OK != retval )
return MB_FAILURE;
324 std::vector< double >& y,
325 std::vector< double >& z,
331 int nprocs = mbpc->proc_config().proc_size();
332 int rank = mbpc->proc_config().proc_rank();
335 std::vector< double > pts;
336 pts.resize( x.size() * 3 );
337 std::vector< int > ids;
338 ids.resize( x.size() );
339 for(
size_t i = 0; i < x.size(); i++ )
342 pts[3 * i + 1] = y[i];
343 pts[3 * i + 2] = z[i];
344 ids[i] = StartID + (int)i;
359 if( rank == 0 ) std::cout <<
"Initializing zoltan..." << std::endl;
364 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
366 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
368 else if( !strcmp( zmethod,
"RIB" ) )
370 else if( !strcmp( zmethod,
"HSFC" ) )
375 snprintf( buff, 10,
"%d", nprocs );
376 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
377 if( ZOLTAN_OK != retval )
return MB_FAILURE;
380 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"ALL" );
381 if( ZOLTAN_OK != retval )
return MB_FAILURE;
396 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
400 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
401 int *assign_procs, *assign_parts;
404 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " << nprocs
405 <<
" processors..." << std::endl;
407 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
408 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
409 assign_procs, assign_parts );
410 if( ZOLTAN_OK != retval )
return MB_FAILURE;
414 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
418 std::sort( import_global_ids, import_global_ids + num_import, std::greater< int >() );
419 std::sort( export_global_ids, export_global_ids + num_export, std::greater< int >() );
422 Range imported, exported;
423 std::copy( import_global_ids, import_global_ids + num_import,
range_inserter( imported ) );
424 std::copy( export_global_ids, export_global_ids + num_export,
range_inserter( exported ) );
425 localGIDs =
subtract( iniGids, exported );
426 localGIDs =
unite( localGIDs, imported );
428 retval =
myZZ->LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
429 if( ZOLTAN_OK != retval )
return MB_FAILURE;
430 retval =
myZZ->LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
431 if( ZOLTAN_OK != retval )
return MB_FAILURE;
439 const bool write_as_sets,
440 int projection_type )
447 std::vector< double > elcoords( elverts.
size() * 3 );
450 std::vector< std::vector< EntityHandle > > part_assignments( num_parts );
454 for(
size_t iel = 0; iel < elverts.
size(); iel++ )
457 double* ecoords = &elcoords[iel * 3];
460 if( projection_type > 0 ) IntxUtils::transform_coordinates( ecoords, projection_type );
463 myZZ->LB_Point_PP_Assign( ecoords, proc, part );
466 part_assignments[part].push_back( elverts[iel] );
470 Tag part_set_tag = mbpc->partition_tag();
477 Interface::UNION );
RR;
481 size_t nparts_assigned = 0;
482 for(
size_t partnum = 0; partnum < num_parts; ++partnum )
484 std::vector< EntityHandle >& partvec = part_assignments[partnum];
486 nparts_assigned += ( partvec.size() ? 1 : 0 );
499 int ipartnum = (int)partnum;
508 std::vector< int > assignment( partvec.size(),
514 if( nparts_assigned != num_parts )
516 std::cout <<
"WARNING: The inference yielded lesser number of parts (" << nparts_assigned
517 <<
") than requested by user (" << num_parts <<
").\n";
526 const char* other_method,
529 const bool write_as_sets,
530 const bool write_as_tags,
531 const int obj_weight,
532 const int edge_weight,
533 const int projection_type,
534 const bool recompute_rcb_box,
538 if( mbpc->proc_config().proc_size() != 1 )
540 std::cout <<
"ZoltanPartitioner::partition_mesh_and_geometry must be called in serial." << std::endl;
544 if( NULL != zmethod && strcmp( zmethod,
"RR" ) && strcmp( zmethod,
"RCB" ) && strcmp( zmethod,
"RIB" ) &&
545 strcmp( zmethod,
"HSFC" ) && strcmp( zmethod,
"Hypergraph" ) && strcmp( zmethod,
"PHG" ) &&
546 strcmp( zmethod,
"PARMETIS" ) && strcmp( zmethod,
"OCTPART" ) )
548 std::cout <<
"ERROR node " << mbpc->proc_config().proc_rank() <<
": Method must be "
549 <<
"RCB, RIB, HSFC, Hypergraph (PHG), PARMETIS, or OCTPART" << std::endl;
553 bool part_geom =
false;
554 if( 0 == strcmp( zmethod,
"RR" ) || 0 == strcmp( zmethod,
"RCB" ) || 0 == strcmp( zmethod,
"RIB" ) ||
555 0 == strcmp( zmethod,
"HSFC" ) )
557 std::vector< double > pts;
558 std::vector< int > ids;
559 std::vector< int > adjs,
length, parts;
560 std::vector< double > obj_weights, edge_weights;
568 if( !strcmp( zmethod,
"RR" ) )
570 if( part_geom_mesh_size < 0. )
574 if( elems.
empty() )
return MB_FAILURE;
576 std::vector< int > assign_vec( elems.
size() );
579 if( extra ) num_per++;
581 for(
int i = 0; i <
nparts; i++ )
583 if( i == extra ) num_per--;
584 std::fill( &assign_vec[nstart], &assign_vec[nstart + num_per], i );
597 std::cout <<
"Assembling graph..." << std::endl;
599 if( part_geom_mesh_size < 0. )
606 MB_CHK_SET_ERR( MB_FAILURE,
"Geometry partitions not supported.\n" );
610 std::cout <<
" time to assemble graph: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
613 double* o_wgt = NULL;
614 double* e_wgt = NULL;
615 if( obj_weights.size() > 0 ) o_wgt = &obj_weights[0];
616 if( edge_weights.size() > 0 ) e_wgt = &edge_weights[0];
627 std::cout <<
" time to initialize points: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
632 std::cout <<
"Initializing zoltan..." << std::endl;
637 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
639 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
641 else if( !strcmp( zmethod,
"RIB" ) )
643 else if( !strcmp( zmethod,
"HSFC" ) )
645 else if( !strcmp( zmethod,
"Hypergraph" ) || !strcmp( zmethod,
"PHG" ) )
647 if( NULL == other_method || ( other_method[0] ==
'\0' ) )
654 std::ostringstream str;
656 myZZ->Set_Param(
"IMBALANCE_TOL", str.str().c_str() );
659 else if( !strcmp( zmethod,
"PARMETIS" ) )
661 if( NULL == other_method )
666 else if( !strcmp( zmethod,
"OCTPART" ) )
668 if( NULL == other_method )
676 snprintf( buff, 10,
"%d",
nparts );
677 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
678 if( ZOLTAN_OK != retval )
return MB_FAILURE;
681 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"PARTITION ASSIGNMENTS" );
682 if( ZOLTAN_OK != retval )
return MB_FAILURE;
686 std::ostringstream str;
688 retval =
myZZ->Set_Param(
"OBJ_WEIGHT_DIM", str.str().c_str() );
689 if( ZOLTAN_OK != retval )
return MB_FAILURE;
692 if( edge_weight > 0 )
694 std::ostringstream str;
696 retval =
myZZ->Set_Param(
"EDGE_WEIGHT_DIM", str.str().c_str() );
697 if( ZOLTAN_OK != retval )
return MB_FAILURE;
708 if( part_geom_mesh_size > 0. )
719 ZOLTAN_ID_PTR dum_local, dum_global;
722 ZOLTAN_ID_PTR assign_gid, assign_lid;
723 int *assign_procs, *assign_parts;
725 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " <<
nparts
726 <<
" processors..." << std::endl;
729 if (NULL == zmethod || !strcmp(zmethod,
"RCB"))
730 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)zmethod, 1, 1, 0, 0);
732 if ( !strcmp(zmethod,
"PHG"))
733 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)zmethod, 1, 0, 1, 1);
736 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, dumnum1, dum_global, dum_local, dum1, dum2,
737 num_assign, assign_gid, assign_lid, assign_procs, assign_parts );
738 if( ZOLTAN_OK != retval )
return MB_FAILURE;
742 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
746 std::cout <<
"Saving partition information to MOAB..." << std::endl;
748 if( part_geom_mesh_size < 0. )
755 MB_CHK_SET_ERR( MB_FAILURE,
"Geometry partitions not supported.\n" );
760 std::cout <<
" time to write partition in memory " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
767 myZZ->LB_Free_Part( &assign_gid, &assign_lid, &assign_procs, &assign_parts );
777 std::cout <<
"Adding closure..." << std::endl;
785 if( ents.
empty() )
continue;
804 Range sets, part_ents;
821 if( !int_range.
empty() )
841 std::vector< double >& coords,
842 std::vector< int >& moab_ids,
843 std::vector< int >& adjacencies,
844 std::vector< int >&
length,
847 int projection_type )
860 result = mbpc->assign_global_ids( rootset, dimension, 1,
true,
true );
RR;
870 double avg_position[3];
894 std::copy( neighbors, neighbors + adjs.
size(), std::back_inserter( adjacencies ) );
904 moab_ids.push_back( moab_id );
906 if( projection_type > 0 ) IntxUtils::transform_coordinates( avg_position, projection_type );
908 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
913 std::cout <<
"Length vector: " << std::endl;
914 std::copy(
length.begin(),
length.end(), std::ostream_iterator< int >( std::cout,
", " ) );
915 std::cout << std::endl;
916 std::cout <<
"Adjacencies vector: " << std::endl;
917 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< int >( std::cout,
", " ) );
918 std::cout << std::endl;
919 std::cout <<
"Moab_ids vector: " << std::endl;
920 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< int >( std::cout,
", " ) );
921 std::cout << std::endl;
922 std::cout <<
"Coords vector: " << std::endl;
923 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
924 std::cout << std::endl;
932 const int* assignment,
933 const bool write_as_sets,
934 const bool write_as_tags )
948 if( !tagged_sets.
empty() )
966 for( i = 0; i < num_new; i++ )
970 tagged_sets.
insert( new_set );
977 for( i = 0; i < num_del; i++ )
988 int* dum_ids =
new int[
nparts];
989 for( i = 0; i <
nparts; i++ )
998 std::vector< EntityHandle > tmp_part_sets;
1009 for( i = 0, rit = elems.
begin(); rit != elems.
end(); ++rit, i++ )
1026 if( !empty_sets.
empty() )
1028 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
1029 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); ++rit )
1030 std::cout << *rit <<
" ";
1031 std::cout << std::endl;
1046 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nRecursive Coordinate Bisection" << std::endl;
1049 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1050 myZZ->Set_Param(
"LB_METHOD",
"RCB" );
1055 myZZ->Set_Param(
"RCB_OUTPUT_LEVEL",
"1" );
1056 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1058 if( recompute_rcb_box )
myZZ->Set_Param(
"RCB_RECOMPUTE_BOX",
"1" );
1063 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nRecursive Inertial Bisection" << std::endl;
1066 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1067 myZZ->Set_Param(
"LB_METHOD",
"RIB" );
1071 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1072 myZZ->Set_Param(
"AVERAGE_CUTS",
"1" );
1077 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nHilbert Space Filling Curve" << std::endl;
1080 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1081 myZZ->Set_Param(
"LB_METHOD",
"HSFC" );
1085 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1090 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nHypergraph (or PHG): " << std::endl;
1093 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1094 myZZ->Set_Param(
"LB_METHOD",
"Hypergraph" );
1097 myZZ->Set_Param(
"PHG_COARSEPARTITION_METHOD", phg_method );
1102 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nPARMETIS: " << parmetis_method << std::endl;
1105 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1106 myZZ->Set_Param(
"LB_METHOD",
"PARMETIS" );
1110 myZZ->Set_Param(
"PARMETIS_METHOD", parmetis_method );
1115 if( mbpc->proc_config().proc_rank() == 0 ) std::cout <<
"\nOctree Partitioning: " << oct_method << std::endl;
1118 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1119 myZZ->Set_Param(
"LB_METHOD",
"OCTPART" );
1123 myZZ->Set_Param(
"OCT_METHOD", oct_method );
1124 myZZ->Set_Param(
"OCT_OUTPUT_LEVEL",
"3" );
1132 double* obj_weights,
1133 double* edge_weights,
1139 int *numPts, *nborProcs = NULL;
1140 int sum, ptsPerProc, ptsAssigned, mySize;
1144 int* sendEdges = NULL;
1145 int* sendNborId = NULL;
1148 if( mbpc->proc_config().proc_rank() == 0 )
1152 numPts = (
int*)malloc(
sizeof(
int ) * mbpc->proc_config().proc_size() );
1153 ptsPerProc = npts / mbpc->proc_config().proc_size();
1156 for( i = 0; i < mbpc->proc_config().proc_size() - 1; i++ )
1158 numPts[i] = ptsPerProc;
1159 ptsAssigned += ptsPerProc;
1162 numPts[mbpc->proc_config().proc_size() - 1] = npts - ptsAssigned;
1164 mySize = numPts[mbpc->proc_config().proc_rank()];
1165 sendPts = pts + ( 3 * numPts[0] );
1166 sendIds = ids + numPts[0];
1170 sendEdges =
length + numPts[0];
1172 for( j = 0; j < numPts[0]; j++ )
1175 sendNborId = adjs +
sum;
1177 for( j = numPts[0]; j < npts; j++ )
1180 nborProcs = (
int*)malloc(
sizeof(
int ) *
sum );
1182 for( j = 0; j <
sum; j++ )
1183 if( ( i = adjs[j] / ptsPerProc ) < mbpc->proc_config().proc_size() )
1186 nborProcs[j] = mbpc->proc_config().proc_size() - 1;
1188 sendProcs = nborProcs + ( sendNborId - adjs );
1190 for( i = 1; i < mbpc->proc_config().proc_size(); i++ )
1192 MPI_Send( &numPts[i], 1, MPI_INT, i, 0x00, mbpc->comm() );
1193 MPI_Send( sendPts, 3 * numPts[i], MPI_DOUBLE, i, 0x01, mbpc->comm() );
1194 MPI_Send( sendIds, numPts[i], MPI_INT, i, 0x03, mbpc->comm() );
1195 MPI_Send( sendEdges, numPts[i], MPI_INT, i, 0x06, mbpc->comm() );
1198 for( j = 0; j < numPts[i]; j++ )
1199 sum += sendEdges[j];
1201 MPI_Send( sendNborId,
sum, MPI_INT, i, 0x07, mbpc->comm() );
1202 MPI_Send( sendProcs,
sum, MPI_INT, i, 0x08, mbpc->comm() );
1203 sendPts += ( 3 * numPts[i] );
1204 sendIds += numPts[i];
1205 sendEdges += numPts[i];
1214 MPI_Recv( &mySize, 1, MPI_INT, 0, 0x00, mbpc->comm(), &stat );
1215 pts = (
double*)malloc(
sizeof(
double ) * 3 * mySize );
1216 ids = (
int*)malloc(
sizeof(
int ) * mySize );
1217 length = (
int*)malloc(
sizeof(
int ) * mySize );
1218 if( obj_weights != NULL ) obj_weights = (
double*)malloc(
sizeof(
double ) * mySize );
1219 MPI_Recv( pts, 3 * mySize, MPI_DOUBLE, 0, 0x01, mbpc->comm(), &stat );
1220 MPI_Recv( ids, mySize, MPI_INT, 0, 0x03, mbpc->comm(), &stat );
1221 MPI_Recv(
length, mySize, MPI_INT, 0, 0x06, mbpc->comm(), &stat );
1224 for( j = 0; j < mySize; j++ )
1227 adjs = (
int*)malloc(
sizeof(
int ) *
sum );
1228 if( edge_weights != NULL ) edge_weights = (
double*)malloc(
sizeof(
double ) *
sum );
1229 nborProcs = (
int*)malloc(
sizeof(
int ) *
sum );
1230 MPI_Recv( adjs,
sum, MPI_INT, 0, 0x07, mbpc->comm(), &stat );
1231 MPI_Recv( nborProcs,
sum, MPI_INT, 0, 0x08, mbpc->comm(), &stat );
1249 ZOLTAN_ID_PTR exportLocalIDs,
1261 if( mbpc->proc_config().proc_rank() == 0 )
1262 MyAssignment = (
int*)malloc(
sizeof(
int ) * npts );
1264 MyAssignment = (
int*)malloc(
sizeof(
int ) *
NumPoints );
1267 MyAssignment[i] = mbpc->proc_config().proc_rank();
1269 for( i = 0; i < numExport; i++ )
1270 MyAssignment[exportLocalIDs[i]] = exportProcs[i];
1272 if( mbpc->proc_config().proc_rank() == 0 )
1277 for( i = 1; i < (int)mbpc->proc_config().proc_size(); i++ )
1279 MPI_Recv( &numPts, 1, MPI_INT, i, 0x04, mbpc->comm(), &stat );
1280 MPI_Recv( recvA, numPts, MPI_INT, i, 0x05, mbpc->comm(), &stat );
1284 *assignment = MyAssignment;
1288 MPI_Send( &
NumPoints, 1, MPI_INT, 0, 0x04, mbpc->comm() );
1289 MPI_Send( MyAssignment,
NumPoints, MPI_INT, 0, 0x05, mbpc->comm() );
1290 free( MyAssignment );
1298 int* vals = (
int*)malloc( mbpc->proc_config().proc_size() *
sizeof( int ) );
1300 MPI_Allgather( &rc, 1, MPI_INT, vals, 1, MPI_INT, mbpc->comm() );
1302 for( i = 0; i < mbpc->proc_config().proc_size(); i++ )
1304 if( vals[i] != ZOLTAN_OK )
1306 if( 0 == mbpc->proc_config().proc_rank() )
1321 int* v1 = (
int*)malloc( 4 *
sizeof(
int ) );
1330 if( mbpc->proc_config().proc_rank() == 0 )
1332 v2 = (
int*)malloc( 4 * mbpc->proc_config().proc_size() *
sizeof( int ) );
1335 MPI_Gather( v1, 4, MPI_INT, v2, 4, MPI_INT, 0, mbpc->comm() );
1337 if( mbpc->proc_config().proc_rank() == 0 )
1339 fprintf( stdout,
"======%s======\n", s );
1340 for( i = 0, v = v2; i < mbpc->proc_config().proc_size(); i++, v += 4 )
1342 fprintf( stdout,
"%u: originally had %d, import %d, exp %d, %s\n", i, v[0], v[1], v[2],
1343 v[3] ?
"a change of partitioning" :
"no change" );
1345 fprintf( stdout,
"==========================================\n" );
1356 if( s ) printf(
"%s ", s );
1361 printf(
"%d: SUCCESSFUL\n", mbpc->proc_config().proc_rank() );
1364 printf(
"%d: WARNING\n", mbpc->proc_config().proc_rank() );
1367 printf(
"%d: FATAL ERROR\n", mbpc->proc_config().proc_rank() );
1370 printf(
"%d: MEMORY ALLOCATION ERROR\n", mbpc->proc_config().proc_rank() );
1373 printf(
"%d: INVALID RETURN CODE\n", mbpc->proc_config().proc_rank() );
1401 if( wgt_dim > 0 ) obj_wgts[i] =
ObjWeights[i];
1432 for( i = 0; i < numObjs; i++ )
1444 pts[next++] =
Points[id3];
1445 pts[next++] =
Points[id3 + 1];
1446 pts[next++] =
Points[id3 + 2];
1462 for( i = 0; i < numObjs; i++ )
1483 ZOLTAN_ID_PTR nborGlobalIds,
1489 int i, id, idSum, j;
1492 for( i = 0; i < numObjs; i++ )
1504 for( j = 0; j < id; j++ )
1507 for( j = 0; j <
NumEdges[id]; j++ )
1511 if( wgt_dim > 0 ) edge_wgts[next] =
EdgeWeights[idSum];
1530 for( i = 0; i < numObjs; i++ )
1540 part[next++] =
Parts[id];
1546 std::multimap< int, int >& extraGraphEdges,
1547 std::map< int, int > procs,
1548 int& numNewPartitions,
1549 std::map< int, Range >& distribution,
1556 std::vector< int > adjacencies;
1557 std::vector< int > ids;
1558 ids.resize( primary.
size() );
1559 std::vector< int >
length;
1560 std::vector< double > coords;
1561 std::vector< int > nbor_proc;
1566 double avg_position[3];
1575 int rank = mbpc->rank();
1593 int size_adjs = (int)adjs.
size();
1595 for(
int k = 0; k < size_adjs; k++ )
1596 neib_proc[k] = rank;
1597 if( extraGraphEdges.find( moab_id ) != extraGraphEdges.end() )
1601 std::pair< std::multimap< int, int >::iterator, std::multimap< int, int >::iterator > ret;
1602 ret = extraGraphEdges.equal_range( moab_id );
1603 for( std::multimap< int, int >::iterator it = ret.first; it != ret.second; ++it )
1605 int otherID = it->second;
1606 neighbors[size_adjs] = otherID;
1607 neib_proc[size_adjs] = procs[otherID];
1613 length.push_back( size_adjs );
1614 std::copy( neighbors, neighbors + size_adjs, std::back_inserter( adjacencies ) );
1615 std::copy( neib_proc, neib_proc + size_adjs, std::back_inserter( nbor_proc ) );
1627 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
1632 std::stringstream ff2;
1633 ff2 <<
"zoltanInput_" << mbpc->rank() <<
".txt";
1635 ofs.open( ff2.str().c_str(), std::ofstream::out );
1636 ofs <<
"Length vector: " << std::endl;
1637 std::copy(
length.begin(),
length.end(), std::ostream_iterator< int >( ofs,
", " ) );
1639 ofs <<
"Adjacencies vector: " << std::endl;
1640 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< int >( ofs,
", " ) );
1642 ofs <<
"Moab_ids vector: " << std::endl;
1643 std::copy( ids.begin(), ids.end(), std::ostream_iterator< int >( ofs,
", " ) );
1645 ofs <<
"Coords vector: " << std::endl;
1646 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( ofs,
", " ) );
1653 if( 1 != met )
Points = &coords[0];
1664 if( mbpc->rank() == 0 ) std::cout <<
"Initializing zoltan..." << std::endl;
1669 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
1673 snprintf( buff, 10,
"%d", numNewPartitions );
1674 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
1675 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1678 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"PARTS" );
1679 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1703 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
1705 int* import_to_part;
1707 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
1708 int *assign_procs, *assign_parts;
1710 if( mbpc->rank() == 0 )
1711 std::cout <<
"Computing partition using method (1-graph, 2-geom):" << met <<
" for " << numNewPartitions
1712 <<
" parts..." << std::endl;
1716 static int counter=0;
1719 std::stringstream basename;
1722 basename <<
"phg_" << counter++;
1723 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)(basename.str().c_str()), 1, 0, 1, 0);
1727 basename <<
"rcb_" << counter++;
1728 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)(basename.str().c_str()), 1, 1, 0, 0);
1732 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
1733 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
1734 assign_procs, assign_parts );
1735 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1738 std::stringstream ff3;
1739 ff3 <<
"zoltanOutput_" << mbpc->rank() <<
".txt";
1741 ofs3.open( ff3.str().c_str(), std::ofstream::out );
1742 ofs3 <<
" export elements on rank " << rank <<
" \n";
1743 ofs3 <<
"\t index \t gb_id \t local \t proc \t part \n";
1744 for(
int k = 0; k < num_export; k++ )
1746 ofs3 <<
"\t" << k <<
"\t" << export_global_ids[k] <<
"\t" << export_local_ids[k] <<
"\t" << assign_procs[k]
1747 <<
"\t" << assign_parts[k] <<
"\n";
1754 assert( num_export == (
int)primary.
size() );
1755 for( i = 0; i < num_export; i++ )
1758 distribution[assign_parts[i]].
insert( cell );
1761 Zoltan::LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
1762 Zoltan::LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
1769 std::vector< int >().swap( adjacencies );
1770 std::vector< int >().swap( ids );
1771 std::vector< int >().swap(
length );
1772 std::vector< int >().swap( nbor_proc );
1773 std::vector< double >().swap( coords );