nvbandwidth

repository·main·Indexed 20 days ago

https://github.com/nvidia/nvbandwidth

A tool for measuring memory bandwidth across NVIDIA GPUs, supporting various memcpy patterns and links using copy engines (CE) or kernel copy methods (SM). It provides benchmarking for both single-node and multi-node environments via MPI and IMEX (NVIDIA Internode Memory Exchange), including support for pairwise GPU testing and pointer-chasing latency measurements.

Tokens
3.5K
Snippets
13
Records
19
Agent score
23%

What's inside nvbandwidth

  1. Interpret Unidirectional and Bidirectional bandwidth results

    main

    Unidirectional Tests

    Unidirectional tests measure the bandwidth between each pair in the output matrix individually. Traffic is sent in one direction at a time and is not simultaneous.

    Bidirectional Tests

    In bidirectional tests, nvbandwidth drives traffic in both directions concurrently. One stream is designated as the "measured stream" while another stream generates interfering traffic in the opposite direction.

    Crucial Interpretation Note: The reported bidirectional GB/s represents the per-direction bandwidth under concurrent opposite-direction copy, not an aggregated sum of both directions.

    Implementation Details:

    • CE Bidirectional: Stream 0 (measured) performs writes while the interfering stream performs reads (and vice versa for Device-to-Host).
    • SM Bidirectional: A kernel is launched where alternating thread warps copy data in alternating directions.
  2. How latency is measured via pointer chasing

    main

    To provide realistic memory latency measurements that prevent prefetching optimizations, nvbandwidth uses a pointer chasing methodology rather than sequential access:

    1. Setup: Memory is organized as a linked list where each node contains a pointer to the next.
    2. Pattern: The chain follows a strided pattern: Node[i] -> Node[(i + stride) % total_nodes].
    3. Execution: A kernel follows this chain for a specified number of accesses.
    4. Measurement: Total time is divided by the number of accesses to find latency per access.

    Key characteristics of this measurement:

    • TLB costs are excluded: The same buffer is reused to keep TLB entries warm, ensuring address translation overhead does not inflate the reported latency.
    • Data cache hits are prevented: The random pointer chasing pattern is designed to bypass data cache benefits.
  3. Understand the difference between CE and SM copy types

    main

    nvbandwidth supports two methods for performing data copies:

    1. Copy Engine (CE) copies: These use standard memcpy APIs.
    2. Streaming Multiprocessor (SM) copies: These use custom CUDA kernels.

    Note on SM copy sizing: To ensure uniform reporting, SM copies truncate the requested copy size to fit the target device's architecture. The actual byte size used is calculated as: (threadsPerBlock * deviceSMCount) * floor(copySize / (threadsPerBlock * deviceSMCount)) where threadsPerBlock is fixed at 512.

  4. Use pair sampling for large multinode tests

    main

    To avoid the time-intensive process of testing every possible GPU pair in large clusters, use the --targetNumPairs option to perform intelligent sampling.

    Sampling Behavior

    • --targetNumPairs -1 (Default): Tests all possible pairs ($N imes (N-1)$ for $N$ GPUs).
    • --targetNumPairs <number>: Tests exactly that many pairs using a two-phase algorithm:
      1. GPU Coverage Phase: Ensures every GPU participates in at least one test pair.
      2. Random Filling Phase: Fills remaining slots with random pairs to maximize topology coverage.

    Examples

    Test 20 selected pairs on a 32-GPU system:

    mpirun ... ./nvbandwidth -p multinode --targetNumPairs 20

    Test ~10% of pairs (100 pairs) on a 32-GPU system:

    mpirun ... ./nvbandwidth -p multinode --targetNumPairs 100

    Note: --targetNumPairs only affects multinode device-to-device tests. It is ignored in single-node mode.

    mpirun -n 32 ./nvbandwidth -p multinode --targetNumPairs 20
  5. Find GPU UUIDs for pairwise testing

    main

    To use the --pair option, you must provide the exact GPU UUIDs in the format GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

    Single-node

    Use nvidia-smi -L to list all GPUs and their UUIDs:

    nvidia-smi -L

    Multi-node

    Use mpirun with your hostfile to query all nodes. To ensure you see all GPUs on every node, match the number of processes (-n) to the total number of GPUs in the cluster and use --map-by ppr:<gpus_per_node>:node:

    # Example: 4 GPUs/node, 2 nodes = 8 total processes
    mpirun --hostfile /etc/nvidia-imex/nodes_config.cfg \
        --map-by ppr:4:node -n 8 \
        nvidia-smi -L
    nvidia-smi -L
  6. Run multinode bandwidth benchmarks

    main

    Multinode testing requires the IMEX (NVIDIA Internode Memory Exchange) service and an MPI environment.

    Prerequisites

    1. Build with multinode support: cmake -DMULTINODE=1 .
    2. Start IMEX service: sudo systemctl start nvidia-imex.service
    3. Configure nodes: Ensure /etc/nvidia-imex/nodes_config.cfg contains the cluster node IP addresses.

    Execution

    Run one process per GPU using mpirun. You must specify the network interface used by your cluster (e.g., via -mca btl_tcp_if_include).

    mpirun --allow-run-as-root --map-by ppr:4:node --bind-to core -np 8 \
        --report-bindings -q -mca btl_tcp_if_include <interface_name> \
        --hostfile /etc/nvidia-imex/nodes_config.cfg ./nvbandwidth -p multinode

    Note: Replace <interface_name> with your actual network interface (e.g., from ip link show).

    Cluster Best Practices

    • Rank Mapping: Run one MPI rank per GPU. Running more than the GPU count is invalid. Running fewer is valid (processes will take consecutive GPUs starting from GPU 0).
    • Output: In MPI mode, only rank 0 outputs stdout. stderr is output by all processes.
    • Testcases: It is recommended to only run multinode* testcases under MPI.
    • Local Testing: You can simulate multinode behavior on a single machine (Ampere+ GPU required) using: mpirun -n 4 ./nvbandwidth -p multinode.
    mpirun --allow-run-as-root --map-by ppr:4:node --bind-to core -np 8 --report-bindings -q -mca btl_tcp_if_include enP5p9s0 --hostfile /etc/nvidia-imex/nodes_config.cfg ./nvbandwidth -p multinode
  7. Perform pairwise GPU testing

    main

    The --pair option restricts device-to-device tests to specific GPUs, which is useful for isolating a single link.

    Single-node Pairwise

    Pass both UUIDs directly to the command:

    ./nvbandwidth -t <testcase> --pair <UUID-0> <UUID-1>

    Multinode Pairwise

    Run with exactly 2 MPI ranks (one per GPU). Each rank must be assigned the UUID of the GPU it will use:

    mpirun -n 2 ./nvbandwidth -t <multinode_testcase> --pair <UUID-0> <UUID-1>

    Supported testcase families for --pair:

    • device_to_device_memcpy_*
    • device_to_device_bidirectional_memcpy_*
    • device_to_device_latency_sm / device_to_device_latency_tma
    • multinode_device_to_device_memcpy_*
    • multinode_device_to_device_bidirectional_memcpy_*
    ./nvbandwidth -t device_to_device_memcpy_read_sm --pair <GPU-UUID-0> <GPU-UUID-1>
  8. Install MPI to resolve libmpi_cxx.so missing errors

    main

    If ldd nvbandwidth reports libmpi_cxx.so.X => not found, you need to install the OpenMPI development packages.

    Ubuntu/Debian:

    sudo apt-get install openmpi-bin libopenmpi-dev

    Red Hat/CentOS/Fedora:

    # RHEL/CentOS 7/8
    sudo yum install openmpi-devel
    
    # Fedora
    sudo dnf install openmpi-devel
    # Ubuntu/Debian
    sudo apt-get install openmpi-bin libopenmpi-dev
    
    # RHEL/CentOS
    sudo yum install openmpi-devel
    
    # Fedora
    sudo dnf install openmpi-devel
  9. Install and build nvbandwidth

    main

    Requirements

    • Linux (primary platform).
    • CUDA Toolkit: version 11.x or above. (Multinode requires 12.3+ and 550+ driver).
    • C++17 compiler: GCC 7.x+ (Linux) or MSVC 2019+ (Windows).
    • CMake: version 3.20 or above (3.24+ recommended).
    • MPI: Required for multinode builds.

    On Linux, ensure nvcc is in your $PATH.

    Build Single-node

    cmake .
    make

    On Ubuntu/Debian, use the provided utility script to automate installation and building:

    sudo ./debian_install.sh

    Build Multinode

    To enable multinode support, pass the MULTINODE=1 flag to CMake:

    cmake -DMULTINODE=1 .
    make
    cmake -DMULTINODE=1 .
    make
  10. Verify system requirements for NVBandwidth

    main

    NVBandwidth requirements depend on whether you are performing single-node or multi-node testing:

    Multi-node requirements:

    • CUDA Toolkit 12.3 & driver and above
    • IMEX setup
    • Proper MPI configuration

    Single-node requirements:

    • CUDA Toolkit 11.x or above

    To enable multi-node support during the build process, ensure you are using CUDA 12.3+ and pass the MULTINODE=1 flag to CMake.

    # Ensure CUDA 12.3+ is in use
    $ nvcc --version
    
    # Build with multi-node support
    $ cmake -DMULTINODE=1
  11. Fix CUDA_ERROR_NO_DEVICE (no CUDA device detected)

    main

    This error occurs when the NVIDIA driver is missing, GPUs are not detected, or there is a CUDA driver/toolkit mismatch.

    Verification Steps:

    1. Check GPU detection: nvidia-smi
    2. Verify driver installation:
      • Check version: cat /proc/driver/nvidia/version
      • Check loaded modules: lsmod | grep nvidia
      • Check package: dpkg -l | grep nvidia-driver
    3. Check CUDA setup:
      • Driver version: nvidia-smi | grep "CUDA Version"
      • Runtime version: nvcc --version

    Solution: Install or reinstall the NVIDIA driver and CUDA toolkit. For detailed diagnostics, run nvidia-bug-report.sh.

    $ nvidia-smi
    $ cat /proc/driver/nvidia/version
    $ lsmod | grep nvidia
    $ dpkg -l | grep nvidia-driver
    $ nvidia-smi | grep "CUDA Version"
    $ nvcc --version
    $ nvidia-bug-report.sh
  12. Fix Unsupported gpu architecture error during compilation

    main

    If you encounter nvcc fatal : Unsupported gpu architecture, it is likely because you are targeting an older architecture with a newer CUDA version.

    Solution:

    • For older architectures (Volta, Maxwell, Pascal), use CUDA < 13.0.
    • For Hopper architecture, specify the architecture explicitly in CMake: cmake -DCMAKE_CUDA_ARCHITECTURES=sm_90
    cmake -DCMAKE_CUDA_ARCHITECTURES=sm_90