| # SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) |
| # Copyright (c) 2022 Nvidia Inc. All rights reserved. See COPYING file |
| |
| import unittest |
| import errno |
| |
| from pyverbs.pyverbs_error import PyverbsRDMAError |
| from tests.base import RCResources, RDMATestCase |
| from pyverbs.mr import DmaBufMR |
| from pyverbs.qp import QPAttr |
| import tests.cuda_utils as cu |
| import pyverbs.enums as e |
| import tests.utils as u |
| |
| try: |
| from cuda import cuda, cudart, nvrtc |
| cu.CUDA_FOUND = True |
| except ImportError: |
| cu.CUDA_FOUND = False |
| |
| GPU_PAGE_SIZE = 1 << 16 |
| |
| |
| @cu.set_mem_io_cuda_methods |
| class DmabufCudaRes(RCResources): |
| def __init__(self, dev_name, ib_port, gid_index, |
| mr_access=e.IBV_ACCESS_LOCAL_WRITE): |
| """ |
| Initializes MR and DMA BUF resources on top of a CUDA memory. |
| Uses RC QPs for traffic. |
| :param dev_name: Device name to be used |
| :param ib_port: IB port of the device to use |
| :param gid_index: Which GID index to use |
| :param mr_access: The MR access |
| """ |
| self.mr_access = mr_access |
| self.cuda_addr = None |
| super().__init__(dev_name=dev_name, ib_port=ib_port, gid_index=gid_index) |
| |
| def create_mr(self): |
| self.cuda_addr = cu.check_cuda_errors(cuda.cuMemAlloc(GPU_PAGE_SIZE)) |
| |
| attr_flag = 1 |
| cu.check_cuda_errors(cuda.cuPointerSetAttribute( |
| attr_flag, |
| cuda.CUpointer_attribute.CU_POINTER_ATTRIBUTE_SYNC_MEMOPS, |
| int(self.cuda_addr))) |
| |
| dmabuf_fd = cu.check_cuda_errors( |
| cuda.cuMemGetHandleForAddressRange(self.cuda_addr, |
| GPU_PAGE_SIZE, |
| cuda.CUmemRangeHandleType.CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD, |
| 0)) |
| try: |
| self.mr = DmaBufMR(self.pd, self.msg_size, self.mr_access, dmabuf_fd) |
| except PyverbsRDMAError as ex: |
| if ex.error_code == errno.EOPNOTSUPP: |
| raise unittest.SkipTest(f'Registering DMABUF MR is not supported') |
| raise ex |
| |
| def create_qp_attr(self): |
| qp_attr = QPAttr(port_num=self.ib_port) |
| qp_access = e.IBV_ACCESS_LOCAL_WRITE | e.IBV_ACCESS_REMOTE_WRITE | \ |
| e.IBV_ACCESS_REMOTE_READ |
| qp_attr.qp_access_flags = qp_access |
| return qp_attr |
| |
| |
| @cu.set_init_cuda_methods |
| class DmabufCudaTest(RDMATestCase): |
| """ |
| Test RDMA traffic over CUDA memory |
| """ |
| |
| def test_cuda_dmabuf_rdma_write_traffic(self): |
| """ |
| Runs RDMA Write traffic over CUDA allocated memory using DMA BUF and |
| RC QPs. |
| """ |
| access = e.IBV_ACCESS_LOCAL_WRITE | e.IBV_ACCESS_REMOTE_WRITE |
| self.create_players(DmabufCudaRes, mr_access=access) |
| u.rdma_traffic(**self.traffic_args, send_op=e.IBV_WR_RDMA_WRITE) |