NVSHMEM Documentation

repository·devel·Indexed 20 days ago

https://github.com/nvidia/nvshmem

A high-performance communication library for NVIDIA GPU clusters based on the OpenSHMEM model. It enables efficient one-sided communication and collective operations across a partitioned global address space (PGAS) using host, CUDA kernel, and CUDA stream interfaces. The library includes community contributions such as nvshmem4rust for Rust host and CUDA-Oxide device bindings, and NVSHMEM4Py for Python interfaces interoperable with CUDA Python, Numba, PyTorch, CuPy, and CuTe DSL.

Tokens
5.6K
Snippets
17
Records
29
Agent score
69%

What's inside NVSHMEM

  1. What is NVSHMEM?

    devel

    NVSHMEM is an OpenSHMEM-based parallel programming interface designed for scalable NVIDIA GPU clusters. It provides a partitioned global address space (PGAS) across NVIDIA GPUs, enabling applications to perform one-sided transfers, atomics, signaling, synchronization, and collective operations.

    NVSHMEM supports three primary interfaces:

    • Host interface: For CPU-initiated communication.
    • CUDA kernel interface: For GPU-initiated communication within kernels.
    • CUDA stream interface: For stream-ordered communication.
  2. Use the NVSHMEM Rust Host Runtime

    devel

    The nvshmem crate provides Rust FFI bindings and high-level wrappers for the NVSHMEM host-side runtime. It manages process-global NVSHMEM state and symmetric memory allocation.

    Core Components

    • NvshmemRuntime: Initializes the process-global NVSHMEM host state using an explicit InitMethod.
    • SymmetricBuffer<T>: Allocates and frees raw symmetric NVSHMEM memory. The buffer retains the NvshmemRuntime instance until the allocation is freed to ensure the runtime remains valid.
    • sys / bindings: Provides the raw host FFI with exact nvshmem_* and nvshmemx_* names.
    • Safe Wrappers: The crate re-exports prefix-stripped aliases and safe wrappers like my_pe, barrier_all, and int_put_on_stream.

    Lifecycle Management

    NVSHMEM finalizes only after the last NvshmemRuntime handle and all associated SymmetricBuffer instances have been dropped.

  3. Understand NVSHMEM versioning and compatibility

    devel

    NVSHMEM follows semantic versioning using a MAJOR.MINOR.PATCH format. This determines API and ABI compatibility:

    • MAJOR version update: Indicates backward-incompatible API or ABI changes.
    • MINOR version update: Indicates backward-compatible API or ABI additions.
    • PATCH version update: Indicates compatible bug fixes.

    When performing vendor version checks, note that the CMake project version is always formatted as MAJOR.MINOR.PATCH.0 to ensure numeric field consistency for ABI and runtime checks.

  4. Understand the purpose and scope of the `contrib/` directory

    devel

    The contrib/ directory contains community and partner contributions that extend NVSHMEM. These additions include language bindings, communication algorithms, higher-level APIs, tools, or reference implementations.

    Key distinction:

    • contrib/ content: Built on top of NVSHMEM's public APIs (nvshmem.h, nvshmemx.h, and nvshmem_host.h). It is maintained by its respective contributors, not the NVSHMEM core team, and does not follow NVSHMEM release quality standards.
    • NVSHMEM core (src/): Managed by the core team. Changes to core files must follow the standard contribution process in CONTRIBUTING.md.
  5. Initialize NVSHMEM with MPI

    devel

    To initialize NVSHMEM using an MPI communicator, use InitMethod::MpiComm.

    This requires a caller-provided pointer to an already initialized MPI_Comm. You must construct the method using unsafe { MpiComm::from_raw(...) }.

    Note: The caller is responsible for ensuring that the MPI implementation matches the one used by NVSHMEM and that the communicator remains valid for the entire duration of the NVSHMEM runtime lifecycle.

  6. Build and run nvshmem4rust tests

    devel

    To build smoke and performance tests, configure the test targets against an existing NVSHMEM build.

    Running Tests:

    • The smoke test target runs in single-PE unique-ID mode by default.
    • For multi-PE execution, use a supported NVSHMEM launcher and set the environment variable NVSHMEM_RUST_INIT=bootstrap.
    • If the standard NVSHMEM build layout is not used, explicitly set NVSHMEM_HOST_LIB_DIR and NVSHMEM_RUST_TEST_DEVICE_LTOIR.
    cmake -S contrib/nvshmem4rust -B build/nvshmem4rust \
      -DNVSHMEM_SOURCE_DIR="$PWD" \
      -DNVSHMEM_HOME="$PWD/install" \
      -DNVSHMEM_BUILD_DIR="$PWD/build" \
      -DNVSHMEM_BUILD_RUST_DEVICE_TESTS=ON \
      -DNVSHMEM_CUDA_OXIDE_ROOT=/path/to/cuda-oxide \
      -DNVSHMEM_CARGO_OXIDE_EXECUTABLE=/path/to/cargo-oxide \
      -DNVSHMEM_CUDA_HOME=/path/to/cuda \
      -DNVSHMEM_RUST_TEST_ARCH=sm_90
    
    cmake --build build/nvshmem4rust --target test_bindings_rust_cuda_oxide
    cmake --build build/nvshmem4rust --target test_bindings_rust_cuda_oxide_perf
  7. Generate raw host FFI bindings only

    devel

    If you only require raw host FFI declarations without CUDA-Oxide device bindings or the runtime crate, use the NVSHMEM_BUILD_RUST_HOST_ONLY=ON flag. This will generate only nvshmem_host.rs and nvshmem_host_api.rs.

    Note: A CUDA Toolkit installation is still required because the NVSHMEM host headers include CUDA types.

    cmake -S contrib/nvshmem4rust -B build/nvshmem4rust-host \
      -DNVSHMEM_SOURCE_DIR="$PWD" \
      -DNVSHMEM_HOME="$PWD/install" \
      -DNVSHMEM_CUDA_HOME=/path/to/cuda \
      -DNVSHMEM_BUILD_RUST_HOST_ONLY=ON
    
    cmake --build build/nvshmem4rust-host --target build_bindings_rust
  8. Use the nvshmem host runtime crate

    devel

    Host programs can depend on the generated nvshmem_host_runtime crate.

    • API Access: The crate exposes exact C ABI names under nvshmem::sys, as well as prefix-stripped aliases and safe wrappers (e.g., nvshmem::my_pe(), nvshmem::barrier_all()).
    • Module Registration: When using CUDA-Oxide, you must keep the guard returned by unsafe { runtime.register_module(&module) } alive while kernels are calling NVSHMEM. This ensures the module registration is finalized before the runtime or module is dropped.
    • Finalization: Call registration.finalize()? after synchronization if you need to report the finalizer status.
    • Build Configuration: At Cargo build time, set NVSHMEM_HOST_LIB_DIR to the directory containing libnvshmem_host.so.
    • Runtime Configuration: The dynamic loader must resolve NVSHMEM via LD_LIBRARY_PATH, an rpath, or system installation. You can use NVSHMEM_HOST_LIB_PATH to select the specific library the runtime reopens with global symbol visibility.
  9. Configure NVSHMEM Rust build and runtime environment

    devel

    To successfully build and run applications using the nvshmem crate, configure the following environment variables:

    Build Time

    • NVSHMEM_HOST_LIB_DIR: Set this to the directory containing libnvshmem_host.so so Cargo can find the host library.
    • NVSHMEM_CUDA_OXIDE_ROOT: Configured via CMake; the generated Cargo.toml uses this to point cuda-core to the correct location.

    Runtime

    • LD_LIBRARY_PATH: Must include the paths to NVSHMEM and its dependencies so the dynamic loader can resolve them.
    • NVSHMEM_HOST_LIB_PATH: (Optional) Allows you to select the exact host-library path that the crate reopens using RTLD_GLOBAL.
  10. Run NVSHMEM performance tests

    devel

    After installation, the executables are organized under the directory specified by NVSHMEM_PERFTEST_INSTALL, following the source hierarchy. To run a specific test, use the corresponding binary path. For example, to run the point-to-point bandwidth test, use the shmem_put_bw binary located in the device/pt-to-pt/ subdirectory.

    # Example: Running the point-to-point bandwidth test
    # Replace $NVSHMEM_PERFTEST_INSTALL with your actual installation path
    $NVSHMEM_PERFTEST_INSTALL/device/pt-to-pt/shmem_put_bw
  11. Install NVSHMEM from a package

    devel

    To install NVSHMEM using a pre-downloaded package, follow the official installation guide. After installation, you must set the NVSHMEM_PREFIX environment variable to your installation directory and update LD_LIBRARY_PATH so the system can locate the libraries.

    export NVSHMEM_PREFIX=/path/to/nvshmem
    export LD_LIBRARY_PATH="$NVSHMEM_PREFIX/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
  12. Register CUDA-Oxide modules with NVSHMEM

    devel

    If you are using CUDA-Oxide, you must register each loaded module before launching kernels that utilize NVSHMEM device state.

    Use NvshmemRuntime::register_module(&module) to obtain a registration guard. This guard ensures the runtime and the CUDA-Oxide module remain valid through NVSHMEM finalization.

    Important: You should explicitly call .finalize() on the guard after your last synchronized kernel to report any finalization errors.

    let registration = unsafe { runtime.register_module(&module) }?;
    
    // launch CUDA-Oxide kernels that call NVSHMEM device functions
    
    registration.finalize()?;