moab
|
Public Member Functions | |
int | num_parts () const |
iMeshP_Part | part_id_from_local_id (int local_id) const |
int | local_id_from_part_id (iMeshP_Part part) const |
int | rank_from_part_id (iMeshP_Part part) const |
int | rank_from_local_id (int id) const |
int | count_from_rank (int rank) const |
void | part_id_from_rank (int rank, std::vector< iMeshP_Part > &parts) const |
void | local_id_from_rank (int rank, std::vector< int > &ids) const |
const std::vector< iMeshP_Part > & | get_parts () const |
const std::vector< int > & | get_ranks () const |
int | build_map (iMesh_Instance imesh, iMeshP_PartitionHandle partition, int num_expected_parts) |
Static Public Member Functions | |
static int | part_from_coords (iMesh_Instance imesh, iMeshP_PartHandle part, int &id_out) |
Private Member Functions | |
int | idx_from_part_id (iMeshP_Part id) const |
int | idx_from_local_id (int id) const |
Private Attributes | |
std::vector< iMeshP_Part > | sortedPartList |
std::vector< int > | partRanks |
std::vector< int > | partLocalIds |
std::vector< int > | localIdReverseMap |
Definition at line 222 of file MOAB_iMeshP_unit_tests.cpp.
int PartMap::build_map | ( | iMesh_Instance | imesh, |
iMeshP_PartitionHandle | partition, | ||
int | num_expected_parts | ||
) |
Definition at line 2758 of file MOAB_iMeshP_unit_tests.cpp.
{ int ierr, rank, size; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &size ); // get local parts std::vector<iMeshP_PartHandle> local_parts; std::vector<iMeshP_Part> imesh_ids; ierr = get_local_parts( imesh, prtn, local_parts, &imesh_ids ); CHKERR; // get logical ids for local parts std::vector<int> local_ids(local_parts.size()); for (size_t i = 0; i < local_parts.size(); ++i) { ierr = part_from_coords( imesh, local_parts[i], local_ids[i] ); CHKERR; } // get total number of parts int num_global = 0, num_local = local_parts.size(); ierr = MPI_Allreduce( &num_local, &num_global, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); CHKERR; if (num_global != num_expected_parts) { std::cerr << "Invalid/unexpected global part count at " __FILE__ ":" << __LINE__ << " (proc " << rank << "): " << std::endl << " Expected: " << num_expected_parts << std::endl << " Actual: " << num_global << std::endl; return 1; } // get counts and displacements for Allgatherv calls std::vector<int> dspls(size), counts(size); ierr = MPI_Allgather( &num_local, 1, MPI_INT, &counts[0], 1, MPI_INT, MPI_COMM_WORLD ); CHKERR; dspls[0] = 0; for (int i = 1; i < size; ++i) dspls[i] = dspls[i-1] + counts[i-1]; // gather iMeshP_Part list from each processor std::vector<unsigned> global_part_ids(num_expected_parts); assert(sizeof(iMeshP_Part) == sizeof(int)); ierr = MPI_Allgatherv( &imesh_ids[0], num_local, MPI_UNSIGNED, &global_part_ids[0], &counts[0], &dspls[0], MPI_UNSIGNED, MPI_COMM_WORLD ); CHKERR; // gather local ids from each processor std::vector<int> global_id_list(num_expected_parts); ierr = MPI_Allgatherv( &local_ids[0], num_local, MPI_INT, &global_id_list[0], &counts[0], &dspls[0], MPI_INT, MPI_COMM_WORLD ); CHKERR; // build owner list std::vector<int> global_owners(num_expected_parts); for (int i = 0; i < size; ++i) for (int j = 0; j < counts[i]; ++j) global_owners[dspls[i]+j] = i; // populate member lists sortedPartList = global_part_ids; std::sort( sortedPartList.begin(), sortedPartList.end() ); partLocalIds.resize( num_expected_parts ); partRanks.resize( num_expected_parts ); for (int i = 0; i < num_expected_parts; ++i) { int idx = std::lower_bound( sortedPartList.begin(), sortedPartList.end(), global_part_ids[i] ) - sortedPartList.begin(); partLocalIds[idx] = global_id_list[i]; partRanks[idx] = global_owners[i]; } // do some consistency checking if (std::unique( sortedPartList.begin(), sortedPartList.end() ) != sortedPartList.end()) { if (rank == 0) { std::cerr << "ERROR: Duplicate iMeshP_Part values detected at " __FILE__ ":" << __LINE__ << std::endl; } return 1; } // build revesre local id map and check for duplicates localIdReverseMap.clear(); localIdReverseMap.resize(num_expected_parts, -1); for (int i = 0; i < num_expected_parts; ++i) { int idx = partLocalIds[i]; if (localIdReverseMap[idx] != -1) { if (rank == 0) { std::cerr << "ERROR: Part mesh has been duplicated in multiple parts." << std::endl << " Detected at " __FILE__ ":" << __LINE__ << std::endl << " See PartMap::part_from_coords" << std::endl; } return 1; } if (idx >= num_expected_parts) { if (rank == 0) { std::cerr << "ERROR: Part mesh invalid/incorrect mesh." << std::endl << " Detected at " __FILE__ ":" << __LINE__ << std::endl << " See PartMap::part_from_coords" << std::endl; } return 1; } localIdReverseMap[idx] = i; } return 0; }
int PartMap::count_from_rank | ( | int | rank | ) | const [inline] |
Definition at line 240 of file MOAB_iMeshP_unit_tests.cpp.
const std::vector<iMeshP_Part>& PartMap::get_parts | ( | ) | const [inline] |
Definition at line 247 of file MOAB_iMeshP_unit_tests.cpp.
{ return sortedPartList; }
const std::vector<int>& PartMap::get_ranks | ( | ) | const [inline] |
Definition at line 250 of file MOAB_iMeshP_unit_tests.cpp.
{ return partRanks; }
int PartMap::idx_from_local_id | ( | int | id | ) | const [inline, private] |
Definition at line 265 of file MOAB_iMeshP_unit_tests.cpp.
{ return localIdReverseMap[id]; }
int PartMap::idx_from_part_id | ( | iMeshP_Part | id | ) | const [inline, private] |
Definition at line 262 of file MOAB_iMeshP_unit_tests.cpp.
{ return std::lower_bound( sortedPartList.begin(), sortedPartList.end(), id ) - sortedPartList.begin(); }
int PartMap::local_id_from_part_id | ( | iMeshP_Part | part | ) | const [inline] |
Definition at line 231 of file MOAB_iMeshP_unit_tests.cpp.
{ return partLocalIds[idx_from_part_id(part)]; }
void PartMap::local_id_from_rank | ( | int | rank, |
std::vector< int > & | ids | ||
) | const |
Definition at line 2876 of file MOAB_iMeshP_unit_tests.cpp.
{ for (size_t i = 0; i < sortedPartList.size(); ++i) if (partRanks[i] == rank) ids.push_back( partLocalIds[i] ); }
int PartMap::num_parts | ( | ) | const [inline] |
Definition at line 225 of file MOAB_iMeshP_unit_tests.cpp.
{ return sortedPartList.size(); }
int PartMap::part_from_coords | ( | iMesh_Instance | imesh, |
iMeshP_PartHandle | part, | ||
int & | id_out | ||
) | [static] |
Definition at line 2884 of file MOAB_iMeshP_unit_tests.cpp.
{ int ierr, rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // get elements const int num_elem = 4; iBase_EntityHandle array[num_elem]; iBase_EntityHandle* ptr = array; int junk1 = num_elem, n = -1; iMesh_getEntities( imesh, part, iBase_FACE, iMesh_QUADRILATERAL, &ptr, &junk1, &n, &ierr ); CHKERR; assert( ptr == array ); assert( junk1 == num_elem ); if (n != num_elem) { std::cerr << "Internal error at " __FILE__ ":" << __LINE__ << " (proc " << rank << "): Expected all parts to have " << num_elem << " elements. Found one with " << n << std::endl; return 1; } // get vertices iBase_EntityHandle adj_array[4*num_elem]; int junk2, junk3, offset_array[5]; ptr = adj_array; junk1 = sizeof(adj_array)/sizeof(adj_array[0]); junk2 = sizeof(offset_array)/sizeof(offset_array[0]); int* ptr2 = offset_array; iMesh_getEntArrAdj( imesh, array, num_elem, iBase_VERTEX, &ptr, &junk1, &n, &ptr2, &junk2, &junk3, &ierr ); CHKERR; assert( ptr == adj_array ); assert( ptr2 == offset_array ); assert( junk1 == sizeof(adj_array)/sizeof(adj_array[0]) ); assert( junk2 == sizeof(offset_array)/sizeof(offset_array[0]) ); assert( n == 4*num_elem ); assert( offset_array[0] == 0 ); for (int i = 1; i < junk3; ++i) assert( offset_array[i] - offset_array[i-1] == 4 ); // find center vertex iBase_EntityHandle vtx; bool all_match; for (int i = 0; i < 4; ++i) { vtx = adj_array[i]; all_match = true; for (int j = 1; j < 4; ++j) { iBase_EntityHandle* mvtx = adj_array + 4*j; int k; for (k = 0; k < 4; ++k) if (mvtx[k] == vtx) break; if (k == 4) all_match = false; } if (all_match) break; } assert(all_match); // get center vertex coordinates double x, y, z; iMesh_getVtxCoord( imesh, vtx, &x, &y, &z, &ierr ); CHKERR; assert( 0.0 == z ); const int xi = ((int)round(x) - 1)/2; const int yi = ((int)round(y) - 1)/2; assert (xi >= 0); assert (yi >= 0); assert( fabs(x - 2*xi - 1) < 1e-12 ); assert( fabs(y - 2*yi - 1) < 1e-12 ); id = 2*xi + yi; return 0; }
iMeshP_Part PartMap::part_id_from_local_id | ( | int | local_id | ) | const [inline] |
Definition at line 228 of file MOAB_iMeshP_unit_tests.cpp.
{ return sortedPartList[idx_from_local_id(local_id)]; }
void PartMap::part_id_from_rank | ( | int | rank, |
std::vector< iMeshP_Part > & | parts | ||
) | const |
Definition at line 2869 of file MOAB_iMeshP_unit_tests.cpp.
{ for (size_t i = 0; i < sortedPartList.size(); ++i) if (partRanks[i] == rank) parts.push_back( sortedPartList[i] ); }
int PartMap::rank_from_local_id | ( | int | id | ) | const [inline] |
Definition at line 237 of file MOAB_iMeshP_unit_tests.cpp.
{ return partRanks[idx_from_local_id(id)]; }
int PartMap::rank_from_part_id | ( | iMeshP_Part | part | ) | const [inline] |
Definition at line 234 of file MOAB_iMeshP_unit_tests.cpp.
{ return partRanks[idx_from_part_id(part)]; }
std::vector<int> PartMap::localIdReverseMap [private] |
Definition at line 271 of file MOAB_iMeshP_unit_tests.cpp.
std::vector<int> PartMap::partLocalIds [private] |
Definition at line 270 of file MOAB_iMeshP_unit_tests.cpp.
std::vector<int> PartMap::partRanks [private] |
Definition at line 269 of file MOAB_iMeshP_unit_tests.cpp.
std::vector<iMeshP_Part> PartMap::sortedPartList [private] |
Definition at line 268 of file MOAB_iMeshP_unit_tests.cpp.