42 if( MB_SUCCESS != result ) return result
60 const bool use_coords,
70 myZZ( NULL ), myNumPts( 0 ), argcArg( argc ), argvArg( argv )
80 const char* other_method,
81 const bool write_as_sets,
82 const bool write_as_tags )
84 if( !strcmp( zmethod,
"RR" ) && !strcmp( zmethod,
"RCB" ) && !strcmp( zmethod,
"RIB" ) &&
85 !strcmp( zmethod,
"HSFC" ) && !strcmp( zmethod,
"Hypergraph" ) && !strcmp( zmethod,
"PHG" ) &&
86 !strcmp( zmethod,
"PARMETIS" ) && !strcmp( zmethod,
"OCTPART" ) )
88 std::cout <<
"ERROR node " << mbpc->proc_config().proc_rank() <<
": Method must be "
89 <<
"RR, RCB, RIB, HSFC, Hypergraph (PHG), PARMETIS, or OCTPART" << std::endl;
93 std::vector< double > pts;
94 std::vector< int > ids;
95 std::vector< int > adjs,
length;
102 if( mbpc->proc_config().proc_rank() == 0 )
118 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
120 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
122 else if( !strcmp( zmethod,
"RIB" ) )
124 else if( !strcmp( zmethod,
"HSFC" ) )
126 else if( !strcmp( zmethod,
"Hypergraph" ) || !strcmp( zmethod,
"PHG" ) )
127 if( NULL == other_method )
131 else if( !strcmp( zmethod,
"PARMETIS" ) )
133 if( NULL == other_method )
138 else if( !strcmp( zmethod,
"OCTPART" ) )
140 if( NULL == other_method )
161 ZOLTAN_ID_PTR importGlobalIds;
162 ZOLTAN_ID_PTR importLocalIds;
166 ZOLTAN_ID_PTR exportGlobalIds;
167 ZOLTAN_ID_PTR exportLocalIds;
171 int rc =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, numImport, importGlobalIds, importLocalIds,
172 importProcs, importToPart, numExport, exportGlobalIds, exportLocalIds, exportProcs,
190 mbFinalizePoints( (
int)ids.size(), numExport, exportLocalIds, exportProcs, &assignment );
192 if( mbpc->proc_config().proc_rank() == 0 )
194 result =
write_partition( mbpc->proc_config().proc_size(), elems, assignment, write_as_sets, write_as_tags );
198 free( (
int*)assignment );
203 myZZ->LB_Free_Part( &importGlobalIds, &importLocalIds, &importProcs, &importToPart );
204 myZZ->LB_Free_Part( &exportGlobalIds, &exportLocalIds, &exportProcs, &exportToPart );
218 std::vector< double >& y,
219 std::vector< double >& z,
220 std::vector< int >& ids,
222 std::vector< int >& dest )
225 int nprocs = mbpc->proc_config().proc_size();
226 int rank = mbpc->proc_config().proc_rank();
229 std::vector< double > pts;
230 pts.resize( x.size() * 3 );
231 for(
size_t i = 0; i < x.size(); i++ )
234 pts[3 * i + 1] = y[i];
235 pts[3 * i + 2] = z[i];
250 if( rank == 0 ) std::cout <<
"Initializing zoltan..." << std::endl;
255 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
257 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
259 else if( !strcmp( zmethod,
"RIB" ) )
261 else if( !strcmp( zmethod,
"HSFC" ) )
266 snprintf( buff, 10,
"%d", nprocs );
267 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
268 if( ZOLTAN_OK != retval )
return MB_FAILURE;
271 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"ALL" );
272 if( ZOLTAN_OK != retval )
return MB_FAILURE;
287 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
291 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
292 int *assign_procs, *assign_parts;
295 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " << nprocs
296 <<
" processors..." << std::endl;
298 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
299 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
300 assign_procs, assign_parts );
302 if( ZOLTAN_OK != retval )
return MB_FAILURE;
306 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
311 for(
int i = 0; i < num_export; i++ )
312 dest[export_local_ids[i]] = assign_procs[i];
315 retval =
myZZ->LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
316 if( ZOLTAN_OK != retval )
return MB_FAILURE;
317 retval =
myZZ->LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
318 if( ZOLTAN_OK != retval )
return MB_FAILURE;
323 std::vector< double >& y,
324 std::vector< double >& z,
330 int nprocs = mbpc->proc_config().proc_size();
331 int rank = mbpc->proc_config().proc_rank();
334 std::vector< double > pts;
335 pts.resize( x.size() * 3 );
336 std::vector< int > ids;
337 ids.resize( x.size() );
338 for(
size_t i = 0; i < x.size(); i++ )
341 pts[3 * i + 1] = y[i];
342 pts[3 * i + 2] = z[i];
343 ids[i] = StartID + (int)i;
358 if( rank == 0 ) std::cout <<
"Initializing zoltan..." << std::endl;
363 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
365 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
367 else if( !strcmp( zmethod,
"RIB" ) )
369 else if( !strcmp( zmethod,
"HSFC" ) )
374 snprintf( buff, 10,
"%d", nprocs );
375 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
376 if( ZOLTAN_OK != retval )
return MB_FAILURE;
379 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"ALL" );
380 if( ZOLTAN_OK != retval )
return MB_FAILURE;
395 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
399 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
400 int *assign_procs, *assign_parts;
403 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " << nprocs
404 <<
" processors..." << std::endl;
406 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
407 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
408 assign_procs, assign_parts );
409 if( ZOLTAN_OK != retval )
return MB_FAILURE;
413 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
417 std::sort( import_global_ids, import_global_ids + num_import, std::greater< int >() );
418 std::sort( export_global_ids, export_global_ids + num_export, std::greater< int >() );
421 Range imported, exported;
422 std::copy( import_global_ids, import_global_ids + num_import,
range_inserter( imported ) );
423 std::copy( export_global_ids, export_global_ids + num_export,
range_inserter( exported ) );
424 localGIDs =
subtract( iniGids, exported );
425 localGIDs =
unite( localGIDs, imported );
427 retval =
myZZ->LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
428 if( ZOLTAN_OK != retval )
return MB_FAILURE;
429 retval =
myZZ->LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
430 if( ZOLTAN_OK != retval )
return MB_FAILURE;
438 const bool write_as_sets,
439 int projection_type )
446 std::vector< double > elcoords( elverts.
size() * 3 );
449 std::vector< std::vector< EntityHandle > > part_assignments( num_parts );
453 for(
size_t iel = 0; iel < elverts.
size(); iel++ )
456 double* ecoords = &elcoords[iel * 3];
459 if( projection_type > 0 ) IntxUtils::transform_coordinates( ecoords, projection_type );
462 myZZ->LB_Point_PP_Assign( ecoords, proc, part );
465 part_assignments[part].push_back( elverts[iel] );
469 Tag part_set_tag = mbpc->partition_tag();
476 Interface::UNION );
RR;
480 size_t nparts_assigned = 0;
481 for(
size_t partnum = 0; partnum < num_parts; ++partnum )
483 std::vector< EntityHandle >& partvec = part_assignments[partnum];
485 nparts_assigned += ( partvec.size() ? 1 : 0 );
498 int ipartnum = (int)partnum;
507 std::vector< int > assignment( partvec.size(),
513 if( nparts_assigned != num_parts )
515 std::cout <<
"WARNING: The inference yielded lesser number of parts (" << nparts_assigned
516 <<
") than requested by user (" << num_parts <<
").\n";
525 const char* other_method,
528 const bool write_as_sets,
529 const bool write_as_tags,
530 const int obj_weight,
531 const int edge_weight,
532 const int projection_type,
533 const bool recompute_rcb_box,
537 if( mbpc->proc_config().proc_size() != 1 )
539 std::cout <<
"ZoltanPartitioner::partition_mesh_and_geometry must be called in serial." << std::endl;
543 if( NULL != zmethod && strcmp( zmethod,
"RR" ) && strcmp( zmethod,
"RCB" ) && strcmp( zmethod,
"RIB" ) &&
544 strcmp( zmethod,
"HSFC" ) && strcmp( zmethod,
"Hypergraph" ) && strcmp( zmethod,
"PHG" ) &&
545 strcmp( zmethod,
"PARMETIS" ) && strcmp( zmethod,
"OCTPART" ) )
547 std::cout <<
"ERROR node " << mbpc->proc_config().proc_rank() <<
": Method must be "
548 <<
"RCB, RIB, HSFC, Hypergraph (PHG), PARMETIS, or OCTPART" << std::endl;
552 bool part_geom =
false;
553 if( 0 == strcmp( zmethod,
"RR" ) || 0 == strcmp( zmethod,
"RCB" ) || 0 == strcmp( zmethod,
"RIB" ) ||
554 0 == strcmp( zmethod,
"HSFC" ) )
556 std::vector< double > pts;
557 std::vector< int > ids;
558 std::vector< int > adjs,
length, parts;
559 std::vector< double > obj_weights, edge_weights;
567 if( !strcmp( zmethod,
"RR" ) )
569 if( part_geom_mesh_size < 0. )
573 if( elems.
empty() )
return MB_FAILURE;
575 std::vector< int > assign_vec( elems.
size() );
578 if( extra ) num_per++;
580 for(
int i = 0; i <
nparts; i++ )
582 if( i == extra ) num_per--;
583 std::fill( &assign_vec[nstart], &assign_vec[nstart + num_per], i );
596 std::cout <<
"Assembling graph..." << std::endl;
598 if( part_geom_mesh_size < 0. )
605 MB_CHK_SET_ERR( MB_FAILURE,
"Geometry partitions not supported.\n" );
609 std::cout <<
" time to assemble graph: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
612 double* o_wgt = NULL;
613 double* e_wgt = NULL;
614 if( obj_weights.size() > 0 ) o_wgt = &obj_weights[0];
615 if( edge_weights.size() > 0 ) e_wgt = &edge_weights[0];
626 std::cout <<
" time to initialize points: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
631 std::cout <<
"Initializing zoltan..." << std::endl;
636 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
638 if( NULL == zmethod || !strcmp( zmethod,
"RCB" ) )
640 else if( !strcmp( zmethod,
"RIB" ) )
642 else if( !strcmp( zmethod,
"HSFC" ) )
644 else if( !strcmp( zmethod,
"Hypergraph" ) || !strcmp( zmethod,
"PHG" ) )
646 if( NULL == other_method || ( other_method[0] ==
'\0' ) )
653 std::ostringstream str;
655 myZZ->Set_Param(
"IMBALANCE_TOL", str.str().c_str() );
658 else if( !strcmp( zmethod,
"PARMETIS" ) )
660 if( NULL == other_method )
665 else if( !strcmp( zmethod,
"OCTPART" ) )
667 if( NULL == other_method )
675 snprintf( buff, 10,
"%d",
nparts );
676 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
677 if( ZOLTAN_OK != retval )
return MB_FAILURE;
680 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"PARTITION ASSIGNMENTS" );
681 if( ZOLTAN_OK != retval )
return MB_FAILURE;
685 std::ostringstream str;
687 retval =
myZZ->Set_Param(
"OBJ_WEIGHT_DIM", str.str().c_str() );
688 if( ZOLTAN_OK != retval )
return MB_FAILURE;
691 if( edge_weight > 0 )
693 std::ostringstream str;
695 retval =
myZZ->Set_Param(
"EDGE_WEIGHT_DIM", str.str().c_str() );
696 if( ZOLTAN_OK != retval )
return MB_FAILURE;
707 if( part_geom_mesh_size > 0. )
718 ZOLTAN_ID_PTR dum_local, dum_global;
721 ZOLTAN_ID_PTR assign_gid, assign_lid;
722 int *assign_procs, *assign_parts;
724 std::cout <<
"Computing partition using " << ( zmethod ? zmethod :
"RCB" ) <<
" method for " <<
nparts
725 <<
" processors..." << std::endl;
728 if (NULL == zmethod || !strcmp(zmethod,
"RCB"))
729 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)zmethod, 1, 1, 0, 0);
731 if ( !strcmp(zmethod,
"PHG"))
732 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)zmethod, 1, 0, 1, 1);
735 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, dumnum1, dum_global, dum_local, dum1, dum2,
736 num_assign, assign_gid, assign_lid, assign_procs, assign_parts );
737 if( ZOLTAN_OK != retval )
return MB_FAILURE;
741 std::cout <<
" time to LB_partition " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
745 std::cout <<
"Saving partition information to MOAB..." << std::endl;
747 if( part_geom_mesh_size < 0. )
754 MB_CHK_SET_ERR( MB_FAILURE,
"Geometry partitions not supported.\n" );
759 std::cout <<
" time to write partition in memory " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
766 myZZ->LB_Free_Part( &assign_gid, &assign_lid, &assign_procs, &assign_parts );
776 std::cout <<
"Adding closure..." << std::endl;
784 if( ents.
empty() )
continue;
803 Range sets, part_ents;
820 if( !int_range.
empty() )
840 std::vector< double >& coords,
841 std::vector< int >& moab_ids,
842 std::vector< int >& adjacencies,
843 std::vector< int >&
length,
846 int projection_type )
859 result = mbpc->assign_global_ids( rootset, dimension, 1,
true,
true );
RR;
869 double avg_position[3];
893 std::copy( neighbors, neighbors + adjs.
size(), std::back_inserter( adjacencies ) );
903 moab_ids.push_back( moab_id );
905 if( projection_type > 0 ) IntxUtils::transform_coordinates( avg_position, projection_type );
907 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
912 std::cout <<
"Length vector: " << std::endl;
913 std::copy(
length.begin(),
length.end(), std::ostream_iterator< int >( std::cout,
", " ) );
914 std::cout << std::endl;
915 std::cout <<
"Adjacencies vector: " << std::endl;
916 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< int >( std::cout,
", " ) );
917 std::cout << std::endl;
918 std::cout <<
"Moab_ids vector: " << std::endl;
919 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< int >( std::cout,
", " ) );
920 std::cout << std::endl;
921 std::cout <<
"Coords vector: " << std::endl;
922 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
923 std::cout << std::endl;
931 const int* assignment,
932 const bool write_as_sets,
933 const bool write_as_tags )
947 if( !tagged_sets.
empty() )
965 for( i = 0; i < num_new; i++ )
969 tagged_sets.
insert( new_set );
976 for( i = 0; i < num_del; i++ )
987 int* dum_ids =
new int[
nparts];
988 for( i = 0; i <
nparts; i++ )
997 std::vector< EntityHandle > tmp_part_sets;
1008 for( i = 0, rit = elems.
begin(); rit != elems.
end(); ++rit, i++ )
1025 if( !empty_sets.
empty() )
1027 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
1028 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); ++rit )
1029 std::cout << *rit <<
" ";
1030 std::cout << std::endl;
1045 if( mbpc->proc_config().proc_rank() == 0 )
1046 std::cout <<
"Using Zoltan-RCB (Recursive Coordinate Bisection) repartitioning scheme..." << std::endl;
1049 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1050 myZZ->Set_Param(
"LB_METHOD",
"RCB" );
1053 myZZ->Set_Param(
"RCB_OUTPUT_LEVEL",
"0" );
1054 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1056 if( recompute_rcb_box )
myZZ->Set_Param(
"RCB_RECOMPUTE_BOX",
"1" );
1061 if( mbpc->proc_config().proc_rank() == 0 )
1062 std::cout <<
"Using Zoltan-RIB (Recursive Inertial Bisection) repartitioning scheme..." << std::endl;
1065 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1066 myZZ->Set_Param(
"LB_METHOD",
"RIB" );
1069 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1070 myZZ->Set_Param(
"AVERAGE_CUTS",
"1" );
1075 if( mbpc->proc_config().proc_rank() == 0 )
1076 std::cout <<
"Using Zoltan-HSFC (Hilbert Space Filling Curve) repartitioning scheme..." << std::endl;
1079 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1080 myZZ->Set_Param(
"LB_METHOD",
"HSFC" );
1083 myZZ->Set_Param(
"KEEP_CUTS",
"1" );
1088 if( mbpc->proc_config().proc_rank() == 0 )
1089 std::cout <<
"Using Zoltan-PHG (Hypergraph) repartitioning scheme..." << std::endl;
1092 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1093 myZZ->Set_Param(
"LB_METHOD",
"Hypergraph" );
1096 myZZ->Set_Param(
"PHG_COARSEPARTITION_METHOD", phg_method );
1101 if( mbpc->proc_config().proc_rank() == 0 )
1102 std::cout <<
"Using Zoltan-ParMetis (" << parmetis_method <<
") repartitioning scheme..." << std::endl;
1105 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1106 myZZ->Set_Param(
"LB_METHOD",
"PARMETIS" );
1109 myZZ->Set_Param(
"PARMETIS_METHOD", parmetis_method );
1114 if( mbpc->proc_config().proc_rank() == 0 )
1115 std::cout <<
"Using Zoltan-OctTree (" << oct_method <<
") repartitioning scheme..." << std::endl;
1118 myZZ->Set_Param(
"DEBUG_LEVEL",
"0" );
1119 myZZ->Set_Param(
"LB_METHOD",
"OCTPART" );
1122 myZZ->Set_Param(
"OCT_METHOD", oct_method );
1123 myZZ->Set_Param(
"OCT_OUTPUT_LEVEL",
"3" );
1131 double* obj_weights,
1132 double* edge_weights,
1138 int *numPts, *nborProcs = NULL;
1139 int sum, ptsPerProc, ptsAssigned, mySize;
1143 int* sendEdges = NULL;
1144 int* sendNborId = NULL;
1147 if( mbpc->proc_config().proc_rank() == 0 )
1151 numPts = (
int*)malloc(
sizeof(
int ) * mbpc->proc_config().proc_size() );
1152 ptsPerProc = npts / mbpc->proc_config().proc_size();
1155 for( i = 0; i < mbpc->proc_config().proc_size() - 1; i++ )
1157 numPts[i] = ptsPerProc;
1158 ptsAssigned += ptsPerProc;
1161 numPts[mbpc->proc_config().proc_size() - 1] = npts - ptsAssigned;
1163 mySize = numPts[mbpc->proc_config().proc_rank()];
1164 sendPts = pts + ( 3 * numPts[0] );
1165 sendIds = ids + numPts[0];
1169 sendEdges =
length + numPts[0];
1171 for( j = 0; j < numPts[0]; j++ )
1174 sendNborId = adjs +
sum;
1176 for( j = numPts[0]; j < npts; j++ )
1179 nborProcs = (
int*)malloc(
sizeof(
int ) *
sum );
1181 for( j = 0; j <
sum; j++ )
1182 if( ( i = adjs[j] / ptsPerProc ) < mbpc->proc_config().proc_size() )
1185 nborProcs[j] = mbpc->proc_config().proc_size() - 1;
1187 sendProcs = nborProcs + ( sendNborId - adjs );
1189 for( i = 1; i < mbpc->proc_config().proc_size(); i++ )
1191 MPI_Send( &numPts[i], 1, MPI_INT, i, 0x00, mbpc->comm() );
1192 MPI_Send( sendPts, 3 * numPts[i], MPI_DOUBLE, i, 0x01, mbpc->comm() );
1193 MPI_Send( sendIds, numPts[i], MPI_INT, i, 0x03, mbpc->comm() );
1194 MPI_Send( sendEdges, numPts[i], MPI_INT, i, 0x06, mbpc->comm() );
1197 for( j = 0; j < numPts[i]; j++ )
1198 sum += sendEdges[j];
1200 MPI_Send( sendNborId,
sum, MPI_INT, i, 0x07, mbpc->comm() );
1201 MPI_Send( sendProcs,
sum, MPI_INT, i, 0x08, mbpc->comm() );
1202 sendPts += ( 3 * numPts[i] );
1203 sendIds += numPts[i];
1204 sendEdges += numPts[i];
1213 MPI_Recv( &mySize, 1, MPI_INT, 0, 0x00, mbpc->comm(), &stat );
1214 pts = (
double*)malloc(
sizeof(
double ) * 3 * mySize );
1215 ids = (
int*)malloc(
sizeof(
int ) * mySize );
1216 length = (
int*)malloc(
sizeof(
int ) * mySize );
1217 if( obj_weights != NULL ) obj_weights = (
double*)malloc(
sizeof(
double ) * mySize );
1218 MPI_Recv( pts, 3 * mySize, MPI_DOUBLE, 0, 0x01, mbpc->comm(), &stat );
1219 MPI_Recv( ids, mySize, MPI_INT, 0, 0x03, mbpc->comm(), &stat );
1220 MPI_Recv(
length, mySize, MPI_INT, 0, 0x06, mbpc->comm(), &stat );
1223 for( j = 0; j < mySize; j++ )
1226 adjs = (
int*)malloc(
sizeof(
int ) *
sum );
1227 if( edge_weights != NULL ) edge_weights = (
double*)malloc(
sizeof(
double ) *
sum );
1228 nborProcs = (
int*)malloc(
sizeof(
int ) *
sum );
1229 MPI_Recv( adjs,
sum, MPI_INT, 0, 0x07, mbpc->comm(), &stat );
1230 MPI_Recv( nborProcs,
sum, MPI_INT, 0, 0x08, mbpc->comm(), &stat );
1248 ZOLTAN_ID_PTR exportLocalIDs,
1260 if( mbpc->proc_config().proc_rank() == 0 )
1261 MyAssignment = (
int*)malloc(
sizeof(
int ) * npts );
1263 MyAssignment = (
int*)malloc(
sizeof(
int ) *
NumPoints );
1266 MyAssignment[i] = mbpc->proc_config().proc_rank();
1268 for( i = 0; i < numExport; i++ )
1269 MyAssignment[exportLocalIDs[i]] = exportProcs[i];
1271 if( mbpc->proc_config().proc_rank() == 0 )
1276 for( i = 1; i < (int)mbpc->proc_config().proc_size(); i++ )
1278 MPI_Recv( &numPts, 1, MPI_INT, i, 0x04, mbpc->comm(), &stat );
1279 MPI_Recv( recvA, numPts, MPI_INT, i, 0x05, mbpc->comm(), &stat );
1283 *assignment = MyAssignment;
1287 MPI_Send( &
NumPoints, 1, MPI_INT, 0, 0x04, mbpc->comm() );
1288 MPI_Send( MyAssignment,
NumPoints, MPI_INT, 0, 0x05, mbpc->comm() );
1289 free( MyAssignment );
1297 int* vals = (
int*)malloc( mbpc->proc_config().proc_size() *
sizeof( int ) );
1299 MPI_Allgather( &rc, 1, MPI_INT, vals, 1, MPI_INT, mbpc->comm() );
1301 for( i = 0; i < mbpc->proc_config().proc_size(); i++ )
1303 if( vals[i] != ZOLTAN_OK )
1305 if( 0 == mbpc->proc_config().proc_rank() )
1320 int* v1 = (
int*)malloc( 4 *
sizeof(
int ) );
1329 if( mbpc->proc_config().proc_rank() == 0 )
1331 v2 = (
int*)malloc( 4 * mbpc->proc_config().proc_size() *
sizeof( int ) );
1334 MPI_Gather( v1, 4, MPI_INT, v2, 4, MPI_INT, 0, mbpc->comm() );
1336 if( mbpc->proc_config().proc_rank() == 0 )
1338 fprintf( stdout,
"======%s======\n", s );
1339 for( i = 0, v = v2; i < mbpc->proc_config().proc_size(); i++, v += 4 )
1341 fprintf( stdout,
"%u: originally had %d, import %d, exp %d, %s\n", i, v[0], v[1], v[2],
1342 v[3] ?
"a change of partitioning" :
"no change" );
1344 fprintf( stdout,
"==========================================\n" );
1355 if( s ) printf(
"%s ", s );
1360 printf(
"%d: SUCCESSFUL\n", mbpc->proc_config().proc_rank() );
1363 printf(
"%d: WARNING\n", mbpc->proc_config().proc_rank() );
1366 printf(
"%d: FATAL ERROR\n", mbpc->proc_config().proc_rank() );
1369 printf(
"%d: MEMORY ALLOCATION ERROR\n", mbpc->proc_config().proc_rank() );
1372 printf(
"%d: INVALID RETURN CODE\n", mbpc->proc_config().proc_rank() );
1400 if( wgt_dim > 0 ) obj_wgts[i] =
ObjWeights[i];
1431 for( i = 0; i < numObjs; i++ )
1443 pts[next++] =
Points[id3];
1444 pts[next++] =
Points[id3 + 1];
1445 pts[next++] =
Points[id3 + 2];
1461 for( i = 0; i < numObjs; i++ )
1482 ZOLTAN_ID_PTR nborGlobalIds,
1488 int i, id, idSum, j;
1491 for( i = 0; i < numObjs; i++ )
1503 for( j = 0; j < id; j++ )
1506 for( j = 0; j <
NumEdges[id]; j++ )
1510 if( wgt_dim > 0 ) edge_wgts[next] =
EdgeWeights[idSum];
1529 for( i = 0; i < numObjs; i++ )
1539 part[next++] =
Parts[id];
1545 std::multimap< int, int >& extraGraphEdges,
1546 std::map< int, int > procs,
1547 int& numNewPartitions,
1548 std::map< int, Range >& distribution,
1549 int partition_method )
1555 std::vector< int > adjacencies;
1556 std::vector< int > ids;
1557 ids.resize( primary.
size() );
1558 std::vector< int >
length;
1559 std::vector< double > coords;
1560 std::vector< int > nbor_proc;
1565 double avg_position[3];
1574 int rank = mbpc->rank();
1580 if( 1 == partition_method )
1592 int size_adjs = (int)adjs.
size();
1594 for(
int k = 0; k < size_adjs; k++ )
1595 neib_proc[k] = rank;
1596 if( extraGraphEdges.find( moab_id ) != extraGraphEdges.end() )
1600 std::pair< std::multimap< int, int >::iterator, std::multimap< int, int >::iterator > ret;
1601 ret = extraGraphEdges.equal_range( moab_id );
1602 for( std::multimap< int, int >::iterator it = ret.first; it != ret.second; ++it )
1604 int otherID = it->second;
1605 neighbors[size_adjs] = otherID;
1606 neib_proc[size_adjs] = procs[otherID];
1612 length.push_back( size_adjs );
1613 std::copy( neighbors, neighbors + size_adjs, std::back_inserter( adjacencies ) );
1614 std::copy( neib_proc, neib_proc + size_adjs, std::back_inserter( nbor_proc ) );
1616 else if( 2 == partition_method )
1626 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
1631 std::stringstream ff2;
1632 ff2 <<
"zoltanInput_" << mbpc->rank() <<
".txt";
1634 ofs.open( ff2.str().c_str(), std::ofstream::out );
1635 ofs <<
"Length vector: " << std::endl;
1636 std::copy(
length.begin(),
length.end(), std::ostream_iterator< int >( ofs,
", " ) );
1638 ofs <<
"Adjacencies vector: " << std::endl;
1639 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< int >( ofs,
", " ) );
1641 ofs <<
"Moab_ids vector: " << std::endl;
1642 std::copy( ids.begin(), ids.end(), std::ostream_iterator< int >( ofs,
", " ) );
1644 ofs <<
"Coords vector: " << std::endl;
1645 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( ofs,
", " ) );
1652 if( 1 != partition_method )
Points = &coords[0];
1666 if( NULL ==
myZZ )
myZZ =
new Zoltan( mbpc->comm() );
1670 snprintf( buff, 10,
"%d", numNewPartitions );
1671 int retval =
myZZ->Set_Param(
"NUM_GLOBAL_PARTITIONS", buff );
1672 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1675 retval =
myZZ->Set_Param(
"RETURN_LISTS",
"PARTS" );
1676 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1681 if( 2 == partition_method )
1687 else if( 1 == partition_method )
1700 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
1702 int* import_to_part;
1704 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
1705 int *assign_procs, *assign_parts;
1713 static int counter=0;
1716 std::stringstream basename;
1717 if (1==partition_method)
1719 basename <<
"phg_" << counter++;
1720 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)(basename.str().c_str()), 1, 0, 1, 0);
1722 else if (2==partition_method)
1724 basename <<
"rcb_" << counter++;
1725 Zoltan_Generate_Files(
myZZ->Get_C_Handle(), (
char*)(basename.str().c_str()), 1, 1, 0, 0);
1729 retval =
myZZ->LB_Partition( changes, numGidEntries, numLidEntries, num_import, import_global_ids, import_local_ids,
1730 import_procs, import_to_part, num_export, export_global_ids, export_local_ids,
1731 assign_procs, assign_parts );
1732 if( ZOLTAN_OK != retval )
return MB_FAILURE;
1735 std::stringstream ff3;
1736 ff3 <<
"zoltanOutput_" << mbpc->rank() <<
".txt";
1738 ofs3.open( ff3.str().c_str(), std::ofstream::out );
1739 ofs3 <<
" export elements on rank " << rank <<
" \n";
1740 ofs3 <<
"\t index \t gb_id \t local \t proc \t part \n";
1741 for(
int k = 0; k < num_export; k++ )
1743 ofs3 <<
"\t" << k <<
"\t" << export_global_ids[k] <<
"\t" << export_local_ids[k] <<
"\t" << assign_procs[k]
1744 <<
"\t" << assign_parts[k] <<
"\n";
1751 assert( num_export == (
int)primary.
size() );
1752 for( i = 0; i < num_export; i++ )
1755 distribution[assign_parts[i]].
insert( cell );
1758 Zoltan::LB_Free_Part( &import_global_ids, &import_local_ids, &import_procs, &import_to_part );
1759 Zoltan::LB_Free_Part( &export_global_ids, &export_local_ids, &assign_procs, &assign_parts );
1766 std::vector< int >().swap( adjacencies );
1767 std::vector< int >().swap( ids );
1768 std::vector< int >().swap(
length );
1769 std::vector< int >().swap( nbor_proc );
1770 std::vector< double >().swap( coords );