16. Displaying GDS NVIDIA FS Driver Statistics#
GDS exposes the IO statistics information on the procfs file system.
To display driver statistics, run the following command.
$ cat /proc/driver/nvidia-fs/stats
Review the output, for example:
GDS Version: 1.0.0.71 NVFS statistics(ver: 4.0) NVFS Driver(version: 2:7:47) Mellanox PeerDirect Supported: True IO stats: Enabled, peer IO stats: Enabled Logging level: info Active Shadow-Buffer (MiB): 0 Active Process: 0 Reads : n=0 ok=0 err=0 readMiB=0 io_state_err=0 Reads : Bandwidth(MiB/s)=0 Avg-Latency(usec)=0 Sparse Reads : n=6 io=0 holes=0 pages=0 Writes : n=0 ok=0 err=0 writeMiB=0 io_state_err=0 pg-cache=0 pg-cache-fail=0 pg-cache-eio=0 Writes : Bandwidth(MiB/s)=0 Avg-Latency(usec)=0 Mmap : n=183 ok=183 err=0 munmap=183 Bar1-map : n=183 ok=183 err=0 free=165 callbacks=18 active=0 Error : cpu-gpu-pages=0 sg-ext=0 dma-map=0 dma-ref=0 Ops : Read=0 Write=0 GPU 0000:be:00.0 uuid:87e5c586-88ed-583b-df45-fcee0f1e7917 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:e7:00.0 uuid:029faa3b-cb0d-2718-259c-6dc650c636eb : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:5e:00.0 uuid:39eeb04b-1c52-81cc-d76e-53d03eb6ed32 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:57:00.0 uuid:a99a7a93-7801-5711-258b-c6aca4fe6d85 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:39:00.0 uuid:d22b0bc4-cdb1-65ac-7495-3570e5860fda : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:34:00.0 uuid:e11b33d9-60f7-a721-220a-d14e5b15a52c : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=128 cross_root_port(%)=0 GPU 0000:b7:00.0 uuid:e8630cd2-5cb7-cab7-ef2e-66c25507c119 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:e5:00.0 uuid:b3d46477-d54f-c23f-dc12-4eb5ea172af6 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:e0:00.0 uuid:7a10c7bd-07e0-971b-a19c-61e7c185a82c : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:bc:00.0 uuid:bb96783c-5a46-233a-cbce-071aeb308083 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:e2:00.0 uuid:b6565ee8-2100-7009-bcc6-a3809905620d : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=2 cross_root_port(%)=0 GPU 0000:5c:00.0 uuid:5527d7fb-a560-ab42-d027-20aeb5512197 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:59:00.0 uuid:bb734f6b-24ad-2f83-86c3-6ab179bce131 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:3b:00.0 uuid:0ef0b9ee-bb8f-cdae-4535-c0d790b2c663 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:b9:00.0 uuid:ad59f685-5836-c2ea-2c79-3c95bea23f0d : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0 GPU 0000:36:00.0 uuid:fda65234-707b-960a-d577-18c519301848 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
16.1. nvidia-fs Statistics#
The following table describes nvidia-fs statistics.
Type |
Statistics |
Description |
|---|---|---|
Reads |
|
Total number of read requests. |
|
Total number of successful read requests. |
|
|
Total number of read errors. |
|
Readmb (mb) |
Total data read into the GPUs. |
|
|
Read errors that were seen. Some pages might have been in the page cache. |
|
Reads |
Bandwidth (MB/s) |
Active Read Bandwidth when IO is in flight. This is the period from when IO was submitted to the GDS kernel driver until the IO completion was received by the GDS kernel driver. There was no userspace involved. |
Avg-Latency (usec) |
Active Read latency when IO is in flight. This is from the period from when IO was submitted to the GDS kernel driver until the IO completion is received by the GDS kernel driver. There was no userspace involved. |
|
Sparse Reads |
|
Total number of sparse read requests. |
|
Total number of holes that were observed during reads. |
|
|
Total number of pages that span the holes. |
|
Writes |
|
Total number of write requests. |
|
Total number of successful write requests. |
|
|
Total number of write errors. |
|
Writemb (mb) |
Total data that was written from the GPUs to the disk. |
|
|
Write errors that were seen. Some pages might have been in the page cache. |
|
|
Total number of write requests that were found in the page cache. |
|
|
Total number of write requests that were found in the page cache but could not be flushed. |
|
|
Total number of write requests that were found in the |
|
Writes |
Bandwidth (MB/s) |
Active Write Bandwidth when IO is in flight. This is the period from when IO is submitted to the GDS kernel driver until the IO completion is received by the GDS kernel driver. There was no userspace involved. |
Avg-Latency (\(\mu\)sec) |
Active Write latency when IO is in flight. This is the period from when IO is submitted to the GDS kernel driver until the IO completion is received by the GDS kernel driver. There was no userspace involved. |
|
Mmap |
|
Total number of mmap system calls that were issued. |
|
Total number of successful mmap system calls. |
|
|
Errors that were observed through the mmap system call. |
|
|
Total number of munmap that were issued. |
|
Bar-map |
|
Total number of times the GPU BAR memory was pinned. |
|
Total number of times the successful GPU BAR memory was pinned. |
|
|
Total errors that were observed during the BAR1 pinning. |
|
|
Total number of times the BAR1 memory was unpinned. |
|
|
Total number of times the NVIDIA kernel driver invoked callback to the GDS driver. This is invoked on the following instances:
|
|
|
Active number of BAR1 memory that was pinned. (This value is the total number and not the total memory.) |
|
Error |
|
Number of IO requests that had a mix of CPU-GPU pages when |
|
Scatterlist that could not be expanded because the number of GPU pages is greater than |
|
|
A DMA map error. |
|
Ops |
Read |
Total number of Active Read IO in flight. |
Write |
Total number of Active Write IO in flight. |
16.2. Analyze Statistics for Each GPU#
You can analyze the statistics for each GPU to better understand what is happening in that GPU.
Consider the following example output:
GPU 0000:5e:00:0 uuid:dc87fe99-4d68-247b-b5d2-63f96d2adab1 : pinned_MB=0 cache_MB=0 max_pinned_MB=79
GPU 0000:b7:00:0 uuid:b3a6a195-d08c-09d1-bf8f-a5423c277c04 : pinned_MB=0 cache_MB=0 max_pinned_MB=76
GPU 0000:e7:00:0 uuid:7c432aed-a612-5b18-76e7-402bb48f21db : pinned_MB=0 cache_MB=0 max_pinned_MB=80
GPU 0000:57:00:0 uuid:aa871613-ee53-9a0c-a546-851d1afe4140 : pinned_MB=0 cache_MB=0 max_pinned_MB=80
In this sample output, 0000:5e:00:0, is the PCI BDF of the GPU with the Dc87fe99-4d68-247b-b5d2-63f96d2adab1
UUID. This is the same UUID that can be used to observe nvidia-smi statistics for this GPU.
Here is some additional information about the statistics:
pinned-MBshows the active GPU memory that is pinned by usingnvidia_p2p_get_pagesfrom the GDS driver in MB across all active processes.cache_MBshows the active GPU memory that is pinned by usingnvidia_p2p_get_pages, but this memory is used as the internal cache by GDS across all active processes.max_pinned_MBshows the max GPU memory that is pinned by GDS at any point in time on this GPU across multiple processes.This value indicates that the max BAR size and administrator can be used for system sizing purposes.
16.3. Resetting the nvidia-fs Statistics#
To reset the nvidia-fs statistics, run the following commands:
$ sudo bash
$ echo 1 >/proc/driver/nvidia-fs/stats
16.4. Checking Peer Affinity Stats for a Kernel File System and Storage Drivers#
The following proc files contain information about peer affinity DMA statistics via nvidia-fs callbacks:
nvidia-fs/statsnvidia-fs/peer_affinitynvidia-fs/peer_distance
To enable the statistics, run the following command:
$ sudo bash
$ echo 1 > /sys/module/nvidia_fs/parameters/peer_stats_enabled
To view consolidated statistics as a regular user, run the following command:
$ cat /proc/driver/nvidia-fs/stats
Sample output:
GDS Version: 1.0.0.71
NVFS statistics(ver: 4.0)
NVFS Driver(version: 2:7:47)
Mellanox PeerDirect Supported: True
IO stats: Enabled, peer IO stats: Enabled
Logging level: info
Active Shadow-Buffer (MiB): 0
Active Process: 0
Reads : n=0 ok=0 err=0 readMiB=0 io_state_err=0
Reads : Bandwidth(MiB/s)=0 Avg-Latency(usec)=0
Sparse Reads : n=6 io=0 holes=0 pages=0
Writes : n=0 ok=0 err=0 writeMiB=0 io_state_err=0 pg-cache=0 pg-cache-fail=0 pg-cache-eio=0
Writes : Bandwidth(MiB/s)=0 Avg-Latency(usec)=0
Mmap : n=183 ok=183 err=0 munmap=183
Bar1-map : n=183 ok=183 err=0 free=165 callbacks=18 active=0
Error : cpu-gpu-pages=0 sg-ext=0 dma-map=0 dma-ref=0
Ops : Read=0 Write=0
GPU 0000:be:00.0 uuid:87e5c586-88ed-583b-df45-fcee0f1e7917 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:e7:00.0 uuid:029faa3b-cb0d-2718-259c-6dc650c636eb : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:5e:00.0 uuid:39eeb04b-1c52-81cc-d76e-53d03eb6ed32 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:57:00.0 uuid:a99a7a93-7801-5711-258b-c6aca4fe6d85 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:39:00.0 uuid:d22b0bc4-cdb1-65ac-7495-3570e5860fda : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:34:00.0 uuid:e11b33d9-60f7-a721-220a-d14e5b15a52c : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=128 cross_root_port(%)=0
GPU 0000:b7:00.0 uuid:e8630cd2-5cb7-cab7-ef2e-66c25507c119 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:e5:00.0 uuid:b3d46477-d54f-c23f-dc12-4eb5ea172af6 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:e0:00.0 uuid:7a10c7bd-07e0-971b-a19c-61e7c185a82c : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:bc:00.0 uuid:bb96783c-5a46-233a-cbce-071aeb308083 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:e2:00.0 uuid:b6565ee8-2100-7009-bcc6-a3809905620d : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=2 cross_root_port(%)=0
GPU 0000:5c:00.0 uuid:5527d7fb-a560-ab42-d027-20aeb5512197 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:59:00.0 uuid:bb734f6b-24ad-2f83-86c3-6ab179bce131 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:3b:00.0 uuid:0ef0b9ee-bb8f-cdae-4535-c0d790b2c663 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:b9:00.0 uuid:ad59f685-5836-c2ea-2c79-3c95bea23f0d : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
GPU 0000:36:00.0 uuid:fda65234-707b-960a-d577-18c519301848 : Registered_MiB=0 Cache_MiB=0 max_pinned_MiB=1 cross_root_port(%)=0
The cross_root_port (%) port is the percentage of total DMA traffic through nvidia-fs callbacks, and
this value spans across PCIe root ports between GPU and its peers such as HCA.
This can be a major reason for low throughput on certain platforms.
This does not consider the DMA traffic that is initiated via
cudaMemcpyDeviceToDeviceorcuMemcpyPeerwith the specified GPU.
16.5. Checking the Peer Affinity Usage for a Kernel File System and Storage Drivers#
To get the peer affinity usage for a kernel file system and storage drivers, run the following command:
$ cat /proc/driver/nvidia-fs/peer_affinity
Review the sample output, for example:
GPU P2P DMA distribution based on pci-distance (last column indicates p2p via root complex) GPU :0000:bc:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:e0:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:e5:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:57:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:59:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:be:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:34:00.0 :0 0 1274489 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:e7:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:b7:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:36:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:3b:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:39:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:b9:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:5c:00.0 :0 0 524288 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:e2:00.0 :0 0 39434 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GPU :0000:5e:00.0 :0 0 513889 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Each row represents a GPU entry, and the columns indicate the peer ranks in ascending order. The lower the rank, the better the affinity. Each column entry is the total number of DMA transactions that occurred between the specified GPU and the peers that belong to the same rank.
For example, the row with GPU 0000:34:00.0 has 2621440 IO operations through the peer with rank 3.
Non-zero values in the last column indicate that the IO is routed through the root complex.
Here are some examples:
Run the following command:
$ /usr/local/cuda-x.y/gds/samples /mnt/lustre/test 0
$ cat /proc/driver/nvidia-fs/stats
Here is the output:
GDS Version: 1.0.0.71
NVFS statistics(ver: 4.0)
NVFS Driver(version: 2:7:47)
Mellanox PeerDirect Supported: True
IO stats: Enabled, peer IO stats: Enabled
Logging level: info
Active Shadow-Buffer (MB): 0
Active Process: 0
Reads : n=0 ok=0 err=0 readmb=0 io_state_err=0
Reads : Bandwidth(MB/s)=0 Avg-Latency(usec)=0
Sparse Reads : n=0 io=0 holes=0 pages=0
Writes : n=1 ok=1 err=0 writemb=0 io_state_err=0 pg-cache=0 pg-cache-fail=0
pg-cache-eio=0
Writes : Bandwidth(MB/s)=0 Avg-Latency(usec)=0
Mmap : n=1 ok=1 err=0 munmap=1
Bar1-map : n=1 ok=1 err=0 free=1 callbacks=0 active=0
Error : cpu-gpu-pages=0 sg-ext=0 dma-map=0
Ops : Read=0 Write=0
GPU 0000:34:00:0 uuid:98bb4b5c-4576-b996-3d84-4a5d778fa970 : pinned_MB=0 cache_MB=0 max_pinned_MB=0 cross_root_port(%)=100
Run the following command:
$ cat /proc/driver/nvidia-fs/peer_affinity
Here is the output:
GPU P2P DMA distribution based on pci-distance
(last column indicates p2p via root complex)
GPU :0000:b7:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:b9:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:bc:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:be:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e0:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e2:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e5:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e7:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:34:00:0 :0 0 0 0 0 0 0 0 0 0 0 2
GPU :0000:36:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:39:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:3b:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:57:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:59:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5c:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5e:00:0 :0 0 0 0 0 0 0 0 0 0 0 0
In the above example, there are DMA transactions between the GPU (34:00.0) and one of its peers. The peer
device has the highest possible rank which indicates it is farthest away from the respective GPU pci-distance wise.
To check the percentage of traffic, check the cross_root_ port % in /proc/driver/nvidia-fs/stats. In
the third example above, this value is 100%, which means that the peer-to peer-traffic is happening over QPI links.
16.6. Display the GPU-to-Peer Distance Table#
The peer_distance table displays the device-wise IO distribution for each peer with its rank for the
specified GPU, and it complements the rank-based stats.
The peer_distance table displays the device-wise IO distribution for each peer with its rank for the specified GPU. It complements the rank-based stats.
The ranking is done in the following order:
Primary priority given to p2p distance (upper 2 bytes).
Secondary priority is given to the device bandwidth (lower 2 bytes)
For peer paths that cross the root port, a fixed cost for p2p distance (127) is added. This is done to induce a preference for paths under one CPU root port relative to paths that cross the CPU root ports.
Issue the following command:
$ cat /proc/driver/nvidia-fs/peer_distance
Sample output:
gpu peer peerrank p2pdist np2p link gen class
0000:af:00.0 0000:86:00.0 0x820088 0x82 0 0x8 0x3 network
0000:af:00.0 0000:18:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:af:00.0 0000:86:00.1 0x820088 0x82 0 0x8 0x3 network
0000:af:00.0 0000:19:00.1 0x820088 0x82 0 0x8 0x3 network
0000:af:00.0 0000:87:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:af:00.0 0000:19:00.0 0x820088 0x82 0 0x8 0x3 network
0000:3b:00.0 0000:86:00.0 0x820088 0x82 0 0x8 0x3 network
0000:3b:00.0 0000:18:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:3b:00.0 0000:86:00.1 0x820088 0x82 0 0x8 0x3 network
0000:3b:00.0 0000:19:00.1 0x820088 0x82 0 0x8 0x3 network
0000:3b:00.0 0000:87:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:3b:00.0 0000:19:00.0 0x820088 0x82 0 0x8 0x3 network
0000:5e:00.0 0000:86:00.0 0x820088 0x82 0 0x8 0x3 network
0000:5e:00.0 0000:18:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:5e:00.0 0000:86:00.1 0x820088 0x82 0 0x8 0x3 network
0000:5e:00.0 0000:19:00.1 0x820088 0x82 0 0x8 0x3 network
0000:5e:00.0 0000:87:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:5e:00.0 0000:19:00.0 0x820088 0x82 0 0x8 0x3 network
0000:d8:00.0 0000:86:00.0 0x820088 0x82 0 0x8 0x3 network
0000:d8:00.0 0000:18:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:d8:00.0 0000:86:00.1 0x820088 0x82 0 0x8 0x3 network
0000:d8:00.0 0000:19:00.1 0x820088 0x82 0 0x8 0x3 network
0000:d8:00.0 0000:87:00.0 0x820088 0x82 0 0x8 0x3 nvme
0000:d8:00.0 0000:19:00.0 0x820088 0x82 0 0x8 0x3 network
16.7. The GDSIO Tool#
GDSIO is a synthetic IO benchmarking tool that uses cufile APIs for IO. The tool can be found in the
/usr/local/cuda-x.y/tools directory. For more information about how to use this tool, run
/usr/local/cuda-x.y/tools/gdsio -h or review the gdsio section in the /usr/local/cuda-x.y/tools/README
file. In the examples below, the files are created on an ext4 file system.
Issue the following command:
# ./gdsio -f /root/sg/test -d 0 -w 4 -s 1M -x 0 -i 4K:32K:1K -I 1
Sample output:
IoType: WRITE XferType: GPUD Threads: 4 DataSetSize: 671/1024(KiB)
IOSize: 4-32-1(KiB) Throughput: 0.044269 GiB/sec, Avg_Latency:
996.094925 usecs ops: 60 total_time 0.014455 secs
This command does a write IO (-I 1) on a file named test of size 1MiB (-s 1M) with an IO size that varies
between 4KiB to 32 KiB in steps of 1KiB (-i 4K:32K:1K). The transfer is performed using GDS (-x 0) using
4 threads (-w 4) on GPU 0 (-d 0).
Some additional features of the tool are:
Support for read/write at random offsets in a file.
The gdsio tool provides options to perform a read and write to a file at random offsets.
Using -I 2 and -I 3 options does a file read and write operation at random offset respectively but the random offsets are always 4KiB aligned.
# ./gdsio -f /root/sg/test -d 0 -w 4 -s 1M -x 0 -i 4K:32K:1K -I 3 IoType: RANDWRITE XferType: GPUD Threads: 4 DataSetSize: 706/1024(KiB) IOSize: 4-32-1(KiB) Throughput: 0.079718 GiB/sec, Avg_Latency: 590.853274 usecs ops: 44 total_time 0.008446 secs
To perform a random read and write at unaligned 4KiB offsets, the
-Uoption can be used with-I 0or-I 1for read and write, respectively.# ./gdsio -f /root/sg/test -d 0 -w 4 -s 1M -x 0 -i 4K:32K:1K -I 1 -U IoType: RANDWRITE XferType: GPUD Threads: 4 DataSetSize: 825/1024(KiB) IOSize: 4-32-1(KiB) Throughput: 0.055666 GiB/sec, Avg_Latency: 919.112500 usecs ops: 49 total_time 0.014134 secs
Random buffer fill for dedupe and compression.
Using the
-Roption fills the io size buffer (-i) with random data. This random data is then written to the file onto different file offsets.# ./gdsio -f /root/sg/test -d 0 -w 4 -s 1M -x 0 -i 4K:32K:1K -I 1 -R IoType: WRITE XferType: GPUD Threads: 4 DataSetSize: 841/1024(KiB) IOSize: 4-32-1(KiB) Throughput: 0.059126 GiB/sec, Avg_Latency: 788.884580 usecs ops: 69 total_time 0.013565 secs
Using the
-Foption will fill the entire file with random data.# ./gdsio -f /root/sg/test -d 0 -w 4 -s 1M -x 0 -i 4K:32K:1K -I 1 -F IoType: WRITE XferType: GPUD Threads: 4 DataSetSize: 922/1024(KiB) IOSize: 4-32-1(KiB) Throughput: 0.024376 GiB/sec, Avg_Latency: 1321.104532 usecs ops: 73 total_time 0.036072 secs
This is useful for file systems that use dedupe and compression algorithms to minimize disk access. Using random data increases the probability that these file systems will hit the backend disk more often.
Variable block size.
To perform a read or a write on a file, you can specify the block size (- i), which says that IO would be performed in chunks of block sized lengths. To check the stats for what block sizes are used use the
gds_statstool. Ensure the the/etc/cufile.jsonfile has cufile_stats is set to 3:# ./gds_stats -p <pid of the gdsio process> -l 3
Sample output:
0-4(KiB): 0 0 4-8(KiB): 0 17205 8-16(KiB): 0 45859 16-32(KiB): 0 40125 32-64(KiB): 0 0 64-128(KiB): 0 0 128-256(KiB): 0 0 256-512(KiB): 0 0 512-1024(KiB): 0 0 1024-2048(KiB): 0 0 2048-4096(KiB): 0 0 4096-8192(KiB): 0 0 8192-16384(KiB): 0 0 16384-32768(KiB): 0 0 32768-65536(KiB): 0 0 65536-...(KiB): 0 0
The highlighted counters show that, for the command above, the block sizes that are used for file IO are in the 4-32 KiB range.
Verification mode usage and limitations.
To ensure data integrity, there is an option to perform IO in a Write and Read in verify mode using the
-Voption. Here is an example:# ./gdsio -V -f /root/sg/test -d 0 -w 1 -s 2G -o 0 -x 0 -k 0 -i 4K:32K:1K -I 1 IoType: WRITE XferType: GPUD Threads: 1 DataSetSize: 2097144/2097152(KiB) IOSize: 4-32-1(KiB) Throughput: 0.074048 GiB/sec, Avg_Latency: 231.812570 usecs ops: 116513 total_time 27.009349 secs Verifying data IoType: READ XferType: GPUD Threads: 1 DataSetSize: 2097144/2097152(KiB) IOSize: 4-32-1(KiB) Throughput: 0.103465 GiB/sec, Avg_Latency: 165.900663 usecs ops: 116513 total_time 19.330184 secs
The command above will perform a write followed by a read verify test.
While using the verify mode, remember the following points:
read test (-I 0) with verify option (
-V) should be used with files written (-I 1) with the-Voptionread test (-I 2) with verify option (
-V) should be used with files written (-I 3) with the-Voption and using same random seed (-k) using same number of threads, offset, and data sizewrite test (-I 1/3) with verify option (
-V) will perform writes followed by read.Verify mode cannot be used in timed mode (
-Toption).If Verify mode is used in a timed mode, it will be ignored.
The configuration file
GDSIO has an option to configure the parameters that are needed to perform an IO in a configuration file and run the IO using those configurations. The configuration file gives the option of performing multiple jobs, where each job has some different configurations.
The configuration file has global parameters and job specific parameter support. For example, with a configuration file, you can configure each job to perform on a GPU and with a different number of threads. The global parameters, such as IO Size and transfer mode, remain the same for each job. For more information, refer to
/usr/local/cuda-x.y/tools/READMEand/usr/local/cuda-x.y/tools/rw-sample.gdsiofiles. After configuring the parameters, to perform the IO operation using the configuration file, run the following command:# ./gdsio <config file name>
See Tabulated Fields for a list of the tabulated fields.
16.8. Tabulated Fields#
The following table describes the tabulated fields in the output of the #./gdsio <config file name> command.
Global Option |
Description |
|---|---|
|
GDSIO Transfer types:
|
|
IO type, rw=read, rw=write, rw=randread, rw=randwrite |
|
block size, for example, bs=1M, for variable block size can specify range, for example, bs=1M:4M:1M, (1M : start block size, 4M : end block size, 1M :steps in which size is varied). |
|
File-size, for example, size=2G. |
|
Duration in seconds. |
|
Use 1 for enabling verification |
|
Skip cufile buffer registration, ignored in cpu mode. |
|
Set up NVlinks. This field is recommended if p2p traffic is cross node. |
|
Use random seed, for example, 1234. |
|
Refill io buffer after every write. |
|
Fill request buffer with random data. |
|
Use random offsets which are not page-aligned. |
|
File offset to start read/write from. |
Per-Job Options |
Description |
|
NUMA node. |
|
GPU device index (check nvidia-smi). |
|
Number of IO Threads per job. |
|
Directory name where files are present. Each thread will work on a per file basis. |
|
Filename for single file mode, where threads share the same file. (Note: directory mode and filemode should not be used in a mixed manner across jobs). |
|
Memory types to be used. Supported values: 0 - ( |
|
File Descriptor mode. 0 - O_DIRECT (default) 1 - non-O_DIRECT |
16.9. GDSCHECK Tool#
The /usr/local/cuda-x.y/tools/gdscheck.py tool is used to perform a GDS platform check and has other options that can be found by using -h option.
$ ./gdscheck.py -h
usage: gdscheck.py [-h] [-p] [--object] [-f FILE] [-v] [-V] [-t] [-e EXPORT_TOPOLOGY] [-o OUTPUT_FILE] [-d DURATION] [-l {0,1,2}] [-i]
GPUDirectStorage platform checker
options:
-h, --help show this help message and exit
-p gds platform check
--object with -p, show the cuObject platform and configuration
-f FILE gds file check
-v gds version checks
-V gds fs checks
-t print optimal GPU/device pairings (quick view)
-e EXPORT_TOPOLOGY export full topology to JSON file (modes: sysfs, config, latency, cufile)
-o OUTPUT_FILE output JSON file path (required with -e)
-d DURATION duration for latency measurements in seconds (default: 30, max: 3600, use with -e latency)
-l {0,1,2} logging level: 0=error, 1=warning (default), 2=debug (use with -e)
-i show detailed info about topology export mode (use with -e)
Examples:
gdscheck.py -p
gdscheck.py -p --object
gdscheck.py -f gds_latency.bin
gdscheck.py -v
gdscheck.py -V
gdscheck.py -t
gdscheck.py -e cufile -o /etc/topology.json
gdscheck.py -e sysfs -o /etc/topology.json -l 2
sudo gdscheck.py -e latency -o /etc/topology.json -d 120 -l 2
To perform a GDS platform check, issue the following command and expect the output in the following format:
# ./gdscheck.py -p
GDS release version: 1.20.0
nvidia_fs version: 2.31 nvidia_fs minimum version: 2.12
Platform: aarch64
============
ENVIRONMENT:
============
=====================
DRIVER CONFIGURATION:
=====================
NVMe : c2c, nvfs, compat
NVMeOF : compat
SCSI : compat
ScaleFlux CSD : compat
NVMesh : compat
DDN EXAScaler : compat
IBM Spectrum Scale : compat
NFS : compat
BeeGFS : compat
ScaTeFS : compat
VIRTIOFS : compat
PanFS : compat
WekaFS : compat
Userspace RDMA : Unsupported
--Mellanox PeerDirect : Disabled
--rdma library : Not Loaded (libcufile_rdma.so)
--rdma devices : Not configured
--rdma_multipath : Disabled
--rdma_health_monitor : Not initialized
--rdma_dev_addr_list_status : Up: 0 Down: 0
=====================
CUFILE CONFIGURATION:
=====================
properties.use_pci_p2pdma : true
properties.use_compat_mode : true
properties.force_compat_mode : false
properties.gds_rdma_write_support : true
properties.use_poll_mode : false
properties.poll_mode_max_size_kb : 4
properties.max_batch_io_size : 256
properties.max_batch_io_timeout_msecs : 5
properties.max_direct_io_size_kb : 16384
properties.max_device_cache_size_kb : 393216
properties.per_buffer_cache_size_kb : 16384
properties.max_device_pinned_mem_size_kb : 33554432
properties.posix_pool_slab_size_kb : 4 1024 16384
properties.posix_pool_slab_count : 128 64 64
properties.gpu_bounce_buffer_slab_size_kb : 1024 8192 16384 65536
properties.gpu_bounce_buffer_slab_count : 128 8 4 2
properties.rdma_peer_affinity_policy : RoundRobin
properties.rdma_dynamic_routing : 0
properties.rdma_multipath_enabled : false
properties.rdma_max_backup_devices : 2
properties.rdma_io_retry_count : 3
properties.rdma_io_retry_delay_ms : 100
properties.rdma_failback_enabled : true
properties.rdma_failback_delay_ms : 100
properties.rdma_health_check_interval_ms : 100
properties.rdma_async_event_monitoring : true
properties.rdma_unhealthy_threshold : 3
fs.generic.posix_unaligned_writes : false
fs.lustre.posix_gds_min_kb: 0
fs.lustre.use_pci_p2pdma : false
properties.vanilla_posix_io_mode : false
properties.gds_fallback_io : false
fs.beegfs.posix_gds_min_kb: 0
fs.beegfs.use_pci_p2pdma : false
fs.scatefs.posix_gds_min_kb: 0
fs.scatefs.use_pci_p2pdma : false
fs.weka.rdma_write_support: false
fs.nfs.use_pci_p2pdma : false
fs.gpfs.gds_write_support: true
fs.gpfs.gds_async_support: true
fs.gpfs.use_pci_p2pdma : false
fs.virtiofs.use_pci_p2pdma : false
fs.panfs.use_pci_p2pdma : false
profile.cufile_stats : 0
miscellaneous.api_check_aggressive : false
sparse.p2p_compat_enable : true
sparse.min_p2pdma_threshold_kb : 16
miscellaneous.enable_static_routing : false
miscellaneous.static_routing_filepath : /etc/cufile-static-topology.json
miscellaneous.enable_static_config : false
miscellaneous.static_config_filepath : /etc/cufile-static-config.json
properties.allow_rdma_token_reset : false
miscellaneous.rdma_token_reset_timeout_secs : 30
execution.max_io_threads : 4
execution.max_io_queue_depth : 128
execution.parallel_io : true
execution.min_io_threshold_size_kb : 8192
execution.max_request_parallelism : 4
properties.force_odirect_mode : false
properties.prefer_iouring : false
block.raid.use_pci_p2pdma : true
block.raid1.use_pci_p2pdma : false
block.raid10.use_pci_p2pdma : false
block.nvme.use_pci_p2pdma : true
block.nvmeof.use_pci_p2pdma : false
=========
GPU INFO:
=========
GPU index 0 NVIDIA GH200 144G HBM3e bar:disabled bar size (MiB):N/A supports GDS, IOMMU State: Pass-through or Enabled
GPU index 1 NVIDIA GH200 144G HBM3e bar:disabled bar size (MiB):N/A supports GDS, IOMMU State: Pass-through or Enabled
==============
PLATFORM INFO:
==============
Found ACS enabled for switch 0009:00:00.0
Found ACS enabled for switch 0019:00:00.0
IOMMU: Pass-through or enabled
Nvidia Driver Info Status: Supported(Nvidia Open Driver Installed)
Cuda Driver Version Installed: 13040
Platform: ARS-221GL-NHIR, Arch: aarch64(Linux 7.0.0-15-generic)
Platform verification succeeded
Starting with cuObject client v1.4.0 in CUDA 13.5, use -p --object to perform the platform check with cuObject configuration selection:
/usr/local/cuda/gds/tools/gdscheck.py -p --object
To check a custom configuration file:
export CUOBJ_ENV_PATH_JSON=/path/to/cuobj.json
/usr/local/cuda/gds/tools/gdscheck.py -p --object
Use the tool from the matching CUDA installation and the same configuration environment as the application.
The --object option requires -p. Without --object, -p checks the cuFile platform and configuration.
Each invocation initializes its own diagnostic process. Its output describes the configuration selected for that invocation; it does not inspect or change the configuration already active in another application process.
# ./gdscheck.py -p --object
Using legacy GPU bounce buffer configuration
GDS release version: 1.20.0
nvidia_fs version: 2.29 nvidia_fs minimum version: 2.12
Platform: aarch64
=====================
CUOBJECT ENVIRONMENT:
=====================
cuObject client release version: 1.4.0
CUOBJ_ENV_PATH_JSON : cuobj.json
Userspace RDMA : Supported
--Mellanox PeerDirect : Disabled
--DmaBuf support : Enabled
--rdma library : Loaded (libcufile_rdma.so)
--rdma devices : Configured
--rdma_multipath : Disabled
--rdma_health_monitor : Not initialized
--rdma_dev_addr_list_status : Up: 1 Down: 0
=======================
CUOBJECT CONFIGURATION:
=======================
properties.gpu_bounce_buffer_mode : legacy
properties.max_device_cache_size_kb : 131072
properties.per_buffer_cache_size_kb : 1024
properties.max_device_pinned_mem_size_kb : 18014398509481980
properties.rdma_peer_type : dmabuf
properties.rdma_transport_type : DC_V1
properties.rdma_dev_addr_list : mlx5_0
properties.rdma_load_balancing_policy : RoundRobin
properties.rdma_multipath_enabled : false
properties.rdma_max_backup_devices : 2
properties.rdma_io_retry_count : 3
properties.rdma_io_retry_delay_ms : 100
properties.rdma_failback_enabled : true
properties.rdma_failback_delay_ms : 100
properties.rdma_health_check_interval_ms : 100
properties.rdma_async_event_monitoring : true
properties.rdma_unhealthy_threshold : 3
execution.parallel_io : false
profile.cufile_stats : 0
=========
GPU INFO:
=========
GPU index 0 NVIDIA GH200 480GB bar:disabled bar size (MiB):N/A supports GDS, IOMMU State: Pass-through or Enabled
==============
PLATFORM INFO:
==============
Found ACS enabled for switch 0009:00:00.0
IOMMU: Pass-through or enabled
Nvidia Driver Info Status: Supported(Nvidia Open Driver Installed)
Cuda Driver Version Installed: 13030
Platform: QuantaGrid S74G-2U 1S7GZ9Z0002, Arch: aarch64(Linux 6.8.0-111-generic)
Platform verification succeeded
16.10. NFS Support with GPUDirect Storage#
This section provides information about NFS support with GDS.
16.10.1. Install Linux NFS server with RDMA Support on MLNX_OFED 5.3 or Later#
To install a standard Linux kernel-based NFS server with RDMA support, complete the following steps:
Note
The server must have a Mellanox connect-X4/5 NIC with MLNX_OFED 5.3 or later installed.
Issue the following command:
$ ofed_info -s MLNX_OFED_LINUX-5.3-1.0.5.1:
Review the output to ensure that the server was installed.
$ sudo apt-get install nfs-kernel-server $ mkfs.ext4 /dev/nvme0n1 $ mount -o data=ordered /dev/nvme0n1 /mnt/nvme $ cat /etc/exports /mnt/nvme *(rw,async,insecure,no_root_squash,no_subtree_check) $ service nfs-kernel-server restart $ modprobe rpcrdma $ echo rdma 20049 > /proc/fs/nfsd/portlist
16.10.2. Install GPUDirect Storage Support for the NFS Client#
To install a NFS client with GDS support complete the following steps:
Note
The client must have a Mellanox connect-X4/5 NIC with MLNX_OFED 5.3 or later installed.
Issue the following command:
$ ofed_info -s MLNX_OFED_LINUX-5.3-1.0.5.0:
Review the output to ensure that the support exists.
$ sudo apt-get install nfs-common $ modprobe rpcrdma $ mkdir -p /mnt/nfs_rdma_gds $ sudo mount -v -o proto=rdma,port=20049,vers=3 172.16.0.101:/ /mnt/nfs_rdma_gds To mount with nconnect using VAST nfs client package: Eg: client IB interfaces 172.16.0.17 , 172.16.0.18, 172.16.0.19, 172.16.0.20, 172.16.0.21,172.16.0.22,172.16.0.23 172.16.0.24 $ sudo mount -v -o proto=rdma,port=20049,vers=3,nconnect=20,localports=172.16.0.17-172.16.0.24,remoteports=172.16.0.101-172.16.0.120 172.16.0.101:/ /mnt/nfs_rdma_gds
16.11. NFS GPUDirect Storage Statistics and Debugging#
NFS IO can be observed using regular Linux tools that are used for monitoring IO, such as iotop and nfsstat.
To enable NFS RPC stats debugging, run the following command:
$ rpcdebug -v
To observer GDS-related IO stats, run the following command:
$ cat /proc/driver/nvidia-fs/stats
To determine GDS statistics per process, run the following command:
$ /usr/local/cuda-x.y/tools/gds_stats -p <PID> -l 3
16.12. GPUDirect Storage IO Behavior#
This section provides information about IO behavior in GDS.
16.12.1. Read/Write Atomicity Consistency with GPUDirect Storage Direct IO#
In GDS, the max_direct_io_size_kb property controls the IO unit size in which the limitation is issued to the
underlying file system. By default, this value is 16MB. This implies that from a Linux VFS perspective, the atomicity
of size is limited to the max_direct_io_size_kb size and not the original request size. This limitation exists
in the standard GDS path and in compatible mode.
16.12.2. Write with File a Opened in O_APPEND Mode (cuFileWrite)#
For a file that is opened in O_APPEND mode with concurrent writers, if the IO size that is used is larger than the
max_direct_io_size_kb property, because of the write atomicity limitations, the file might have interleaved data
from multiple writers. This cannot be prevented even if the underlying file-system has locking guarantees.
16.12.3. GPU to NIC Peer Affinity#
The library maintains a peer affinity table that is a pci-distance-based ranking for a GPU and the available NICs in the platform for RDMA. Currently, the limitation in the ranking does not consider NUMA attributes for the NICs. For a NIC that does not share a common root port with a GPU, the P2P traffic might get routed cross socket over QPI links even if there is a NIC that resides on the same CPU socket as the GPU.
16.12.4. Compatible Mode with Unregistered Buffers#
Currently, in compatible mode, the IO path with non-registered buffers does not have optimal performance and does buffer allocation and deallocation in every cuFileRead or cuFileWrite.
16.12.5. Unaligned writes with Non-Registered Buffers#
For unaligned writes, using unregistered buffers performance may not be optimal as compared to registered buffers.
16.12.6. Process Hang with NFS#
A process hang is observed in NFS environments when the application crashes.
16.12.7. Tools Support Limitations for CUDA 9 and Earlier#
The gdsio binary has been built against CUDA runtime 10.1 and has a dependency on the CUDA runtime environment to be equal to version 10.1 or later. Otherwise, a driver dependency error will be reported by the tool.
16.13. GDS Statistics for Dynamic Routing#
Dynamic Routing decisions are performed at I/O operation granularity. The GDS User-space Statistics contain a per-GPU counter to indicate the number of I/Os that have been routed using Dynamic Routing.
Entry |
Description |
|---|---|
|
Number of |
There are existing counters in the PER_GPU POOL BUFFER STATS and PER_GPU POSIX POOL BUFFER STATS
from which a user can infer the GPUs that are chosen by dynamic routing for use as the bounce buffers.
Platform has GPUs (0 and 1) not sharing the same PCIe host bridge as the NICs:
"rdma_dev_addr_list": [ "192.168.0.12", "192.168.1.12" ], "rdma_dynamic_routing": true, "rdma_dynamic_routing_order": [ "GPU_MEM_NVLINKS", "GPU_MEM", "SYS_MEM" ]
$ gds_stats -p <process id> -l 3
GPU 0 Read: bw=0 util(%)=0 n=0 posix=0 unalign=0 dr=0 r_sparse=0 r_inline=0 err=0 MiB=0 Write: bw=3.37598 util(%)=532 n=6629 posix=0 unalign=0 dr=6629 err=0 MiB=6629 BufRegister: n=4 err=0 free=0 MiB=4 GPU 1 Read: bw=0 util(%)=0 n=0 posix=0 unalign=0 dr=0 r_sparse=0 r_inline=0 err=0 MiB=0 Write: bw=3.29297 util(%)=523 n=6637 posix=0 unalign=0 dr=6637 err=0 MiB=6637 BufRegister: n=4 err=0 free=0 MiB=4 PER_GPU POOL BUFFER STATS: GPU : 6 pool_size_MiB : 7 usage : 1/7 used_MiB : 1 GPU : 7 pool_size_MiB : 7 usage : 0/7 used_MiB : 0 GPU : 8 pool_size_MiB : 7 usage : 2/7 used_MiB : 2 GPU : 9 pool_size_MiB : 7 usage : 2/7 used_MiB : 2 PER_GPU POSIX POOL BUFFER STATS: PER_GPU RDMA STATS: GPU 0000:34:00.0 : mlx5_3(138:48):0 mlx5_6(265:48):0 GPU 0000:36:00.0 : mlx5_3(138:48):0 mlx5_6(265:48):0 GPU 0000:39:00.0 : mlx5_3(138:48):0 mlx5_6(265:48):0 GPU 0000:3b:00.0 : mlx5_3(138:48):0 mlx5_6(265:48):0 GPU 0000:57:00.0 : mlx5_3(7:48):0 mlx5_6(265:48):0 GPU 0000:59:00.0 : mlx5_3(7:48):0 mlx5_6(265:48):0 GPU 0000:5c:00.0 : mlx5_3(3:48):3318 mlx5_6(265:48):0 GPU 0000:5e:00.0 : mlx5_3(3:48):3318 mlx5_6(265:48):0 GPU 0000:b7:00.0 : mlx5_6(3:48):3316 mlx5_3(265:48):0 GPU 0000:b9:00.0 : mlx5_6(3:48):3317 mlx5_3(265:48):0 GPU 0000:bc:00.0 : mlx5_6(7:48):0 mlx5_3(265:48):0 GPU 0000:be:00.0 : mlx5_6(7:48):0 mlx5_3(265:48):0 GPU 0000:e0:00.0 : mlx5_6(138:48):0 mlx5_3(265:48):0 GPU 0000:e2:00.0 : mlx5_6(138:48):0 mlx5_3(265:48):0 GPU 0000:e5:00.0 : mlx5_6(138:48):0 mlx5_3(265:48):0 GPU 0000:e7:00.0 : mlx5_6(138:48):0 mlx5_3(265:48):0
Platform configuration that has no GPUs sharing the same PCIe host bridge as the NICs and no NVLinks between the GPUs. For such configurations, an admin can set a policy to use system memory other than the default P2P policy.
"rdma_dev_addr_list": [ "192.168.0.12", "192.168.1.12" ], "rdma_dynamic_routing": true, "rdma_dynamic_routing_order": [ "SYS_MEM" ]
PER_GPU STATS: GPU 4 Read: bw=0 util(%)=0 n=0 posix=0 unalign=0 r_sparse=0 r_inline=0 err=0 MiB=0 Write: bw=1.11GiB util(%)=0 n=1023 posix=1023 unalign=1023 dr=1023 err=0 MiB=1023 BufRegister: n=0 err=0 free=0 MiB=0 GPU 8 Read: bw=0 util(%)=0 n=0 posix=0 unalign=0 r_sparse=0 r_inline=0 err=0 MiB=0 Write: bw=1.11GiB util(%)=0 n=1023 posix=1023 unalign=1023 dr=1023 err=0 MiB=1023 BufRegister: n=0 err=0 free=0 MiB=0 PER_GPU POSIX POOL BUFFER STATS: GPU 4 4(KiB) :0/0 1024(KiB) :0/1 16384(KiB) :0/0 GPU 8 4(KiB) :0/0 1024(KiB) :1/1 16384(KiB) :0/0
16.13.1. Peer Affinity Dynamic Routing#
Dynamic Routing decisions are performed at I/O operation granularity. The GDS User-space Statistics contain a per-GPU counter to indicate the number of I/Os that have been routed using Dynamic Routing.
Entry |
Description |
|---|---|
|
Number of |
There are existing counters in the PER_GPU POOL BUFFER STATS and PER_GPU POSIX POOL BUFFER STATS
from which a user can infer the GPUs that are chosen by dynamic routing for use as the bounce buffers.
// "rdma_dev_addr_list": [ "192.168.4.12", "192.168.5.12", "192.168.6.12", "192.168.7.12" ],
cufile.log:
--------------
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:133 Computing GPU->NIC affinity table:
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:34:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:36:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:39:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:3b:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:57:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:59:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:5c:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:5e:00.0 RDMA dev: mlx5_6 mlx5_8 mlx5_7 mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:b7:00.0 RDMA dev: mlx5_6
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:b9:00.0 RDMA dev: mlx5_6
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:bc:00.0 RDMA dev: mlx5_7
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:be:00.0 RDMA dev: mlx5_7
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:e0:00.0 RDMA dev: mlx5_8
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:e2:00.0 RDMA dev: mlx5_8
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:e5:00.0 RDMA dev: mlx5_9
23-02-2021 10:17:49:641 [pid=22436 tid=22436] INFO curdma-ldbal:139 GPU: 0000:e7:00.0 RDMA dev: mlx5_9
A sample from gds_stats showing the GPU to NIC binding during a sample IO test:
PER_GPU RDMA STATS:
GPU 0000:34:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:36:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:39:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:3b:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:57:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:59:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:5c:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:5e:00.0 : mlx5_6(265:48):0 mlx5_8(265:48):0 mlx5_7(265:48):0 mlx5_9(265:48):0
GPU 0000:b7:00.0 : mlx5_6(3:48):22918 mlx5_7(7:48):0 mlx5_8(138:48):0 mlx5_9(138:48):0
GPU 0000:b9:00.0 : mlx5_6(3:48):22949 mlx5_7(7:48):0 mlx5_8(138:48):0 mlx5_9(138:48):0
GPU 0000:bc:00.0 : mlx5_7(3:48):22945 mlx5_6(7:48):0 mlx5_8(138:48):0 mlx5_9(138:48):0
GPU 0000:be:00.0 : mlx5_7(3:48):22942 mlx5_6(7:48):0 mlx5_8(138:48):0 mlx5_9(138:48):0
GPU 0000:e0:00.0 : mlx5_8(3:48):22937 mlx5_9(7:48):0 mlx5_6(138:48):0 mlx5_7(138:48):0
GPU 0000:e2:00.0 : mlx5_8(3:48):22930 mlx5_9(7:48):0 mlx5_6(138:48):0 mlx5_7(138:48):0
GPU 0000:e5:00.0 : mlx5_9(3:48):22922 mlx5_8(7:48):0 mlx5_6(138:48):0 mlx5_7(138:48):0
GPU 0000:e7:00.0 : mlx5_9(3:48):22920 mlx5_8(7:48):0 mlx5_6(138:48):0 mlx5_7(138:48):0
For kernel-based DFS, DDN-Lustre and VAST-NFS, nvidia-fs driver provides a callback to determine the best NIC given a target GPU. The nvidia-fs peer_affinity can be used to track end-to-end IO affinity behavior.
For example, with a routing policy of GPU_MEM_NVLINK, one should not see cross-port traffic as shown in the statistics snippet below:
$ cat /proc/driver/nvidia-fs/peer_affinity
GPU P2P DMA distribution based on pci-distance
(last column indicates p2p via root complex)
GPU :0000:bc:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e0:00.0 :0 0 205305577 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e5:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:57:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:59:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:be:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:34:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e7:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:b7:00.0 :0 0 205279892 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:36:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:3b:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:39:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:b9:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5c:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e2:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5e:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
With routing policy of P2P, one can expect to see cross-port traffic as shown in the following statistics snippet:
dgxuser@e155j-dgx2-c6-u04:~/ssen$ cat /proc/driver/nvidia-fs/peer_affinity
GPU P2P DMA distribution based on pci-distance
(last column indicates p2p via root complex)
GPU :0000:bc:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e0:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e5:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:57:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:59:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:be:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:34:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9186359
GPU :0000:e7:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:b7:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:36:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9191164
GPU :0000:3b:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9194318
GPU :0000:39:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9188836
GPU :0000:b9:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5c:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:e2:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
GPU :0000:5e:00.0 :0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0