java-topology/defects/ompi/patch/ompi-0001-group-ops-process-name-hashmap.patch

109 lines
4.9 KiB
Diff

# UNDF: UNDF-2026-000000399
# UNDF: (pending)
--- a/ompi/group/group.c
+++ b/ompi/group/group.c
@@ -98,6 +98,17 @@ int ompi_group_translate_ranks ( ompi_group_t *group1,
#endif
+ /* Build reverse-hash of group2: (jobid<<32|vpid) -> rank+1 */
+ opal_hash_table_t *g2_ht = OBJ_NEW(opal_hash_table_t);
+ if (NULL == g2_ht) return MPI_ERR_NO_MEM;
+ opal_hash_table_init(g2_ht, group2->grp_proc_count * 2 + 1);
+ for (int _i = 0; _i < group2->grp_proc_count; _i++) {
+ opal_process_name_t _n = ompi_group_get_proc_name(group2, _i);
+ uint64_t _k = (((uint64_t)_n.jobid) << 32) | (uint64_t)_n.vpid;
+ opal_hash_table_set_value_uint64(g2_ht, _k, (void *)(uintptr_t)(_i + 1));
+ }
+
/* loop over all ranks */
for (int proc = 0; proc < n_ranks; ++proc) {
ompi_process_name_t proc1_name, proc2_name;
@@ -110,17 +121,13 @@ int ompi_group_translate_ranks ( ompi_group_t *group1,
proc1_name = ompi_group_get_proc_name(group1, rank);
/* initialize to no "match" */
ranks2[proc] = MPI_UNDEFINED;
- for (int proc2 = 0; proc2 < group2->grp_proc_count; ++proc2) {
- proc2_name = ompi_group_get_proc_name(group2, proc2);
- if(0 == opal_compare_proc(proc1_name, proc2_name)) {
- ranks2[proc] = proc2;
- break;
- }
- } /* end proc2 loop */
+ uint64_t _k = (((uint64_t)proc1_name.jobid) << 32) | (uint64_t)proc1_name.vpid;
+ void *_v = NULL;
+ opal_hash_table_get_value_uint64(g2_ht, _k, &_v);
+ ranks2[proc] = _v ? (int)((uintptr_t)_v - 1) : MPI_UNDEFINED;
} /* end proc loop */
+ OBJ_RELEASE(g2_ht);
return MPI_SUCCESS;
}
@@ -453,6 +460,17 @@ int ompi_group_intersection(ompi_group_t* group1,ompi_group_t* group2,
k = 0;
+
+ /* Build reverse-hash of group2 for O(1) membership test */
+ opal_hash_table_t *g2_ht = OBJ_NEW(opal_hash_table_t);
+ if (NULL == g2_ht) { free(ranks_included); return MPI_ERR_NO_MEM; }
+ opal_hash_table_init(g2_ht, group2_pointer->grp_proc_count * 2 + 1);
+ for (int _i = 0; _i < group2_pointer->grp_proc_count; _i++) {
+ opal_process_name_t _n = ompi_group_get_proc_name(group2_pointer, _i);
+ uint64_t _k = (((uint64_t)_n.jobid) << 32) | (uint64_t)_n.vpid;
+ opal_hash_table_set_value_uint64(g2_ht, _k, (void *)(uintptr_t)1);
+ }
+
/* determine the list of included processes for the incl-method */
for (proc1 = 0; proc1 < group1_pointer->grp_proc_count; proc1++) {
proc1_name = ompi_group_get_proc_name(group1_pointer , proc1);
- /* check to see if this proc is in group2 */
- for (proc2 = 0; proc2 < group2_pointer->grp_proc_count; proc2++) {
- proc2_name = ompi_group_get_proc_name(group2_pointer ,proc2);
- if(0 == opal_compare_proc(proc1_name, proc2_name)) {
- ranks_included[k] = proc1;
- k++;
- break;
- }
- } /* end proc2 loop */
+ uint64_t _k = (((uint64_t)proc1_name.jobid) << 32) | (uint64_t)proc1_name.vpid;
+ void *_v = NULL;
+ opal_hash_table_get_value_uint64(g2_ht, _k, &_v);
+ if (_v) { ranks_included[k++] = proc1; }
} /* end proc1 loop */
+ OBJ_RELEASE(g2_ht);
result = ompi_group_incl(group1, k, ranks_included, new_group);
@@ -629,14 +643,20 @@ bool ompi_group_overlap (const ompi_group_t *group1, const ompi_group_t *group2)
{
- for (int i = 0 ; i < group1->grp_proc_count ; ++i) {
- opal_process_name_t proc1 = ompi_group_get_proc_name (group1, i);
- for (int j = 0 ; j < group2->grp_proc_count ; ++j) {
- opal_process_name_t proc2 = ompi_group_get_proc_name (group2, j);
- if (0 == opal_compare_proc (proc1, proc2)) {
- return true;
- }
- }
- }
- return false;
+ /* Build hash of smaller group for O(N+M) instead of O(N*M) */
+ const ompi_group_t *small = (group1->grp_proc_count <= group2->grp_proc_count) ? group1 : group2;
+ const ompi_group_t *large = (small == group1) ? group2 : group1;
+ opal_hash_table_t *ht = OBJ_NEW(opal_hash_table_t);
+ if (NULL == ht) return false; /* conservative: assume no overlap on OOM */
+ opal_hash_table_init(ht, small->grp_proc_count * 2 + 1);
+ for (int i = 0; i < small->grp_proc_count; i++) {
+ opal_process_name_t n = ompi_group_get_proc_name(small, i);
+ uint64_t k = (((uint64_t)n.jobid) << 32) | (uint64_t)n.vpid;
+ opal_hash_table_set_value_uint64(ht, k, (void *)(uintptr_t)1);
+ }
+ bool found = false;
+ for (int i = 0; i < large->grp_proc_count && !found; i++) {
+ opal_process_name_t n = ompi_group_get_proc_name(large, i);
+ uint64_t k = (((uint64_t)n.jobid) << 32) | (uint64_t)n.vpid;
+ void *v = NULL;
+ opal_hash_table_get_value_uint64(ht, k, &v);
+ found = (v != NULL);
+ }
+ OBJ_RELEASE(ht);
+ return found;
}