# # This software product is a proprietary product of NVIDIA CORPORATION & # AFFILIATES (the "Company") and all right, title, and interest in and to the # software product, including all associated intellectual property rights, are # and shall remain exclusively with the Company. # # This software product is governed by the End User License Agreement # provided with the software product. # # GPUNetIO Samples This section contains two samples that show how to enable simple GPUNetIO features. Be sure to correctly set the following environment variables: ## Build the sample ```plaintext export PATH=${PATH}:/usr/local/cuda/bin export CPATH="$(echo /usr/local/cuda/targets/{x86_64,sbsa}-linux/include | sed 's/ /:/'):${CPATH}" export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/usr/lib/pkgconfig:/opt/mellanox/grpc/lib/{x86_64,aarch64}-linux-gnu/pkgconfig:/opt/mellanox/dpdk/lib/{x86_64,aarch64}-linux-gnu/pkgconfig:/opt/mellanox/doca/lib/{x86_64,aarch64}-linux-gnu/pkgconfig export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda/lib64:/opt/mellanox/gdrcopy/src:/opt/mellanox/dpdk/lib/{x86_64,aarch64}-linux-gnu:/opt/mellanox/doca/lib/{x86_64,aarch64}-linux-gnu ``` ## Info All the DOCA samples described in this section are governed under the BSD-3 software license agreement. ## Note Please ensure the arch of your GPU is included in the meson.build file before building the samples (e.g., sm_80 for Ampere, sm_89 for L40, sm_90 for H100, etc). --- ## Ethernet Send Wait Time The sample shows how to enable Accurate Send Scheduling (or wait-on-time) in the context of a GPUNetIO application. Accurate Send Scheduling is the ability of an NVIDIA NIC to send packets in the future according to application-provided timestamps. > **Note:** This feature is supported on ConnectX-6 Dx and later. ## Info This NVIDIA blog post offers an example for how this feature has been used in 5G networks. This DOCA GPUNetIO sample provides a simple application to send packets with Accurate Send Scheduling from the GPU. ## Synchronizing Clocks Before starting the sample, it is important to properly synchronize the CPU clock with the NIC clock. This way, timestamps provided by the system clock are synchronized with the time in the NIC. For this purpose, at least the phc2sys service must be used. To install it on an Ubuntu system: ## phc2sys ```plaintext sudo apt install linuxptp ``` To start the phc2sys service properly, a config file must be created in /lib/systemd/system/phc2sys.service: ## phc2sys ```plaintext [Unit] Description=Synchronize system clock or PTP hardware clock (PHC) Documentation=man:phc2sys [Service] Restart=always RestartSec=5s Type=simple ExecStart=/bin/sh -c "taskset -c 15 /usr/sbin/phc2sys -s /dev/ptp$(ethtool -T ens6f0 | grep PTP | awk '{print $4}') -c CLOCK_REALTIME -n 24 -O 0 -R 256 -u 256" [Install] WantedBy=multi-user.target ``` Now phc2sys service can be started: ## phc2sys ```plaintext sudo systemctl stop systemd-timesyncd sudo systemctl disable systemd-timesyncd sudo systemctl daemon-reload sudo systemctl start phc2sys.service ``` To check the status of phc2sys: ## phc2sys ```plaintext $ sudo systemctl status phc2sys.service ● phc2sys.service - Synchronize system clock or PTP hardware clock (PHC) Loaded: loaded (/lib/systemd/system/phc2sys.service; disabled; vendor preset: enabled) Active: active (running) since Mon 2023-04-03 10:59:13 UTC; 2 days ago Docs: man:phc2sys Main PID: 337824 (sh) Tasks: 2 (limit: 303788) Memory: 560.0K CPU: 52min 8.199s CGroup: /system.slice/phc2sys.service ├─337824 /bin/sh -c "taskset -c 15 /usr/sbin/phc2sys -s /dev/ptp\$(ethtool -T enp23s0f1np1 | grep PTP | awk '{print \$4}') -c CLOCK_REALTIME -n 24 -O 0 -R > └─337829 /usr/sbin/phc2sys -s /dev/ptp3 -c CLOCK_REALTIME -n 24 -O 0 -R 256 -u 256 Apr 05 16:35:52 doca-vr-045 phc2sys[337829]: [457395.040] CLOCK_REALTIME rms 8 max 18 freq +110532 +/- 27 delay 770 +/- 3 Apr 05 16:35:53 doca-vr-045 phc2sys[337829]: [457396.071] CLOCK_REALTIME rms 8 max 20 freq +110513 +/- 30 delay 769 +/- 3 Apr 05 16:35:54 doca-vr-045 phc2sys[337829]: [457397.102] CLOCK_REALTIME rms 8 max 18 freq +110527 +/- 30 delay 769 +/- 3 Apr 05 16:35:55 doca-vr-045 phc2sys[337829]: [457398.130] CLOCK_REALTIME rms 8 max 18 freq +110517 +/- 31 delay 769 +/- 3 Apr 05 16:35:56 doca-vr-045 phc2sys[337829]: [457399.159] CLOCK_REALTIME rms 8 max 19 freq +110523 +/- 32 delay 770 +/- 3 Apr 05 16:35:57 doca-vr-045 phc2sys[337829]: [457400.191] CLOCK_REALTIME rms 8 max 20 freq +110528 +/- 33 delay 770 +/- 3 Apr 05 16:35:58 doca-vr-045 phc2sys[337829]: [457401.221] CLOCK_REALTIME rms 8 max 19 freq +110512 +/- 38 delay 770 +/- 3 Apr 05 16:35:59 doca-vr-045 phc2sys[337829]: [457402.253] CLOCK_REALTIME rms 9 max 20 freq +110538 +/- 47 delay 770 +/- 4 Apr 05 16:36:00 doca-vr-045 phc2sys[337829]: [457403.281] CLOCK_REALTIME rms 8 max 21 freq +110517 +/- 38 delay 769 +/- 3 Apr 05 16:36:01 doca-vr-045 phc2sys[337829]: [457404.311] CLOCK_REALTIME rms 8 max 17 freq +110526 +/- 26 delay 769 +/- 3 ... ``` At this point, the system and NIC clocks are synchronized so timestamps provided by the CPU are correctly interpreted by the NIC. > **Warning:** The timestamps you get may not reflect the real time and day. To get that, you must properly set the ptp4l service with an external grand master on the system. Doing that is out of the scope of this sample. ## Running the Sample The sample is shipped with the source files that must be built: ## phc2sys ```plaintext # Ensure DOCA and DPDK are in the pkgconfig environment variable cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_send_wait_time meson build ninja -C build ``` The sample sends 8 bursts of 32 raw Ethernet packets or 1kB to a dummy Ethernet address, 10:11:12:13:14:15, in a timed way. Program the NIC to send every t nanoseconds (command line option -t). The following example programs a system with GPU PCIe address ca:00.0 and NIC PCIe address 17:00.0 to send 32 packets every 5 milliseconds: ## Run ```plaintext # Ensure DOCA and DPDK are in the LD_LIBRARY_PATH environment variable $ sudo ./build/doca_gpunetio_send_wait_time -n 17:00.0 -g ca:00.0 -t 5000000[09:22:54:165778][1316878][DOCA][INF][gpunetio_send_wait_time_main.c:195][main] Starting the sample [09:22:54:438260][1316878][DOCA][INF][gpunetio_send_wait_time_main.c:224][main] Sample configuration: GPU ca:00.0 NIC 17:00.0 Timeout 5000000ns EAL: Detected CPU lcores: 128 ... EAL: Probe PCI driver: mlx5_pci (15b3:a2d6) device: 0000:17:00.0 (socket 0) [09:22:54:819996][1316878][DOCA][INF][gpunetio_send_wait_time_sample.c:607][gpunetio_send_wait_time] Wait on time supported mode: DPDK EAL: Probe PCI driver: gpu_cuda (10de:20b5) device: 0000:ca:00.0 (socket 1) [09:22:54:830212][1316878][DOCA][INF][gpunetio_send_wait_time_sample.c:252][create_tx_buf] Mapping send queue buffer (0x0x7f48e32a0000 size 262144B) with legacy nvidia-peermem mode [09:22:54:832462][1316878][DOCA][INF][gpunetio_send_wait_time_sample.c:657][gpunetio_send_wait_time] Launching CUDA kernel to send packets [09:22:54:842945][1316878][DOCA][INF][gpunetio_send_wait_time_sample.c:664][gpunetio_send_wait_time] Waiting 10 sec for 256 packets to be sent [09:23:04:883309][1316878][DOCA][INF][gpunetio_send_wait_time_sample.c:684][gpunetio_send_wait_time] Sample finished successfully [09:23:04:883339][1316878][DOCA][INF][gpunetio_send_wait_time_main.c:239][main] Sample finished successfully ``` To verify that packets are actually sent at the right time, use a packet sniffer on the other side (e.g., tcpdump): ## phc2sys ```plaintext $ sudo tcpdump -i enp23s0f1np1 -A -s 64 17:12:23.480318 IP5 (invalid) Sent from DOCA GPUNetIO........................... .... 17:12:23.480368 IP5 (invalid) Sent from DOCA GPUNetIO........................... # end of first burst of 32 packets, bump to +5ms 17:12:23.485321 IP5 (invalid) Sent from DOCA GPUNetIO........................... ... 17:12:23.485369 IP5 (invalid) Sent from DOCA GPUNetIO........................... # end of second burst of 32 packets, bump to +5ms 17:12:23.490278 IP5 (invalid) Sent from DOCA GPUNetIO........................... ... ``` The output should show a jump of approximately 5 milliseconds every 32 packets. ## Note - `tcpdump` may increase latency in sniffing packets and reporting the receive timestamp. As a result, the difference between bursts of 32 packets reported may be less than expected, especially with small interval times like 500 microseconds (`-t 500000`). ## Warning - Invoking a `printf` from a CUDA kernel is not good practice for release software. It should only be used to print debug information, as it slows down the overall execution of the CUDA kernel. ## To Build and Run the Application ```plaintext # Ensure DOCA and DPDK are in the pkgconfig environment variable cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_simple_receive meson build ninja -C build ``` To test the application, this guide assumes the usual setup with two machines: one with the DOCA receiver application and the second one acting as packet generator. As UDP packet generator, this example considers the nping application that can be easily installed easily on any Linux machine. The command to send 10 UDP packets via nping on the packet generator machine is: ## nping generator ```plaintext $ nping --udp -c 10 -p 2090 192.168.1.1 --data-length 1024 --delay 500ms Starting Nping 0.7.80 ( https://nmap.org/nping ) at 2023-11-20 11:05 UTC SENT (0.0018s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (0.5018s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (1.0025s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (1.5025s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (2.0032s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (2.5033s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (3.0040s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (3.5040s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (4.0047s) UDP packet with 1024 bytes to 192.168.1.1:2090 SENT (4.5048s) UDP packet with 1024 bytes to 192.168.1.1:2090 Max rtt: N/A | Min rtt: N/A | Avg rtt: N/A UDP packets sent: 10 | Rcvd: 0 | Lost: 10 (100.00%) Nping done: 1 IP address pinged in 5.50 seconds ``` Assuming the DOCA Simple Receive sample is waiting on the other machine at IP address 192.168.1.1. The DOCA Simple Receive sample is launched on a system with NIC at 17:00.1 PCIe address and GPU at ca:00.0 PCIe address: ## DOCA Simple Receive ```plaintext # Ensure DOCA and DPDK are in the LD_LIBRARY_PATH environment variable $ sudo ./build/doca_gpunetio_simple_receive -n 17:00.1 -g ca:00.0 [11:00:30:397080][2328673][DOCA][INF][gpunetio_simple_receive_main.c:159][main] Starting the sample [11:00:30:652622][2328673][DOCA][INF][gpunetio_simple_receive_main.c:189][main] Sample configuration: GPU ca:00.0 NIC 17:00.1 EAL: Detected CPU lcores: 128 EAL: Detected NUMA nodes: 2 EAL: Detected shared linkage of DPDK EAL: Multi-process socket /var/run/dpdk/rte/mp_socket EAL: Selected IOVA mode 'PA' EAL: VFIO support initialized TELEMETRY: No legacy callbacks, legacy socket not created EAL: Probe PCI driver: mlx5_pci (15b3:a2d6) device: 0000:17:00.1 (socket 0) [11:00:31:036760][2328673][DOCA][WRN][engine_model.c:72][adapt_queue_depth] adapting queue depth to 128. [11:00:31:928926][2328673][DOCA][WRN][engine_port.c:321][port_driver_process_properties] detected representor used in VNF mode (driver port id 0) EAL: Probe PCI driver: gpu_cuda (10de:20b5) device: 0000:ca:00.0 (socket 1) [11:00:31:977261][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:425][create_rxq] Creating Sample Eth Rxq [11:00:31:977841][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:466][create_rxq] Mapping receive queue buffer (0x0x7f86cc000000 size 33554432B) with nvidia-peermem mode [11:00:32:043182][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:610][gpunetio_simple_receive] Launching CUDA kernel to receive packets [11:00:32:055193][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:614][gpunetio_simple_receive] Waiting for termination Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 Thread 0 received UDP packet with Eth src 10:70:fd:fa:77:f5 - Eth dst 10:70:fd:fa:77:e9 # Type Ctrl+C to kill the sample [11:01:44:265141][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:45][signal_handler] Signal 2 received, preparing to exit! [11:01:44:265189][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:620][gpunetio_simple_receive] Exiting from sample [11:01:44:265533][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:362][destroy_rxq] Destroying Rxq [11:01:44:307829][2328673][DOCA][INF][gpunetio_simple_receive_sample.c:631][gpunetio_simple_receive] Sample finished successfully [11:01:44:307861][2328673][DOCA][INF][gpunetio_simple_receive_main.c:204][main] Sample finished successfully ``` --- ## RDMA Client Server This sample exhibits how to use the GPUNetIO RDMA API to receive and send/write with immediate using a single RDMA queue. The server has a GPU buffer array A composed by GPU_BUF_NUM doca_gpu_buf elements, each 1kB in size. The client has two GPU buffer arrays, B and C, each composed by GPU_BUF_NUM doca_gpu_buf elements, each 512B in size. The goal is for the client to fill a single server buffer of 1kB with two GPU buffers of 512B as illustrated in the following figure: ![](server_buffer.jpg) To show how to use RDMA write and send, even buffers are sent from the client with write immediate, while odd buffers are sent with send immediate. In both cases, the server must pre-post the RDMA receive operations. For each buffer, the CUDA kernel code repeats the handshake: ![](handshake.png) Once all buffers are filled, the server double checks that all values are valid. The server output should be as follows: ## DOCA RDMA Server side ```plaintext # Ensure DOCA and DPDK are in the LD_LIBRARY_PATH environment variable $ cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_rdma_client_server_write $ ./build/doca_gpunetio_rdma_client_server_write -gpu 17:00.0 -d mlx5_0 [14:11:43:000930][1173110][DOCA][INF][gpunetio_rdma_client_server_write_main.c:250][main] Starting the sample ... [14:11:43:686610][1173110][DOCA][INF][rdma_common.c:91][oob_connection_server_setup] Listening for incoming connections [14:11:45:681523][1173110][DOCA][INF][rdma_common.c:105][oob_connection_server_setup] Client connected at IP: 192.168.2.28 and port: 46274 ... [14:11:45:771807][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:644][rdma_write_server] Before launching CUDA kernel, buffer array A is: [14:11:45:771822][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:646][rdma_write_server] Buffer 0 -> offset 0: 1111 | offset 128: 1111 [14:11:45:771837][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:646][rdma_write_server] Buffer 1 -> offset 0: 1111 | offset 128: 1111 [14:11:45:771851][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:646][rdma_write_server] Buffer 2 -> offset 0: 1111 | offset 128: 1111 [14:11:45:771864][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:646][rdma_write_server] Buffer 3 -> offset 0: 1111 | offset 128: 1111 RDMA Recv 2 ops completed with immediate values 0 and 1! RDMA Recv 2 ops completed with immediate values 1 and 2! RDMA Recv 2 ops completed with immediate values 2 and 3! RDMA Recv 2 ops completed with immediate values 3 and 4! [14:11:45:781561][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:671][rdma_write_server] After launching CUDA kernel, buffer array A is: [14:11:45:781574][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:673][rdma_write_server] Buffer 0 -> offset 0: 2222 | offset 128: 3333 [14:11:45:781583][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:673][rdma_write_server] Buffer 1 -> offset 0: 2222 | offset 128: 3333 [14:11:45:781593][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:673][rdma_write_server] Buffer 2 -> offset 0: 2222 | offset 128: 3333 [14:11:45:781602][1173110][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:673][rdma_write_server] Buffer 3 -> offset 0: 2222 | offset 128: 3333 [14:11:45:781640][1173110][DOCA][INF][gpunetio_rdma_client_server_write_main.c:294][main] Sample finished successfully ``` On the other side, assuming the server is at IP address 192.168.2.28, the client output should be as follows: ## DOCA RDMA Client side # Ensure DOCA and DPDK are in the LD_LIBRARY_PATH environment variable ```plaintext $ cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_rdma_client_server_write $ ./build/doca_gpunetio_rdma_client_server_write -gpu 17:00.0 -d mlx5_0 -c 192.168.2.28 [16:08:22:335744][160913][DOCA][INF][gpunetio_rdma_client_server_write_main.c:197][main] Starting the sample ... [16:08:25:753316][160913][DOCA][INF][rdma_common.c:147][oob_connection_client_setup] Connected with server successfully ...... Client waiting on flag 7f6596735000 for server to post RDMA Recvs Thread 0 post rdma write imm 0 Thread 1 post rdma write imm 0 Client waiting on flag 7f6596735001 for server to post RDMA Recvs Thread 0 post rdma send imm 1 Thread 1 post rdma send imm 1 Client waiting on flag 7f6596735002 for server to post RDMA Recvs Thread 0 post rdma write imm 2 Thread 1 post rdma write imm 2 Client waiting on flag 7f6596735003 for server to post RDMA Recvs Thread 0 post rdma send imm 3 Thread 1 post rdma send imm 3 [16:08:25:853454][160913][DOCA][INF][gpunetio_rdma_client_server_write_main.c:241][main] Sample finished successfully ``` ## Note With RDMA, the network device must be specified by name (e.g., mlx5_0 ) instead of the PCIe address (as is the case for Ethernet). It is also possible to enable the RDMA CM mode, establishing two connections with the same RDMA GPU handler. An example on the client side: ## DOCA RDMA Client side with CM ```plaintext # Ensure DOCA and DPDK are in the LD_LIBRARY_PATH environment variable $ cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_rdma_client_server_write $ ./build/samples/doca_gpunetio_rdma_client_server_write -d mlx5_0 -gpu 17:00.0 -gid 3 -c 10.137.189.28 -cm --server-addr-type ipv4 --server-addr 192.168.2.28 [11:30:34:489781][3853018][DOCA][INF][gpunetio_rdma_client_server_write_main.c:461][main] Starting the sample ... [11:30:35:038828][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:950][rdma_write_client] Client is waiting for a connection establishment [11:30:35:082039][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:963][rdma_write_client] Client - Connection 1 is established ... [11:30:35:095282][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:1006][rdma_write_client] Establishing connection 2.. [11:30:35:097521][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:1016][rdma_write_client] Client is waiting for a connection establishment [11:30:35:102718][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:1029][rdma_write_client] Client - Connection 2 is established [11:30:35:102783][3853018][DOCA][INF][gpunetio_rdma_client_server_write_sample.c:1046][rdma_write_client] Client, terminate kernels Client waiting on flag 7f16067b5000 for server to post RDMA Recvs Thread 0 post rdma write imm 0 Thread 1 post rdma write imm 1 Client waiting on flag 7f16067b5001 for server to post RDMA Recvs Thread 0 post rdma send imm 1 Thread 1 post rdma send imm 2 Client waiting on flag 7f16067b5002 for server to post RDMA Recvs Thread 0 post rdma write imm 2 Thread 1 post rdma write imm 3 Client waiting on flag 7f16067b5003 for server to post RDMA Recvs Thread 0 post rdma send imm 3 Thread 1 post rdma send imm 4 Client posted and completed 4 RDMA commits on connection 0. Waiting on the exit flag. Client waiting on flag 7f16067b5000 for server to post RDMA Recvs Thread 0 post rdma write imm 0 Thread 1 post rdma write imm 1 Client waiting on flag 7f16067b5001 for server to post RDMA Recvs Thread 0 post rdma send imm 1 Thread 1 post rdma send imm 2 Client waiting on flag 7f16067b5002 for server to post RDMA Recvs Thread 0 post rdma write imm 2 Thread 1 post rdma write imm 3 Client waiting on flag 7f16067b5003 for server to post RDMA Recvs Thread 0 post rdma send imm 3 Thread 1 post rdma send imm 4 Client posted and completed 4 RDMA commits on connection 1. Waiting on the exit flag. [11:30:35:122448][3853018][DOCA][INF][gpunetio_rdma_client_server_write_main.c:512][main] Sample finished successfully ``` In case of RDMA CM, the command option -cm must be specified on the server side. > **Warning:** Printing from a CUDA kernel is not recommended for performance. It may make sense for debugging purposes and for simple samples like this one. --- ## GPU DMA Copy This sample exhibits how to use the DOCA DMA and DOCA GPUNetIO libraries to DMA copy a memory buffer from the CPU to the GPU (with DOCA DMA CPU functions) and from the GPU to the CPU (with DOCA GPUNetIO DMA device functions) from a CUDA kernel. This sample requires a DPU as it uses the DMA engine on it. ## DOCA RDMA Client side ```plaintext $ cd /opt/mellanox/doca/samples/doca_gpunetio/gpunetio_dma_memcpy # Build the sample and then execute $ ./build/doca_gpunetio_dma_memcpy -g 17:00.0 -n ca:00.0 [15:44:04:189462][862197][DOCA][INF][gpunetio_dma_memcpy_main.c:164][main] Starting the sample EAL: Detected CPU lcores: 64 EAL: Detected NUMA nodes: 2 EAL: Detected shared linkage of DPDK EAL: Selected IOVA mode 'VA' EAL: No free 2048 kB hugepages reported on node 0 EAL: No free 2048 kB hugepages reported on node 1 EAL: VFIO support initialized TELEMETRY: No legacy callbacks, legacy socket not created EAL: Probe PCI driver: gpu_cuda (10de:2331) device: 0000:17:00.0 (socket 0) [15:44:04:857251][862197][DOCA][INF][gpunetio_dma_memcpy_sample.c:211][init_sample_mem_objs] The CPU source buffer value to be copied to GPU memory: This is a sample piece of text from CPU [15:44:04:857359][862197][DOCA][WRN][doca_mmap.cpp:1743][doca_mmap_set_memrange] Mmap 0x55aec6206140: Memory range isn't cache-line aligned - addr=0x55aec52ceb10. For best performance align address to 64B [15:44:04:858839][862197][DOCA][INF][gpunetio_dma_memcpy_sample.c:158][init_sample_mem_objs] The GPU source buffer value to be copied to CPU memory: This is a sample piece of text from GPU [15:44:04:921702][862197][DOCA][INF][gpunetio_dma_memcpy_sample.c:570][submit_dma_memcpy_task] Success, DMA memcpy job done successfully CUDA KERNEL INFO: The GPU destination buffer value after the memcpy: This is a sample piece of text from CPU CPU received message from GPU: This is a sample piece of text from GPU [15:44:04:930087][862197][DOCA][INF][gpunetio_dma_memcpy_sample.c:364][gpu_dma_cleanup] Cleanup DMA ctx with GPU data path [15:44:04:932658][862197][DOCA][INF][gpunetio_dma_memcpy_sample.c:404][gpu_dma_cleanup] Cleanup DMA ctx with CPU data path [15:44:04:954156][862197][DOCA][INF][gpunetio_dma_memcpy_main.c:197][main] Sample finished successfully ```