# 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; }