Skip to content

Commit

Permalink
fabtests/hmem: add dmabuf ops for cuda.
Browse files Browse the repository at this point in the history
Signed-off-by: Shi Jin <sjina@amazon.com>
  • Loading branch information
shijin-aws committed Oct 17, 2023
1 parent 39b362b commit 45b33fb
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 1 deletion.
20 changes: 20 additions & 0 deletions fabtests/common/hmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct ft_hmem_ops {
size_t size);
int (*copy_from_hmem)(uint64_t device, void *dst, const void *src,
size_t size);
int (*get_dmabuf_fd_offset)(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset);
};

static struct ft_hmem_ops hmem_ops[] = {
Expand All @@ -61,6 +63,7 @@ static struct ft_hmem_ops hmem_ops[] = {
.mem_set = ft_host_memset,
.copy_to_hmem = ft_host_memcpy,
.copy_from_hmem = ft_host_memcpy,
.get_dmabuf_fd_offset = ft_hmem_no_get_dmabuf_fd_offset,
},
[FI_HMEM_CUDA] = {
.init = ft_cuda_init,
Expand All @@ -72,6 +75,7 @@ static struct ft_hmem_ops hmem_ops[] = {
.mem_set = ft_cuda_memset,
.copy_to_hmem = ft_cuda_copy_to_hmem,
.copy_from_hmem = ft_cuda_copy_from_hmem,
.get_dmabuf_fd_offset = ft_cuda_get_dmabuf_fd_offset,
},
[FI_HMEM_ROCR] = {
.init = ft_rocr_init,
Expand All @@ -83,6 +87,7 @@ static struct ft_hmem_ops hmem_ops[] = {
.mem_set = ft_rocr_memset,
.copy_to_hmem = ft_rocr_memcpy,
.copy_from_hmem = ft_rocr_memcpy,
.get_dmabuf_fd_offset = ft_hmem_no_get_dmabuf_fd_offset,
},
[FI_HMEM_ZE] = {
.init = ft_ze_init,
Expand All @@ -94,6 +99,7 @@ static struct ft_hmem_ops hmem_ops[] = {
.mem_set = ft_ze_memset,
.copy_to_hmem = ft_ze_copy,
.copy_from_hmem = ft_ze_copy,
.get_dmabuf_fd_offset = ft_hmem_no_get_dmabuf_fd_offset,
},
[FI_HMEM_NEURON] = {
.init = ft_neuron_init,
Expand All @@ -105,6 +111,7 @@ static struct ft_hmem_ops hmem_ops[] = {
.mem_set = ft_neuron_memset,
.copy_to_hmem = ft_neuron_memcpy_to_hmem,
.copy_from_hmem = ft_neuron_memcpy_from_hmem,
.get_dmabuf_fd_offset = ft_hmem_no_get_dmabuf_fd_offset,
},
};

Expand Down Expand Up @@ -183,3 +190,16 @@ int ft_hmem_copy_from(enum fi_hmem_iface iface, uint64_t device, void *dst,
{
return hmem_ops[iface].copy_from_hmem(device, dst, src, size);
}

int ft_hmem_get_dmabuf_fd_offset(enum fi_hmem_iface iface, uint64_t device,
void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset)
{
return hmem_ops[iface].get_dmabuf_fd_offset(device, buf, len, dmabuf_fd, dmabuf_offset);
}

int ft_hmem_no_get_dmabuf_fd_offset(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset)
{
return -FI_ENOSYS;
}
118 changes: 118 additions & 0 deletions fabtests/common/hmem_cuda.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "hmem.h"
#include "shared.h"

#define HAVE_CUDA_RUNTIME_H 1

#ifdef HAVE_CUDA_RUNTIME_H

#include <dlfcn.h>
Expand All @@ -56,6 +58,13 @@ struct cuda_ops {
CUdeviceptr ptr);
CUresult (*cuGetErrorName)(CUresult error, const char** pStr);
CUresult (*cuGetErrorString)(CUresult error, const char** pStr);
CUresult (*cuMemGetHandleForAddressRange)(void* handle,
CUdeviceptr dptr, size_t size,
CUmemRangeHandleType handleType,
unsigned long long flags);
CUresult (*cuDeviceGetAttribute)(int* pi,
CUdevice_attribute attrib, CUdevice dev);
CUresult (*cuDeviceGet)(CUdevice* device, int ordinal);
};

static struct cuda_ops cuda_ops;
Expand Down Expand Up @@ -192,6 +201,27 @@ int ft_cuda_init(void)
goto err_dlclose_cuda;
}

cuda_ops.cuMemGetHandleForAddressRange = dlsym(cuda_handle,
STRINGIFY(cuMemGetHandleForAddressRange));
if (!cuda_ops.cuPointerSetAttribute) {
FT_ERR("Failed to find cuMemGetHandleForAddressRange\n");
goto err_dlclose_cuda;
}

cuda_ops.cuDeviceGetAttribute = dlsym(cuda_handle,
STRINGIFY(cuDeviceGetAttribute));
if (!cuda_ops.cuPointerSetAttribute) {
FT_ERR("Failed to find cuPointerSetAttribute\n");
goto err_dlclose_cuda;
}

cuda_ops.cuDeviceGet = dlsym(cuda_handle,
STRINGIFY(cuDeviceGet));
if (!cuda_ops.cuPointerSetAttribute) {
FT_ERR("Failed to find cuDeviceGet\n");
goto err_dlclose_cuda;
}

cuda_ret = cuda_ops.cudaSetDevice(opts.device);
if (cuda_ret != cudaSuccess) {
CUDA_ERR(cuda_ret, "cudaSetDevice failed");
Expand Down Expand Up @@ -317,6 +347,88 @@ int ft_cuda_copy_from_hmem(uint64_t device, void *dst, const void *src,
return -FI_EIO;
}

/**
* @brief detect dmabuf support in the current platform
* This checks the dmabuf support in the current platform
* by querying the property of cuda device 0
*
* @return FI_SUCCESS if dmabuf support check is successful
* -FI_EIO upon CUDA API error
*/
static int ft_cuda_hmem_detect_dmabuf_support(uint64_t device, int *is_dmabuf_supported)
{
CUresult cuda_ret;
CUdevice dev;
int is_supported = 0;

cuda_ret = cuda_ops.cuDeviceGet(&dev, 0);
if (cuda_ret != CUDA_SUCCESS) {
ft_cuda_driver_api_print_error(cuda_ret, "cuDeviceGet");
return -FI_EIO;
}

cuda_ret = cuda_ops.cuDeviceGetAttribute(&is_supported,
CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED, dev);
if (cuda_ret != CUDA_SUCCESS) {
ft_cuda_driver_api_print_error(cuda_ret, "cuDeviceGetAttribute");
return -FI_EIO;
}

*is_dmabuf_supported = is_supported;
return FI_SUCCESS;
}

/**
* @brief Get dmabuf fd and offset for a given cuda memory allocation
*
* @param device cuda device index
* @param buf the starting address of the cuda memory allocation
* @param len the length of the cuda memory allocation
* @param dmabuf_fd the fd of the dmabuf region
* @param dmabuf_offset the offset of the buf in the dmabuf region
* @return FI_SUCCESS if dmabuf fd and offset are retrieved successfully
* -FI_EIO upon CUDA API error
*/
int ft_cuda_get_dmabuf_fd_offset(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset)
{
CUdeviceptr aligned_ptr;
CUresult cuda_ret;
int ret;
int is_dmabuf_supported = 0;

size_t aligned_size;
size_t host_page_size = sysconf(_SC_PAGESIZE);

ret = ft_cuda_hmem_detect_dmabuf_support(device, &is_dmabuf_supported);
if (ret != FI_SUCCESS)
return -FI_EIO;

if (!is_dmabuf_supported) {
FT_LOG("warn", "dmabuf is not supported on cuda device %lu\n", device);
return -FI_EOPNOTSUPP;
}

aligned_ptr = (uintptr_t) ft_get_page_start(buf, host_page_size);
aligned_size = (uintptr_t) ft_get_page_end((void *) ((uintptr_t) buf + len),
host_page_size) - (uintptr_t) aligned_ptr + 1;

cuda_ret = cuda_ops.cuMemGetHandleForAddressRange(
(void *)dmabuf_fd,
aligned_ptr, aligned_size,
CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD,
0);
if (cuda_ret != CUDA_SUCCESS) {
ft_cuda_driver_api_print_error(cuda_ret,
"cuMemGetHandleForAddressRange");
return -FI_EIO;
}

*dmabuf_offset = (uintptr_t) buf - (uintptr_t) aligned_ptr;

return FI_SUCCESS;
}

#else

int ft_cuda_init(void)
Expand Down Expand Up @@ -366,4 +478,10 @@ int ft_cuda_copy_from_hmem(uint64_t device, void *dst, const void *src,
return -FI_ENOSYS;
}

int ft_cuda_get_dmabuf_fd_offset(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset)
{
return -FI_ENOSYS;
}

#endif /* HAVE_CUDA_RUNTIME_H */
8 changes: 7 additions & 1 deletion fabtests/include/hmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ int ft_cuda_copy_to_hmem(uint64_t device, void *dst, const void *src,
size_t size);
int ft_cuda_copy_from_hmem(uint64_t device, void *dst, const void *src,
size_t size);
int ft_cuda_get_dmabuf_fd_offset(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset);
int ft_rocr_init(void);
int ft_rocr_cleanup(void);
int ft_rocr_alloc(uint64_t device, void **buf, size_t size);
Expand Down Expand Up @@ -210,5 +212,9 @@ int ft_hmem_copy_to(enum fi_hmem_iface iface, uint64_t device, void *dst,
const void *src, size_t size);
int ft_hmem_copy_from(enum fi_hmem_iface iface, uint64_t device, void *dst,
const void *src, size_t size);

int ft_hmem_get_dmabuf_fd_offset(enum fi_hmem_iface iface, uint64_t device,
void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset);
int ft_hmem_no_get_dmabuf_fd_offset(uint64_t device, void *buf, size_t len,
int *dmabuf_fd, uint64_t *dmabuf_offset);
#endif /* _HMEM_H_ */
12 changes: 12 additions & 0 deletions fabtests/include/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ enum {
FT_OPT_PERF = 1 << 24,
FT_OPT_DISABLE_TAG_VALIDATION = 1 << 25,
FT_OPT_ADDR_IS_OOB = 1 << 26,
FT_OPT_REG_DMABUF_MR = 1 << 27,
FT_OPT_OOB_CTRL = FT_OPT_OOB_SYNC | FT_OPT_OOB_ADDR_EXCH,
};

Expand Down Expand Up @@ -687,4 +688,15 @@ void ft_longopts_usage();
}
#endif

static inline void *ft_get_page_start(const void *addr, size_t page_size)
{
return (void *)((uintptr_t) addr & ~(page_size - 1));
}

static inline void *ft_get_page_end(const void *addr, size_t page_size)
{
return (void *)((uintptr_t)ft_get_page_start((const char *)addr
+ page_size, page_size) - 1);
}

#endif /* _SHARED_H_ */

0 comments on commit 45b33fb

Please sign in to comment.