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+
602674static 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 ) {
0 commit comments