Skip to content

Commit 4eecbb7

Browse files
UCC/CORE: Added automation to loading local rank from topo if not provided by user
1 parent 84d6c72 commit 4eecbb7

4 files changed

Lines changed: 144 additions & 6 deletions

File tree

src/components/topo/ucc_topo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,16 @@ static inline ucc_rank_t ucc_topo_nnodes(ucc_topo_t *topo)
290290
return sbgp->group_size;
291291
}
292292

293+
static inline ucc_rank_t ucc_topo_node_local_rank(ucc_topo_t *topo)
294+
{
295+
ucc_sbgp_t *sbgp = ucc_topo_get_sbgp(topo, UCC_SBGP_NODE);
296+
297+
if (sbgp->status == UCC_SBGP_NOT_EXISTS) {
298+
return 0;
299+
}
300+
return sbgp->group_rank;
301+
}
302+
293303
/* Returns node leaders array - array that maps each rank to the TEAM RANK that
294304
is the leader of that rank's node. Also returns per-node leaders array - array
295305
mapping node_id to the TEAM RANK of that node's leader */

src/core/ucc_context.c

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "config.h"
88
#include "ucc_context.h"
9+
#include "components/topo/ucc_topo.h"
910
#include "utils/ucc_proc_info.h"
1011
#include "components/cl/ucc_cl.h"
1112
#include "components/tl/ucc_tl.h"
@@ -599,6 +600,77 @@ ucc_status_t ucc_core_addr_exchange(
599600
return UCC_OK;
600601
}
601602

603+
ucc_status_t ucc_core_ctx_id_exchange(ucc_context_t *context, ucc_oob_coll_t *oob,
604+
ucc_addr_storage_t *addr_storage)
605+
{
606+
ucc_status_t status;
607+
ucc_rank_t i;
608+
609+
poll:
610+
if (addr_storage->oob_req) {
611+
status = oob->req_test(addr_storage->oob_req);
612+
if (status < 0) {
613+
oob->req_free(addr_storage->oob_req);
614+
ucc_error("oob req test failed during topo addr exchange");
615+
return status;
616+
} else if (UCC_INPROGRESS == status) {
617+
return status;
618+
}
619+
oob->req_free(addr_storage->oob_req);
620+
addr_storage->oob_req = NULL;
621+
}
622+
if (0 == addr_storage->addr_len) {
623+
if (NULL == addr_storage->storage) {
624+
addr_storage->size = oob->n_oob_eps;
625+
626+
addr_storage->storage = (ucc_context_id_t *)ucc_malloc(
627+
addr_storage->size * sizeof(ucc_context_id_t), "ctx_ids_storage");
628+
if (!addr_storage->storage) {
629+
ucc_error(
630+
"failed to allocate %zd bytes for ctx_ids storage",
631+
addr_storage->size * sizeof(ucc_context_id_t));
632+
return UCC_ERR_NO_MEMORY;
633+
}
634+
addr_storage->addr_len = sizeof(ucc_context_id_t);
635+
636+
status = oob->allgather(&context->id, addr_storage->storage,
637+
sizeof(ucc_context_id_t), oob->coll_info,
638+
&addr_storage->oob_req);
639+
if (UCC_OK != status) {
640+
ucc_free(addr_storage->storage);
641+
ucc_error("failed to start oob allgather for ctx_ids");
642+
return status;
643+
}
644+
goto poll;
645+
}
646+
}
647+
ucc_assert(addr_storage->storage != NULL);
648+
if (addr_storage->addr_len == 0 ) {
649+
ucc_free(addr_storage->storage);
650+
addr_storage->storage = NULL;
651+
return UCC_OK;
652+
}
653+
654+
{
655+
ucc_context_id_t *ctx_ids = (ucc_context_id_t *)addr_storage->storage;
656+
ucc_rank_t r = UCC_RANK_MAX;
657+
658+
for (i = 0; i < addr_storage->size; i++) {
659+
if (UCC_CTX_ID_EQUAL(context->id, ctx_ids[i])) {
660+
if (r != UCC_RANK_MAX) {
661+
ucc_error("ctx_id collision: %d %d", r, i);
662+
return UCC_ERR_NO_MESSAGE;
663+
}
664+
r = i;
665+
}
666+
}
667+
668+
addr_storage->flags = 0;
669+
addr_storage->rank = r;
670+
}
671+
return UCC_OK;
672+
}
673+
602674
static void remove_tl_ctx_from_array(ucc_tl_context_t **array, unsigned *size,
603675
ucc_tl_context_t *tl_ctx)
604676
{
@@ -669,6 +741,60 @@ ucc_status_t ucc_context_create_proc_info(
669741
ucc_check_wait_for_debugger(ctx->rank);
670742
#endif
671743
}
744+
745+
ctx->id.pi = *proc_info;
746+
ctx->id.seq_num = ucc_atomic_fadd32(&ucc_context_seq_num, 1);
747+
748+
if (config->node_local_id == UCC_ULUNITS_AUTO) {
749+
if (params->mask & UCC_CONTEXT_PARAM_FIELD_OOB && params->oob.n_oob_eps > 1) {
750+
do {
751+
/* UCC context create is blocking fn, so we can wait here for the
752+
completion of addr exchange */
753+
status = ucc_core_ctx_id_exchange(ctx, &ctx->params.oob,
754+
&ctx->addr_storage);
755+
if (status < 0) {
756+
ucc_error("failed to exchange addresses during context "
757+
"creation with status: %s",
758+
ucc_status_string(status));
759+
goto error_ctx_create;
760+
}
761+
} while (status == UCC_INPROGRESS);
762+
status = ucc_context_topo_init(&ctx->addr_storage, &ctx->topo);
763+
if (UCC_OK != status) {
764+
ucc_free(ctx->addr_storage.storage);
765+
ucc_error("failed to init ctx topo");
766+
goto error_ctx_create;
767+
}
768+
ucc_assert(ctx->addr_storage.rank == params->oob.oob_ep);
769+
770+
if (ctx->topo) {
771+
ucc_subset_t set;
772+
ucc_topo_t *topo = NULL;
773+
774+
memset(&set.map, 0, sizeof(ucc_ep_map_t));
775+
set.map.type = UCC_EP_MAP_FULL;
776+
set.myrank = params->oob.oob_ep;
777+
set.map.ep_num = params->oob.n_oob_eps;
778+
779+
status = ucc_topo_init(set, ctx->topo, &topo);
780+
if (UCC_OK != status) {
781+
ucc_warn("failed to init topo for computing local rank");
782+
} else {
783+
b_params.node_local_id = ucc_topo_node_local_rank(topo);
784+
ucc_topo_cleanup(topo);
785+
}
786+
}
787+
788+
/* clean up addr_storage */
789+
ucc_free(ctx->addr_storage.storage);
790+
ctx->addr_storage.storage = NULL;
791+
ctx->addr_storage.addr_len = 0;
792+
ctx->addr_storage.size = 0;
793+
ctx->addr_storage.rank = UCC_RANK_MAX;
794+
ctx->addr_storage.flags = 0;
795+
}
796+
}
797+
672798
status = ucc_create_tl_contexts(ctx, config, b_params);
673799
if (UCC_OK != status) {
674800
/* only critical error could have happened - bail */
@@ -748,8 +874,7 @@ ucc_status_t ucc_context_create_proc_info(
748874
ucc_error("failed to init progress queue for context %p", ctx);
749875
goto error_ctx_create;
750876
}
751-
ctx->id.pi = *proc_info;
752-
ctx->id.seq_num = ucc_atomic_fadd32(&ucc_context_seq_num, 1);
877+
753878
if (params->mask & UCC_CONTEXT_PARAM_FIELD_OOB &&
754879
params->oob.n_oob_eps > 1) {
755880
do {
@@ -765,7 +890,7 @@ ucc_status_t ucc_context_create_proc_info(
765890
}
766891
} while (status == UCC_INPROGRESS);
767892

768-
if (topo_required) {
893+
if (topo_required && !ctx->topo) {
769894
/* At least one available CL context reported it needs topo info */
770895
status = ucc_context_topo_init(&ctx->addr_storage, &ctx->topo);
771896
if (UCC_OK != status) {

src/core/ucc_context.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ ucc_status_t ucc_context_progress_deregister(ucc_context_t *ctx,
152152
ucc_status_t ucc_core_addr_exchange(ucc_context_t *context, ucc_oob_coll_t *oob,
153153
ucc_addr_storage_t *addr_storage);
154154

155+
/* Performs context id address exchange between the processes group defined by OOB.
156+
This function is used to exchange the context ids between the processes in order
157+
to find the local rank.
158+
*/
159+
ucc_status_t ucc_core_ctx_id_exchange(ucc_context_t *context, ucc_oob_coll_t *oob,
160+
ucc_addr_storage_t *addr_storage);
155161
/* UCC context packed address layout:
156162
--------------------------------------------------------------------------
157163
|ctx_id|host_info|n_components|id0|offset0|id1|offset1|..|

tools/perf/ucc_pt_comm.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ ucc_status_t ucc_pt_comm::init()
167167
cfg_mod = std::to_string(bootstrap->get_ppn());
168168
UCCCHECK_GOTO(ucc_context_config_modify(ctx_config, NULL,
169169
"ESTIMATED_NUM_PPN", cfg_mod.c_str()), free_ctx_config, st);
170-
cfg_mod = std::to_string(bootstrap->get_local_rank());
171-
UCCCHECK_GOTO(ucc_context_config_modify(ctx_config, NULL,
172-
"NODE_LOCAL_ID", cfg_mod.c_str()), free_ctx_config, st);
173170
std::memset(&ctx_params, 0, sizeof(ucc_context_params_t));
174171
ctx_params.mask = UCC_CONTEXT_PARAM_FIELD_TYPE |
175172
UCC_CONTEXT_PARAM_FIELD_OOB |

0 commit comments

Comments
 (0)