Skip to content

Commit 43a60f7

Browse files
committed
UCT/CUDA/CUDA_COPY: Remove shared context
1 parent 9ca826f commit 43a60f7

3 files changed

Lines changed: 62 additions & 115 deletions

File tree

src/uct/cuda/cuda_copy/cuda_copy_md.c

Lines changed: 57 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -589,110 +589,71 @@ static size_t uct_cuda_copy_md_get_total_device_mem(CUdevice cuda_device)
589589
return 1; /* return 1 byte to avoid division by zero */
590590
}
591591

592-
struct uct_cuda_copy_md_query_ctx {
593-
CUcontext cuda_ctx; /* memory's owning context, or NULL */
594-
CUdevice cuda_device; /* owning device, or CU_DEVICE_INVALID */
595-
CUcontext pushed_cuda_ctx; /* context pushed by this query, if any */
596-
CUdevice pushed_cuda_device; /* device whose primary ctx was pushed */
597-
};
598-
599-
static ucs_status_t
600-
uct_cuda_copy_md_ensure_ctx_pushed(uct_cuda_copy_md_query_ctx_t *query_ctx,
601-
ucs_log_level_t log_level)
602-
{
603-
ucs_status_t status;
604-
605-
if ((query_ctx == NULL) ||
606-
((query_ctx->cuda_ctx == NULL) &&
607-
(query_ctx->cuda_device == CU_DEVICE_INVALID))) {
608-
return UCS_OK;
609-
}
610-
611-
if ((query_ctx->pushed_cuda_ctx != NULL) ||
612-
(query_ctx->pushed_cuda_device != CU_DEVICE_INVALID)) {
613-
return UCS_OK;
614-
}
615-
616-
if (query_ctx->cuda_ctx == NULL) {
617-
status = uct_cuda_ctx_primary_push(query_ctx->cuda_device, 0,
618-
log_level);
619-
if (status == UCS_OK) {
620-
query_ctx->pushed_cuda_device = query_ctx->cuda_device;
621-
}
622-
} else {
623-
status = UCT_CUDADRV_FUNC(cuCtxPushCurrent(query_ctx->cuda_ctx),
624-
log_level);
625-
if (status == UCS_OK) {
626-
query_ctx->pushed_cuda_ctx = query_ctx->cuda_ctx;
627-
}
628-
}
629-
630-
return status;
631-
}
632-
633-
static void
634-
uct_cuda_copy_md_pop_ctx(uct_cuda_copy_md_query_ctx_t *query_ctx)
635-
{
636-
uct_cuda_ctx_pop_and_release(query_ctx->pushed_cuda_device,
637-
query_ctx->pushed_cuda_ctx);
638-
query_ctx->pushed_cuda_device = CU_DEVICE_INVALID;
639-
query_ctx->pushed_cuda_ctx = NULL;
640-
}
641-
642592
static void uct_cuda_copy_md_sync_memops_get_address_range(
643593
const uct_cuda_copy_md_t *md, CUdeviceptr address, size_t length,
644-
int is_vmm, ucs_memory_info_t *mem_info,
645-
uct_cuda_copy_md_query_ctx_t *query_ctx)
594+
CUcontext cuda_ctx, CUdevice cuda_device, int is_vmm,
595+
ucs_memory_info_t *mem_info)
646596
{
597+
CUcontext tmp_ctx;
647598
CUdeviceptr base_address;
648599
size_t alloc_length;
649600
size_t total_bytes;
601+
ucs_status_t status;
650602

651603
mem_info->base_address = (void*)address;
652604
mem_info->alloc_length = length;
653605

654-
/* sync memops and cuMemGetAddressRange below need a current context */
655-
if (uct_cuda_copy_md_ensure_ctx_pushed(query_ctx, UCS_LOG_LEVEL_ERROR) !=
656-
UCS_OK) {
606+
if (cuda_ctx == NULL) {
607+
status = uct_cuda_ctx_primary_push(cuda_device, 0, UCS_LOG_LEVEL_ERROR);
608+
} else {
609+
status = UCT_CUDADRV_FUNC_LOG_ERR(cuCtxPushCurrent(cuda_ctx));
610+
}
611+
if (status != UCS_OK) {
657612
return;
658613
}
659614

615+
/* Wrapped the method by push/pop CUDA context since it sets
616+
CU_CTX_SYNC_MEMOPS flag for the current context */
660617
uct_cuda_copy_sync_memops(address, is_vmm);
661618

662619
if (md->config.alloc_whole_reg == UCS_CONFIG_OFF) {
663620
/* Extending the registration range is disable by configuration */
664-
return;
621+
goto out_ctx_pop;
665622
}
666623

667624
if (UCT_CUDADRV_FUNC_LOG_DEBUG(
668625
cuMemGetAddressRange(&base_address, &alloc_length, address)) !=
669626
UCS_OK) {
670-
return;
627+
goto out_ctx_pop;
671628
}
672629

673630
ucs_trace("query address 0x%llx: 0x%llx..0x%llx length %zu", address,
674631
base_address, base_address + alloc_length, alloc_length);
675632

676633
if (md->config.alloc_whole_reg == UCS_CONFIG_AUTO) {
677-
total_bytes = uct_cuda_copy_md_get_total_device_mem(
678-
query_ctx->cuda_device);
634+
total_bytes = uct_cuda_copy_md_get_total_device_mem(cuda_device);
679635
if (alloc_length > (total_bytes * md->config.max_reg_ratio)) {
680-
return;
636+
goto out_ctx_pop;
681637
}
682638
} else {
683639
ucs_assert(md->config.alloc_whole_reg == UCS_CONFIG_ON);
684640
}
685641

686642
mem_info->base_address = (void*)base_address;
687643
mem_info->alloc_length = alloc_length;
644+
645+
out_ctx_pop:
646+
UCT_CUDADRV_FUNC_LOG_WARN(cuCtxPopCurrent(&tmp_ctx));
647+
if (cuda_ctx == NULL) {
648+
UCT_CUDADRV_FUNC_LOG_WARN(cuDevicePrimaryCtxRelease(cuda_device));
649+
}
688650
}
689651

690652
static ucs_status_t
691653
uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
692654
const void *address, size_t length,
693655
ucs_memory_info_t *mem_info,
694-
int *is_async_managed, int *is_host_located,
695-
uct_cuda_copy_md_query_ctx_t *query_ctx)
656+
int *is_async_managed, int *is_host_located)
696657
{
697658
#define UCT_CUDA_MEM_QUERY_NUM_ATTRS 4
698659
CUmemorytype cuda_mem_type = CU_MEMORYTYPE_HOST;
@@ -715,8 +676,6 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
715676
if (mem_info->type == UCS_MEMORY_TYPE_UNKNOWN) {
716677
return UCS_ERR_INVALID_ADDR;
717678
}
718-
719-
query_ctx->cuda_device = cuda_device;
720679
} else {
721680
attr_type[0] = CU_POINTER_ATTRIBUTE_MEMORY_TYPE;
722681
attr_data[0] = &cuda_mem_type;
@@ -741,9 +700,6 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
741700
return UCS_ERR_INVALID_ADDR;
742701
}
743702

744-
query_ctx->cuda_ctx = cuda_mem_ctx;
745-
query_ctx->cuda_device = cuda_device;
746-
747703
if (is_managed) {
748704
/* cuMemGetAddress range does not support managed memory so use
749705
* provided address and length as base address and alloc length
@@ -799,8 +755,9 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
799755
}
800756

801757
uct_cuda_copy_md_sync_memops_get_address_range(md, (CUdeviceptr)address,
802-
length, is_vmm, mem_info,
803-
query_ctx);
758+
length, cuda_mem_ctx,
759+
cuda_device, is_vmm,
760+
mem_info);
804761
return UCS_OK;
805762

806763
out_default_range:
@@ -809,9 +766,8 @@ uct_cuda_copy_md_query_attributes(const uct_cuda_copy_md_t *md,
809766
return UCS_OK;
810767
}
811768

812-
static int uct_cuda_copy_md_get_dmabuf_fd(
813-
uintptr_t address, size_t length, ucs_sys_device_t sys_dev,
814-
uct_cuda_copy_md_query_ctx_t *query_ctx)
769+
static int uct_cuda_copy_md_get_dmabuf_fd(uintptr_t address, size_t length,
770+
ucs_sys_device_t sys_dev)
815771
{
816772
#if CUDA_VERSION >= 11070
817773
unsigned long long flags = 0;
@@ -856,10 +812,6 @@ static int uct_cuda_copy_md_get_dmabuf_fd(
856812
}
857813
#endif
858814

859-
/* Best-effort. If the push fails, still attempt the export with
860-
* whatever context is current. */
861-
(void)uct_cuda_copy_md_ensure_ctx_pushed(query_ctx, UCS_LOG_LEVEL_DEBUG);
862-
863815
cu_err = get_handle_func((void*)&fd, address, length,
864816
CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD, flags);
865817
if (cu_err == CUDA_SUCCESS) {
@@ -876,10 +828,9 @@ static int uct_cuda_copy_md_get_dmabuf_fd(
876828
return UCT_DMABUF_FD_INVALID;
877829
}
878830

879-
uct_cuda_copy_md_dmabuf_t
880-
uct_cuda_copy_md_get_dmabuf(const void *address, size_t length,
881-
ucs_sys_device_t sys_dev,
882-
uct_cuda_copy_md_query_ctx_t *query_ctx)
831+
uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf(const void *address,
832+
size_t length,
833+
ucs_sys_device_t sys_dev)
883834
{
884835
uct_cuda_copy_md_dmabuf_t dmabuf;
885836
uintptr_t base_address, aligned_start, aligned_end;
@@ -889,7 +840,7 @@ uct_cuda_copy_md_get_dmabuf(const void *address, size_t length,
889840
aligned_end = ucs_align_up_pow2(base_address + length, ucs_get_page_size());
890841
dmabuf.fd = uct_cuda_copy_md_get_dmabuf_fd(aligned_start,
891842
aligned_end - aligned_start,
892-
sys_dev, query_ctx);
843+
sys_dev);
893844
dmabuf.offset = base_address - aligned_start;
894845
return dmabuf;
895846
}
@@ -898,8 +849,7 @@ static uint8_t
898849
uct_cuda_copy_md_detect_mem_flags(uct_cuda_copy_md_t *md,
899850
const ucs_memory_info_t *mem_info,
900851
int is_async_managed, int is_host_located,
901-
const uct_cuda_copy_md_dmabuf_t *dmabuf,
902-
uct_cuda_copy_md_query_ctx_t *query_ctx)
852+
const uct_cuda_copy_md_dmabuf_t *dmabuf)
903853
{
904854
int close_dmabuf = 0;
905855
uct_cuda_copy_md_dmabuf_t local_dmabuf;
@@ -924,8 +874,7 @@ uct_cuda_copy_md_detect_mem_flags(uct_cuda_copy_md_t *md,
924874
if (dmabuf == NULL) {
925875
local_dmabuf = uct_cuda_copy_md_get_dmabuf(mem_info->base_address,
926876
mem_info->alloc_length,
927-
mem_info->sys_dev,
928-
query_ctx);
877+
mem_info->sys_dev);
929878
dmabuf = &local_dmabuf;
930879
close_dmabuf = 1;
931880
}
@@ -956,15 +905,11 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
956905
.fd = UCT_DMABUF_FD_INVALID,
957906
.offset = 0
958907
};
959-
uct_cuda_copy_md_query_ctx_t query_ctx = {
960-
.cuda_ctx = NULL,
961-
.cuda_device = CU_DEVICE_INVALID,
962-
.pushed_cuda_ctx = NULL,
963-
.pushed_cuda_device = CU_DEVICE_INVALID
964-
};
965-
int dmabuf_queried = 0;
966-
int is_async_managed = 0;
967-
int is_host_located = 0;
908+
int dmabuf_queried = 0;
909+
int is_async_managed = 0;
910+
int is_host_located = 0;
911+
CUdevice cur_cuda_device = CU_DEVICE_INVALID;
912+
CUdevice avail_cuda_device = CU_DEVICE_INVALID;
968913
ucs_memory_info_t cached_mem_info;
969914
ucs_memory_info_t addr_mem_info;
970915
ucs_status_t cache_status;
@@ -987,10 +932,8 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
987932
status = uct_cuda_copy_md_query_attributes(md, address, length,
988933
&addr_mem_info,
989934
&is_async_managed,
990-
&is_host_located,
991-
&query_ctx);
935+
&is_host_located);
992936
if (status != UCS_OK) {
993-
uct_cuda_copy_md_pop_ctx(&query_ctx);
994937
return status;
995938
}
996939

@@ -1020,11 +963,22 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
1020963
mem_attr->alloc_length = addr_mem_info.alloc_length;
1021964
}
1022965

966+
/* dmabuf export and mem_flags detection require a current context on the
967+
* memory's device; reuse the current one if suitable, otherwise push it */
968+
if (addr_mem_info.sys_dev != UCS_SYS_DEVICE_ID_UNKNOWN) {
969+
if (uct_cuda_ctx_primary_push_avail(0, addr_mem_info.sys_dev,
970+
&cur_cuda_device, &avail_cuda_device,
971+
UCS_LOG_LEVEL_DEBUG) != UCS_OK) {
972+
/* best-effort: continue with whatever context is current */
973+
avail_cuda_device = cur_cuda_device;
974+
}
975+
}
976+
1023977
if ((mem_attr->field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD) ||
1024978
(mem_attr->field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_OFFSET)) {
1025979
dmabuf = uct_cuda_copy_md_get_dmabuf(addr_mem_info.base_address,
1026980
addr_mem_info.alloc_length,
1027-
addr_mem_info.sys_dev, &query_ctx);
981+
addr_mem_info.sys_dev);
1028982
dmabuf_queried = 1;
1029983
if (mem_attr->field_mask & UCT_MD_MEM_ATTR_V2_FIELD_DMABUF_FD) {
1030984
mem_attr->dmabuf_fd = dmabuf.fd;
@@ -1039,7 +993,7 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
1039993
if (address != NULL) {
1040994
addr_mem_info.mem_flags = uct_cuda_copy_md_detect_mem_flags(
1041995
md, &addr_mem_info, is_async_managed, is_host_located,
1042-
dmabuf_queried ? &dmabuf : NULL, &query_ctx);
996+
dmabuf_queried ? &dmabuf : NULL);
1043997
ucs_memtype_cache_update(addr_mem_info.base_address,
1044998
addr_mem_info.alloc_length, addr_mem_info.type,
1045999
addr_mem_info.sys_dev,
@@ -1060,7 +1014,10 @@ ucs_status_t uct_cuda_copy_md_mem_query(uct_md_h tl_md, const void *address,
10601014
ucs_close_fd(&dmabuf.fd);
10611015
}
10621016

1063-
uct_cuda_copy_md_pop_ctx(&query_ctx);
1017+
if (cur_cuda_device != avail_cuda_device) {
1018+
uct_cuda_ctx_primary_pop_and_release(avail_cuda_device);
1019+
}
1020+
10641021
return UCS_OK;
10651022
}
10661023

src/uct/cuda/cuda_copy/cuda_copy_md.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ typedef struct {
7272
} uct_cuda_copy_md_dmabuf_t;
7373

7474

75-
/**
76-
* CUDA context state for a single memory query
77-
*/
78-
typedef struct uct_cuda_copy_md_query_ctx uct_cuda_copy_md_query_ctx_t;
79-
80-
8175
ucs_status_t uct_cuda_copy_md_detect_memory_type(uct_md_h md,
8276
const void *address,
8377
size_t length,
@@ -104,14 +98,10 @@ int uct_cuda_copy_md_is_dmabuf_supported();
10498
file descriptor can be used by a Direct NIC. If sys_dev
10599
is UCS_SYS_DEVICE_ID_UNKNOWN, the file descriptor can
106100
be used by any device.
107-
* @param query_ctx [inout] Optional context state (see
108-
* uct_cuda_copy_md_query_ctx_t); NULL relies on the
109-
* caller's current context.
110101
* @return The dmabuf file descriptor and offset
111102
*/
112-
uct_cuda_copy_md_dmabuf_t
113-
uct_cuda_copy_md_get_dmabuf(const void *address, size_t length,
114-
ucs_sys_device_t sys_dev,
115-
uct_cuda_copy_md_query_ctx_t *query_ctx);
103+
uct_cuda_copy_md_dmabuf_t uct_cuda_copy_md_get_dmabuf(const void *address,
104+
size_t length,
105+
ucs_sys_device_t sys_dev);
116106

117107
#endif

src/uct/ib/mlx5/gdaki/gdaki.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static int uct_gdaki_check_umem_dmabuf(const uct_ib_md_t *md)
152152
}
153153

154154
dmabuf = uct_cuda_copy_md_get_dmabuf((void*)buff, 1,
155-
UCS_SYS_DEVICE_ID_UNKNOWN, NULL);
155+
UCS_SYS_DEVICE_ID_UNKNOWN);
156156
if (dmabuf.fd == UCT_DMABUF_FD_INVALID) {
157157
goto out_free;
158158
}
@@ -337,7 +337,7 @@ uct_rc_gdaki_umem_reg(const uct_ib_md_t *md, struct ibv_context *ibv_context,
337337

338338
if (uct_gdaki_get_driver_features(md) & UCT_GDAKI_DMABUF_UMEM) {
339339
dmabuf = uct_cuda_copy_md_get_dmabuf(address, length,
340-
UCS_SYS_DEVICE_ID_UNKNOWN, NULL);
340+
UCS_SYS_DEVICE_ID_UNKNOWN);
341341
}
342342

343343
if (dmabuf.fd == UCT_DMABUF_FD_INVALID) {

0 commit comments

Comments
 (0)