Generated banner for Doca Rdma
Generated logo for Doca Rdma

Doca Rdma

NVIDIAOfficialCreated by NVIDIA

  • Skill
  • Tool integration
  • Software development
  • Apache-2.0
  • Medium risk

From the author

RDMA data movement on NVIDIA BlueField/ConnectX NICs (RoCE/InfiniBand) with DOCA RDMA, instead of hand-written libibverbs/rdma_cm. Use when the user moves data between processes or hosts over the NIC, or hits "one-sided read returns permission denied", "completions never arrive after submit", "connection callback never fires", atomic compare-and-swap over RoCE, or DOCA_ERROR_FULL on the send queue under burst, even without naming DOCA RDMA. Covers bringing up an RDMA context on a doca_dev, connection methods (RDMA CM, bridge/OOB, or gRPC exchange of doca_rdma_export()), the eleven task types (Send/Receive/Send-Imm, Read/Write/Write-Imm, Atomic CmpSwap/FetchAdd, Get/Set/Add Remote Sync Event), matching mmap + RDMA permissions, queue and connection sizing, doca_rdma_cap_* queries, and DOCA_ERROR_* from RDMA calls. Raw QP/verbs control belongs to doca-verbs. Refuse and route elsewhere for general RDMA / ibverbs theory (queue pairs, MRs, RoCE vs IB), installing DOCA itself, or non-RDMA DOCA libraries.
— the description by NVIDIA

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides technical guidance for developers using the DOCA RDMA library to facilitate data movement between processes or hosts on NVIDIA BlueField DPU or ConnectX NIC hardware. It covers the lifecycle of RDMA contexts, connection methods, task types, and permission management, ensuring developers use the DOCA API rather than raw libibverbs or rdma_cm. The skill emphasizes the use of shipped DOCA samples as the starting point for development and provides structured workflows for configuring, building, and debugging RDMA-enabled applications.

What it does

  • Guides the setup of RDMA contexts and connection methods like RDMA CM, bridge, or gRPC.
  • Defines the taxonomy of eleven RDMA task types including Send, Receive, Read, Write, and Atomic operations.
  • Provides a permission matrix for mmap and RDMA operations to prevent access errors.
  • Outlines the capability discovery process using doca_rdma_cap_* functions.
  • Maps DOCA_ERROR_* codes to specific RDMA lifecycle or configuration issues.
  • Prescribes a workflow for modifying shipped DOCA RDMA samples to implement custom logic.

When to use it

  • When implementing data movement between hosts or processes over NVIDIA NICs.
  • When troubleshooting RDMA connection failures or permission errors.
  • When determining the appropriate RDMA task type for a specific data pattern.
  • When integrating RDMA functionality into non-C applications via FFI or bindings.
  • When verifying if a specific RDMA capability is supported on a given device.

Advantages

  • Ensures adherence to the DOCA programming model for portability and lifecycle management.
  • Prevents common pitfalls associated with bypassing the DOCA abstraction layer.
  • Provides a clear, verified path for building and running RDMA applications.
  • Standardizes the approach to debugging RDMA-specific errors and connection states.

Usage examples

“How do I set up a basic RDMA connection between two processes?”
The agent provides the lifecycle workflow: create context, configure tasks and permissions, start the context, establish a connection, and handle completion events.
“My one-sided read returns a permission denied error. What should I check?”
The agent guides you to verify the mmap permissions and RDMA access flags against the task requirements defined in the capability companion.
“Does my device support Atomic Compare-and-Swap over RoCE?”
The agent instructs you to use doca_rdma_cap_task_atomic_cmp_swap_is_supported against your doca_devinfo to confirm hardware support.
“How do I build a custom RDMA application using DOCA?”
The agent directs you to build the shipped DOCA RDMA samples first, then apply modifications to the payload and logic while maintaining the required build structure.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/nvidia/doca-rdma/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip doca-rdma.zip -d .agents/skills

Documentation by NVIDIA

DOCA RDMA

Examples

  • "Completions never arrive after submit." — stay on the DOCA RDMA task and progress-engine path. Do not rewrite it as raw verbs.

  • "One-sided read returns permission denied." — check mmap + RDMA permissions and doca_rdma_cap_* before changing the task type.

Instructions

Follow Loading order below. Open the tasks companion for configure / build / run. Open the capabilities companion for the task taxonomy and safety policy. Do not open every companion file.

Non-negotiable: the deliverable uses DOCA RDMA, not raw verbs

When this skill is in scope, the user is asking for DOCA RDMA. The program you produce must link libdoca_rdma and call the doca_rdma_* API (directly in C/C++, or through a thin FFI/cgo shim from another language). Do NOT implement the request with raw libibverbs / librdmacm / RDMA-CM and call it done. Those move bytes but completely bypass DOCA — which defeats the entire purpose of using this library, loses the DOCA programming model (progress engine, task/ event lifecycle, capability discovery, portability across BlueField/ ConnectX generations), and is the single most common failure mode.

"Raw verbs is fewer lines" / "it avoids building a DOCA binding layer" is not an acceptable reason to bypass DOCA. The correct low-friction path for a non-C language (Go, Rust, Python, …) is not to re-bind the whole API — it is to start from a shipped DOCA RDMA sample under $(pkg-config --variable=prefix doca)/samples/doca_rdma/ (substitute the module resolved on the target) and wrap its entry functions in a thin cgo/FFI shim built with #cgo pkg-config: doca (Go) or the equivalent. That shim is a single small file, not "a large custom binding layer". See ## build Step 0 and

modify.

If pkg-config doca or the DOCA build fails, fix the build (module name, PKG_CONFIG_PATH, sample path) — do not silently fall back to verbs. A binary whose ldd shows no libdoca_rdma is a failed DOCA-RDMA task, regardless of whether bytes moved.

Concrete path (verified on DOCA 3.3, one RoCE port, two processes):

  1. Record the installed version first: run pkg-config --modversion doca-rdma and show the result.

  2. Build the shipped pair in place, output outside. The samples' meson.build reads ../../../VERSION, so a copied samples tree does not configure. Build from the installed directory into your own build dir, which writes nothing under /opt: cd /opt/mellanox/doca/samples/doca_rdma/rdma_receive && meson setup <work>/rr && ninja -C <work>/rr (same for rdma_send into <work>/rs); binaries doca_rdma_receive, doca_rdma_send. Confirm flags with --help.

  3. Run both in one command. Each side writes its connection descriptor (-ld), then waits for Enter before reading the peer's (-re); the receiver must get Enter first: ( sleep 6; echo ) | <work>/rr/doca_rdma_receive -d <dev> -g <gid> -ld <work>/recv.desc -re <work>/send.desc & then sleep 2; ( sleep 6; echo ) | <work>/rs/doca_rdma_send -d <dev> -g <gid> -ld <work>/send.desc -re <work>/recv.desc; wait. Green: the receiver logs Got from sender: "..." and both print Sample finished successfully. Failed to open the file ... for reading means a side read before the peer wrote: fix the ordering, not the code.

  4. Extend only after the stock run is green. For extra output (a checksum or proof line), copy the whole samples tree with /opt/mellanox/doca/VERSION kept three levels above the sample directory, change only the payload and the receiver's print, and keep the same run sequence and any program names or output format the user asked for. Never write a new RDMA program from scratch, never edit the installed samples, and never fall back to raw verbs, rdma_cm code, ib_write_bw, rping or a loopback.

Device and GID. Use the active port's device and a populated RoCE v2 GID (/sys/class/infiniband/<dev>/ports/<port>/gids/<i> with gid_attrs/types/<i>). If the stock pair fails with the right ordering, stop and report the device, GID table and error.

Where to start: This skill assumes DOCA is already installed and the user is doing hands-on RDMA work on a BlueField / ConnectX / host with DOCA. Open the tasks companion if the user wants to do something (configure / build / modify / run / test / debug); open the capabilities companion when the question is what can RDMA express on this version. If the user has not installed DOCA yet, route to doca-setup/SKILL.md first.

Example questions this skill answers well

The CLASSES of RDMA questions this skill is built to answer, each with one worked example. The agent should treat the class as the load-bearing piece — the worked example is a single instance.

  • "How do I bring up an RDMA context and connect two sides?" — worked example: "set up sender + receiver with RDMA CM on a single host for first-run testing". Answered by the lifecycle + connection workflow in ## configure +

    Capabilities and modes

    connection-method selection.

  • "Which RDMA task type fits this data-movement pattern?" — worked example: "one-sided write + completion via Send-with-Immediate for a small control message". Answered by the task taxonomy in

    Capabilities and modes

    • the task-config workflow in

    modify.

  • "What mmap permissions does this task need? Do I have to export the mmap?" — worked example: "my Read task fails with insufficient permissions". Answered by the permission matrix in

    Safety policy

    • the mmap-export checklist in

    test.

  • "Is this RDMA capability supported on my device + transport?" — worked example: "does this device support Atomic Compare-and-Swap over RoCE". Answered by the capability-query rule (doca_rdma_cap_task_*_is_supported against a doca_devinfo) in

    Capabilities and modes

    • the discovery step in

    configure.

  • "Is this RDMA API available on my installed DOCA version?" — worked example: "is RDMA CM in DOCA 2.6.0". Answered by the version-compatibility section in

    Version compatibility

    • the version-discovery rule (pkg-config --modversion doca) pinned in ## configure.

  • "What does this DOCA_ERROR_* from an RDMA call mean and which layer caused it?" — worked example: "DOCA_ERROR_BAD_STATE from doca_rdma_connection_disconnect". Answered by the RDMA overlay on the cross-library taxonomy in

    Error taxonomy

    • the layered ladder in

    debug that escalates to

    doca-debug/SKILL.md.

Audience

This skill serves external developers building applications that consume the DOCA RDMA library — i.e., users whose code calls doca_rdma_* (directly in C/C++, or through FFI/bindings from another language) to do RDMA data movement between two sides (host↔host, host↔BlueField, DPU↔DPU, or SF↔SF on a BlueField). It is not for NVIDIA developers contributing to DOCA RDMA itself.

Language scope. DOCA RDMA normally ships as a C library inside the umbrella doca pkg-config module (public header doca_rdma.h, shared object libdoca_rdma.so); split installs may expose a per-library module. Always discover the module on the target (pkg-config --list-all | grep -i doca) rather than assuming either layout. The shipped samples are written in C (NVIDIA's choice). C and C++ consumers are the canonical case and the worked examples in the tasks companion assume that path. Other-language consumers (Rust, Go, Python, …) consume the same *.so through FFI or language-specific bindings; the skill's contribution in that case is to keep the lifecycle, capability-discovery, permission-matrix, error-taxonomy, and connection-method guidance language-neutral, and to route the agent to the public C ABI as the authoritative surface that any wrapper will eventually call. The non-C deliverable is still a DOCA program: a thin cgo/FFI shim over the shipped doca_rdma sample that links libdoca_rdma (#cgo pkg-config: doca) — never a raw-libibverbs reimplementation chosen to avoid wrapping DOCA (see the mandate at the top of this file).

When to load this skill

Load this skill when the user is doing hands-on DOCA RDMA work, in any language. Concretely:

  • Initializing an RDMA context on a doca_dev. The Core order is create → configure (task set_conf + mmap/RDMA permissions + optional set_*) → start → connect → use → stop → destroy. Configuration MUST finish before doca_ctx_start().

  • Establishing a connection — picking between RDMA CM (doca_rdma_connect_to_addr() / doca_rdma_start_listen_to_port() / doca_rdma_connection_accept()), bridge / OOB (doca_rdma_bridge_*), or gRPC (out-of-band exchange of doca_rdma_export() output).

  • Setting permissions on doca_mmap correctly for the chosen task type (Read needs RDMA-read + local read-write; Write needs RDMA-write; Atomic needs RDMA-atomic; Send needs only local read-write).

  • Reading / setting library properties via doca_rdma_set_* and doca_rdma_cap_get_* to size queues, list lengths, and transport-type selection.

  • Checking which RDMA task types and transport types are supported on the active doca_devinfo.

  • Debugging a DOCA_ERROR_* returned from an RDMA call (lifecycle vs. permission vs. capability vs. driver-below) and the connection state-machine transitions (doca_rdma_set_connection_state_callbacks).

  • Designing or extending non-C bindings (Rust, Go, Python, …) that wrap the RDMA C ABI — for the lifecycle, permission, and capability rules the wrapper must honor.

Do not load this skill for general DOCA orientation, install of DOCA itself, or non-RDMA library questions. For those, use doca-public-knowledge-map/SKILL.md.

What this skill provides

This is a thin loader. The body keeps only the orientation needed to pick the right next file. The substantive RDMA-specific material lives in two companion files:

  • the capabilities companion — what RDMA can express on this version: the eleven task types and their permission matrix, the three connection methods, transport types (RC baseline and alpha-level DC for the export/connect CPU-datapath flow — there is no UD) — note these are the per-QP service type controlled by doca_rdma_set_transport_type(), NOT the link-layer (IB vs RoCE) which is inherited from the device port configuration, the capability-query surface (doca_rdma_cap_*), the RDMA error taxonomy (mapped onto the cross-library DOCA_ERROR_* set), the observability surface (per-task events, connection state callbacks), and the safety policy that gates permission and export decisions.

  • the tasks companion — step-by-step workflows for the six in-scope RDMA verbs: configure, build, modify, run, test, debug. Plus a Deferred task verbs block that points out-of-scope questions at the right next skill.

The skill assumes a host or BlueField where DOCA is already installed at the standard location and the user has the privileges their public install profile expects. It does not cover installing DOCA — that path goes through doca-setup/SKILL.md.

What this skill deliberately does not ship

This skill is agent guidance, not a samples or templates bundle. To keep the boundary clean, it deliberately does not contain — and pull requests should not add:

  • Pre-written DOCA RDMA application source code, in any language. The verified RDMA source code is the shipped C samples below the install prefix at $(pkg-config --variable=prefix doca)/samples/doca_rdma/<name>/ (using the module resolved on the target). The agent's job is to route the user to those files and prescribe a minimum-diff modification on them via the universal modify-a-sample workflow in doca-programming-guide/SKILL.md, layered with the RDMA-specific overrides in

    modify.

  • Standalone build manifests (meson.build, CMakeLists.txt, Cargo.toml, …) parked inside the skill. The agent constructs the build manifest in the user's project directory against the user's installed DOCA, where pkg-config --modversion doca is the source of truth (resolve the module per ## build Step 0 — prefer doca-rdma when it resolves).

  • A samples/, bindings/, or reference/ subtree of any kind. A mock or incomplete artifact in this skill's tree, even one labeled "reference", is misleading: users will read it as buildable.

Loading order

  1. Read this skill first to confirm the user's question is in scope.

  2. If the question is what RDMA can express—task taxonomy, link-layer vs transport-type selection, connection methods, permissions, errors, observability, or safety—read the capabilities companion.

  3. If the question is how to do it—configure, build, modify, run, test, or debug—read the matching H2 in the tasks companion. Read both companions only when the workflow depends on a capability or safety decision; do not load both unconditionally.

Both companion files cross-link to each other and to doca-public-knowledge-map/SKILL.md whenever the right answer is "look it up in the public docs or the installed package layout" rather than "RDMA-specific guidance".

  • doca-public-knowledge-map/SKILL.md — the routing table for every public DOCA documentation source and the on-disk layout of an installed DOCA package. Always available alongside this skill.

  • doca-setup/SKILL.md — env preparation, install verification, and the I have no install yet path with the public NGC DOCA container. This skill assumes its preconditions are satisfied.

  • doca-programming-guide/SKILL.md — general DOCA programming patterns shared by every library: the canonical pkg-config + meson build pattern, the universal modify-a-shipped-sample first-app workflow, the universal lifecycle, the cross-library DOCA_ERROR_* taxonomy, and the program-side debug order. This skill layers RDMA specifics on top.

  • doca-debug/SKILL.md — the cross-cutting debug ladder (install / version / build / link / runtime / program / driver). RDMA-specific debug (state-machine transitions, permission failures, connection callbacks) overlays on top of that ladder.

Files

TASKS.md

DOCA RDMA workflows

Where to start: The verbs run configure → build → modify → run → test → debug. Skip ahead only when the user is already past a verb. The ## test verb is an iterative loop (capability check → permission check → bidi smoke → completion drain → loop back if the permission set or task set changed), not a one-shot pass — see the eval-loop overlay in ## test below.

Read this file when the loader sent you here from SKILL.md. For the underlying capability matrix, version compatibility, error taxonomy, observability surface, and safety policy that these workflows assume, see CAPABILITIES.md. For where to find docs, the installed DOCA layout, or release notes, route through doca-public-knowledge-map/SKILL.md.

Each verb below describes the shape of the workflow, not a copy-paste recipe. The agent’s job is to walk the user through the steps in order, verifying preconditions before recommending the next call.

configure

Goal: bring up a DOCA RDMA context on a host or BlueField and confirm both sides are in a state where data-movement tasks are meaningful.

Core order, named in full every time: create → configure → start → connect → use → stop → destroy. Task configuration and permission setting belong in configure and MUST finish before doca_ctx_start(). Connect is its own step after start; do not fold it into use.

Steps the agent should walk the user through:

  1. Confirm the installed DOCA version. Use the procedure in doca-setup CAPABILITIES.md ## Version compatibility (doca-setup/CAPABILITIES.md#version-compatibility). Quote the version observed (pkg-config --modversion doca, then doca_caps --version); do not assume "latest".

  2. Discover the device capability surface for RDMA. Run doca_caps --list-devs (doca-caps/SKILL.md) to see which devices have RDMA capability, then run the per-doca_devinfo doca_rdma_cap_* queries against the candidate device. Record the link layer the active port already exposes (IB or Ethernet/RoCE) separately from the DOCA RDMA transport type (RC or DC, with DC alpha and restricted as described in the capabilities matrix). IB / RoCE is not an argument to doca_rdma_set_transport_type(). Also record which task types are supported for the selected transport and what doca_rdma_cap_get_max_* returns for the queue / buf-list sizes. The capability matrix to compare against lives in CAPABILITIES.md ## Capabilities and modes.

  3. Decide the connection method. RDMA CM (callback-driven) vs bridge / OOB vs gRPC. The pick decides the next-step code shape; the trade-off matrix lives in CAPABILITIES.md ## Capabilities and modes connection-methods table. Do not pick for the user when their intent is ambiguous — ask.

  4. Configure the RDMA instance. Mandatory before doca_ctx_start(): enable at least one task type (doca_rdma_task_*_set_conf); set permissions (doca_rdma_set_permissions); set the mmap permissions (doca_mmap_set_permissions) to match the task type per the matrix in CAPABILITIES.md ## Safety policy. Optional but commonly needed: doca_rdma_set_transport_type(), doca_rdma_set_max_num_connections(), doca_rdma_set_* queue sizes. Then doca_ctx_start(), then connect with the method from step 3, then use. Never connect or submit before start; tear-down is stop then destroy.

  5. Sanity check before any task submission. Confirm with the user: which side is requesting work (Read/Write originator), which side is exporting memory (doca_mmap_export_rdma()), which transport, which connection method. If any of those are unclear, stop and ask — do not invent.

If any step fails with a DOCA_ERROR_*, route through the error taxonomy in CAPABILITIES.md ## Error taxonomy before retrying. Configure retries use the bounded identity defined in ## test: the same error family and configure step on the same device, link layer, transport, task set, permission set, and connection method, with unchanged logs, capability results, and connection-state evidence. Stop after two unchanged iterations and escalate instead of retrying indefinitely.

build

Goal: produce a binary that links DOCA RDMA against the user's installed DOCA, using the canonical cross-library build pattern.

The build pattern for any DOCA C/C++ consumer is identical across libraries — pkg-config for include + link flags, meson or CMake as the build system — and is fully documented in doca-programming-guide TASKS.md ## build (doca-programming-guide/TASKS.md#build).

Step 0 — resolve the pkg-config module (do this first; do not assume). DOCA RDMA is normally delivered inside the umbrella doca pkg-config module; split installs may expose a per-library module. Resolve the actual module on the target before writing any build file:

  1. Make sure pkg-config can see DOCA. If pkg-config --exists doca fails, discover the install's pkgconfig directory first with find /opt -name 'doca-*.pc' -path '*/pkgconfig/*', then prepend that discovered directory to PKG_CONFIG_PATH.

  2. List what actually exists: pkg-config --list-all | grep -i doca. Use the most specific RDMA module that exists if a split install exposes one; otherwise use the umbrella doca (the normal case). The public RDMA header is doca_rdma.h and the shared object is libdoca_rdma.so regardless of which .pc resolves them.

Guardrail — DOCA is the deliverable, not "any RDMA". If pkg-config doca-rdma (or any --libs/--cflags probe) fails, the cause is almost always a wrong module name or an unset PKG_CONFIG_PATH — fix that. Do NOT silently fall back to raw libibverbs / librdmacm / RDMA-CM and hand-roll a verbs program. That technically moves bytes but abandons DOCA entirely, which defeats the purpose of this work. A build that does not link libdoca_rdma is a failed DOCA-RDMA build — troubleshoot the module resolution above (and escalate via the error taxonomy) instead of bypassing DOCA.

Concrete path — build the shipped DOCA RDMA sample pair first. Before writing any new code, start from the samples the DOCA RDMA guide ships under /opt/mellanox/doca/samples/doca_rdma/. Each sample directory holds <name>_sample.c, <name>_main.c, and meson.build. The pairs are:

Pair (run both)PatternWhen to pick it
rdma_receive + rdma_sendTwo-sided send/receiveThe first pair to build; it is also the ## test smoke
rdma_write_responder + rdma_write_requesterOne-sided writeData must land in the peer's memory without a posted receive
rdma_read_responder + rdma_read_requesterOne-sided readThe requester pulls data from the peer's exported memory
*_immediate variantsSame, plus a 32-bit immediate valueOnly when the user needs the immediate value
  1. ls /opt/mellanox/doca/samples/doca_rdma/ — quote the pairs this install actually ships before naming one.

  2. pkg-config --modversion doca-rdma (or the module Step 0 resolved) — record the version next to the build.

  3. Build each side out of tree with meson + ninja, as the guide documents: cd /opt/mellanox/doca/samples/doca_rdma/rdma_receive, meson /tmp/build-rdma-receive, ninja -C /tmp/build-rdma-receive; repeat for rdma_send into its own build directory. The binary is doca_<sample_name> in that build directory. Never edit files under /opt/mellanox/doca/samples/ or leave build directories there — when the user's intent needs a code change, copy the whole samples tree to a workspace first so the shared helper files still resolve, and edit and build the copy.

  4. Prove the routing on the exact binary you will run, as its own unfiltered command: ldd /tmp/build-rdma-send/doca_rdma_send, and read the libdoca_rdma.so => … line in the full output. No such line means this is not a DOCA RDMA build — fix the build; do not switch to another tool.

This skill carries only the RDMA-specific overlay:

SlotValue for RDMAWhy it matters
pkg-config module namedoca-rdma when pkg-config --exists doca-rdma succeeds, otherwise the umbrella doca (verify per Step 0)The .pc that resolves the RDMA cflags/libs on current DOCA host packages
Required runtime libswhatever pkg-config --libs doca reports — it pulls in libdoca_common, libdoca_rdma, and the device-side providersRDMA depends on Core + the rdma transport providers shipped with DOCA
Header checkdoca_rdma.h resolvable under the include directory pkg-config --cflags doca reports (do not hardcode the include path — the install layout can move)If --cflags resolves but doca_rdma.h is missing, the install is partial
Minimum required DOCA versionQuery with pkg-config --modversion doca; never hardcode in build filesCross-version build/runtime mixing breaks per CAPABILITIES.md ## Version compatibility

For non-C consumers (Rust, Go, Python), the link surface is the same *.so files (cgo #cgo pkg-config: doca, Rust pkg-config crate on doca, etc.); the FFI wrapper layer is the language-specific binding and is out of scope for this skill — but the slots above (and the guardrail) are still the load-bearing inputs the wrapper needs.

modify

Goal: take a shipped DOCA RDMA sample as the verified starting point and apply a minimum-diff modification to express the user's intent.

Non-C languages (Go / Rust / Python): this is still the right verb. Do not reimplement RDMA in raw libibverbs to avoid C. Start from the shipped sample under $(pkg-config --variable=prefix doca)/samples/doca_rdma/<name>/ (substitute the module resolved in ## build Step 0), then expose its entry points (e.g. the sample's send/receive or write/read driver functions) through a thin FFI shim — for Go, one small *.c/*.h pair compiled via #cgo pkg-config: doca calling the sample functions, with main.go orchestrating. This keeps the verified DOCA datapath intact and links libdoca_rdma; it is a single small wrapper, not a full re-binding of the DOCA API.

The universal modify-a-shipped-sample workflow lives in doca-programming-guide TASKS.md ## modify (doca-programming-guide/TASKS.md#modify). Use it as-is. The RDMA-specific overlay is the modify-from-sample schema fill — the five slots the agent must elicit from the user before recommending any code-level edit:

SlotWhat the agent asks the userRDMA-specific consideration
1. Starting sampleWhich sample under $(pkg-config --variable=prefix doca)/samples/doca_rdma/ (using the resolved module)?Pick the closest in task direction (one-sided vs two-sided) and connection method (CM vs bridge vs OOB) to the user's intent. Do NOT bridge across both axes — a smaller diff is always safer than a re-architecture
2. Task types added or removedWhich task types from the eleven?Each added type needs its own doca_rdma_task_*_set_conf call before doca_ctx_start(), plus its matching mmap-permission flags
3. Permission changesWhich mmap / RDMA permissions change?Refer to the permission matrix in CAPABILITIES.md ## Safety policy; over-broad permissions are a silent security regression
4. Connection methodChange CM → bridge or vice versa?This is a re-architecture, not a tweak. If yes, recommend the user start from the sample that already uses the target method instead of patching one over
5. Transport / connection sizingChange transport type or max_num_connections?If yes, re-run the capability queries from ## configure step 2; transport-type support is device-conditional

The agent emits an intent description + the five filled slots; the actual unified diff against the sample source is produced by the user (this bundle has no diff renderer). The agent must walk the user through the diff line-by-line against the sample source they read on disk, and have the user paste back the result for validation. Modify is complete only when (1) all five slots match the edited sample, (2) the resulting binary links DOCA RDMA (libdoca_rdma is present in the resolved link/runtime dependency surface), and (3) the edited sample builds successfully with the install-resolved pkg-config flags.

run

Goal: actually execute the built binary against the user's installed DOCA on a host or BlueField, including a peer to connect to.

Steps the agent should walk the user through:

  1. Confirm the peer is reachable. RDMA needs a peer; running the binary on one side alone produces a misleading hang. Either both sides are on networks that route IB or RoCE to each other, or both run as local processes on a single host over the same doca_dev (see Single-host loopback below) — the latter is the right first-run smoke test when only one BlueField / NIC is on hand.

  2. Run the side that listens first. Server (RDMA CM) or accept-side (bridge / OOB) must be running and at the connection-listening state before the client / connect-side starts. Confirm with the user which side is which.

  3. Capture the structured log. Set DOCA_LOG_LEVEL=trace for the first run (see doca-debug CAPABILITIES.md ## Observability (doca-debug/CAPABILITIES.md#observability)). This is the cheapest way to make the lifecycle and connection state transitions visible on first failure.

  4. Capture the completion events on the PE. A run that produces no completion events but doesn't error is almost always a missed doca_pe_progress() call. Confirm the progress engine is being driven on both sides.

Two peers on one box (only one BlueField / NIC available). A peer does not have to be a second host. Run the responder / receiver and the requester / sender as two separate processes on the same active port (-d <ibdev>), or across two ports, or host ↔ BlueField. Two processes on one port still move the bytes through the NIC. What does not count is a same-process, same-buffer loopback, or a client / server pointed at 127.0.0.1 / localhost. Exchange connection details with the samples' own arguments (DOCA 3.5 RDMA guide, common sample arguments):

  • Out-of-band descriptor files (default). -ld / --local-descriptor-path is where a side writes its own descriptor; -re / --remote-descriptor-path is where it reads the peer's; the one-sided read/write samples also take -m / --mmap-descriptor-path for the peer's exported mmap. On one box the receiver's local path is the sender's remote path and vice versa. Start the responder / receiver first, then the requester / sender.

  • RDMA CM. -cm / --use-rdma-cm on both sides; the listener takes -lp / --listen-port, the connector takes -sa / --server-addr with -sat / --server-addr-type (IPv4, IPv6, or GID). Use the port's own IP or GID, never a loopback address.

Two caveats that bite agents: (a) the descriptor handshake waits for Enter on each side once both descriptor files exist, and the write/atomic samples expect a second Enter on the responder after the requester reports its task done — a single Enter looks like a hang; drive these prompts from the same foreground command and wait for both processes, do not leave them in the background; (b) prove the transfer with the independent evidence in ## test (receiver-side data check plus the receiving port's RDMA byte counters sampled before and after), not from the sample's log alone.

test

Goal: prove the configured RDMA instance can actually move data correctly between the two sides on the user's hardware, and that the permission and capability set was sized right.

This is a loop, not a one-shot pass. Each iteration narrows either the capability set, the permission set, the task set, or the sizing. The loop terminates when either (a) the user's intended data-movement pattern flows end-to-end with the expected completions, or (b) the agent has narrowed the failure cause to a layer outside RDMA itself (driver / firmware / network) and escalated to the matching skill.

What proves a DOCA RDMA transfer — and what does not. Declare the data path working only when one run captures all four:

  1. Routing. Plain ldd on the executed requester and responder binaries (built from the shipped sample per ## build) shows libdoca_rdma.so.

  2. Two peers. Responder / receiver and requester / sender are separate processes with different PIDs (two hosts, host ↔ BlueField, two ports, or one active port). The responder starts first, the command waits for both, and both exit 0.

  3. Data check. The receiver validates the payload it actually received against what the sender sent — for example the SHA-256 of the sent and received buffers. Use synthetic test bytes, never user data.

  4. NIC evidence. Sample the receiving port's RDMA byte counters before and after the run — map the device to its netdev with ibdev2netdev, then read ethtool -S <netdev> (the mlx5 rx_vport_rdma_unicast_bytes / tx_vport_rdma_unicast_bytes counters). The receive-side delta should be at least the payload size.

ib_write_bw, ib_send_bw, rping, ibv_rc_pingpong, and other rdma-core / perftest tools exercise only the verbs layer and the fabric: they can be a fabric pre-check, but they do not validate the DOCA RDMA path and are never the deliverable. Neither is a loopback shortcut (same process / same buffer, or 127.0.0.1).

Iteration shape:

  1. Capability re-check. Re-run doca_rdma_cap_task_*_is_supported for every task the user intends to submit, against the active doca_devinfo. If false → that's the answer; the user's device or DOCA version does not support the task. Update the user's intent or update the install.

  2. Permission cross-check. Compare the configured mmap + RDMA-permission pair against the matrix in CAPABILITIES.md ## Safety policy. Mismatches surface as DOCA_ERROR_NOT_PERMITTED on the first task submission, not at configure time.

  3. Bidirectional smoke. Always start with a Send + Receive pair, even if the user's intent is one-sided (Read / Write). If the bidirectional control path works, the connection + two-sided permissions are correct, and any subsequent one-sided failure narrows cleanly to the one-sided permission set. Skipping this step is the most common reason "Write fails and we don't know why".

  4. Completion drain. Confirm completion events arrive on the PE for every submitted task. Submitted but no completion is the most expensive class of bug to discover late; confirm it on the smoke pair before adding bulk submissions.

  5. Negative test. Once the positive path works, intentionally submit one task type the device should NOT support (per step 1) and confirm the failure is the expected DOCA_ERROR_NOT_SUPPORTED. This validates the agent's capability-discovery is itself correct. Run this only in a non-production test environment, on a dedicated test connection and mmap that contain no production data.

Eval-loop overlay — why this is a loop, not a one-shot pass:

Iteration triggerWhat it looks likeWhat changes next iteration
DOCA_ERROR_NOT_SUPPORTED on a task we expected to workA doca_rdma_cap_* returned true for a task type but the runtime rejects itThe agent quoted the library capability; the device capability per doca_devinfo is the real gate. Re-narrow to the device-level query.
DOCA_ERROR_NOT_PERMITTED on a one-sided taskThe local-side smoke worked; the cross-side Read/Write/Atomic failsThe mmap was not exported, or the peer's mmap permissions don't include the matching RDMA flag. Re-check the matrix.
Submitted task produces no completiondoca_task_submit() returned DOCA_SUCCESS; the PE produces nothingEither the PE is not being progressed, or the peer disconnected silently. Wire the connection-state callbacks.
Bulk submit returns DOCA_ERROR_FULLFirst N submissions succeed, then FULLThe queue sizing is below the user's intended in-flight depth. Raise send_queue_size and re-run, or drain completions between bursts.
Connection callback never firesRDMA CM connect was called; no callback arrives before the configured connection_request_timeout expiresServer side is not listening, the network does not route, or the configured timeout is too short. Record the configured value, check the network first, then change only that timeout if the evidence supports it.

Loop identity is the same trigger or DOCA_ERROR_* family for the same device, link layer, transport, task set, permission set, connection method, and configured timeout, with unchanged program log, capability results, completion events, and connection-state callbacks. Stop after two consecutive iterations with that identity produce no evidence change — that means the cause is below RDMA. Escalate to doca-debug ## debug (doca-debug/TASKS.md#debug) with the captured layer-1-through-5 evidence. The configure workflow reuses this exact identity and bound.

debug

Goal: when a DOCA RDMA call returns a DOCA_ERROR_* (or the program doesn't make forward progress), narrow the cause to a specific layer and act on it.

The cross-library debug ladder lives in doca-debug TASKS.md ## debug (doca-debug/TASKS.md#debug). Walk through it in order — install → version → build → link → runtime → program → driver — before recommending RDMA-specific fixes. This skill's overlay names the RDMA-specific manifestation at layers 5 (runtime) and 6 (program):

Layer 5 (runtime) — RDMA overlay.

  • Walk the connection state machine: was the context started? Was the connection request received? Was the connection established? Was a task submitted before the connection reached established? The wrong order returns DOCA_ERROR_BAD_STATE, not a clear symptom.

  • Confirm the PE is being progressed. No completion events is almost always a missing doca_pe_progress() in the user's main loop.

  • Confirm both sides agreed on transport type. A mixed-transport pair returns DOCA_ERROR_DRIVER from the layer below; the fix is at configure time, not in the RDMA call.

Layer 6 (program) — RDMA overlay.

  • Permission matrix: the most common RDMA program-layer bug is an mmap-permission / RDMA-permission mismatch surfaced as DOCA_ERROR_NOT_PERMITTED. Walk the matrix in CAPABILITIES.md ## Safety policy against the user's configured permissions.

  • Lifecycle order: create → configure → start → connect → use → stop → destroy. Out-of-order returns DOCA_ERROR_BAD_STATE. The most common case is destroying an mmap before doca_ctx_destroy().

  • Bulk-submit sizing: DOCA_ERROR_FULL on bulk submit is a sizing-vs-drain mismatch, not a hardware failure.

Once the layer is identified, route to the matching debug verb on the matching skill: install / build / link / driver to doca-setup ## debug (doca-setup/TASKS.md#debug); cross-cutting runtime to doca-debug ## debug (doca-debug/TASKS.md#debug); program-layer Core-context patterns to doca-programming-guide TASKS.md ## debug (doca-programming-guide/TASKS.md#debug).

Deferred task verbs

The following verbs are out of scope for this skill but are commonly asked in the same conversations. Route them as follows so the agent does not invent guidance:

  • install. Installing DOCA, choosing packages, post-install verification, pkg-config wiring — defer to doca-setup/SKILL.md and to the install-tree layout in doca-public-knowledge-map ## Layout of an installed DOCA package (doca-public-knowledge-map/SKILL.md#layout-of-an-installed-doca-package). This skill assumes DOCA is already installed.

  • deploy. Deploying RDMA-using applications at scale across many hosts / DPUs, Kubernetes operator workflows for RDMA workloads, multi-tenant RDMA isolation — out of scope for this skill. For single-host first-run testing, the right verb in this skill is ## run; do not invent a "deploy" workflow.

  • rollback. Coordinated rollback of RDMA-using applications across multiple hosts / DPUs — out of scope for this skill. For a single in-session RDMA configuration rollback, the right verb in this skill is destroying the context (doca_ctx_stop → doca_ctx_destroy) and re-running ## configure with the corrected parameters; do not invent a "rollback" workflow.

  • kernel-level driver install / firmware burn. Installing the mlx5_core driver, burning new ConnectX firmware, or modifying mlxconfig parameters that need a reset — out of scope for this skill. Route to doca-setup ## debug (doca-setup/TASKS.md#debug) layer 5 (driver), then to the upstream MLNX OFED / firmware documentation reachable through doca-public-knowledge-map/SKILL.md.

Command appendix

Every command below is cross-cutting on DOCA RDMA — it answers a recurring class of question that comes up in the verbs above. The agent should treat the class as load-bearing; the worked example is a single instance. Run-as user is the unprivileged user unless noted. Rows that need elevated privileges call that out explicitly.

Infra-aware preamble (every row below). Per the bundle's detect → prefer → fall back → report contract documented in doca-structured-tools-contract ## The agent behavior contract (doca-structured-tools-contract/SKILL.md#the-agent-behavior-contract), the agent should:

  1. Probe for the matching structured helper FIRST (doca-env --json for version + devices + libraries + drivers + hugepages in one shot; doca-capability-snapshot for per-device capability flags; version-matrix.json for “available since” lookups).

  2. If the probe succeeds, the structured tool's output is the authoritative answer and the agent SHOULD NOT also run the manual command in the row below. Report “using structured <tool>”.

  3. If the probe fails, fall back to the manual command in the row. Report “falling back to manual chain”.

  4. The schemas the structured tools emit are defined in doca-structured-tools-contract ## Schemas (doca-structured-tools-contract/SKILL.md#schemas); the version-handling semantics (four-way match, NGC, headers-win) are owned by doca-version/SKILL.md.

Command (worked example)Owning stepClass of question it answersWhat healthy output looks like
pkg-config --modversion doca## configure step 1; ## build slot 4What is the build-time DOCA version?A semver string matching doca_caps --version. Disagreement = partial install (route to doca-version TASKS.md ## debug (doca-version/TASKS.md#debug) layer 2). Use pkg-config --modversion doca-rdma when that module resolves; otherwise the umbrella doca module (verify with `pkg-config --list-all
pkg-config --cflags --libs doca## buildWhat include + link flags does the linker need?Trust whatever pkg-config --cflags --libs doca produces on this install. Do not hardcode either the -I include path or the -l<name> flag form — both can drift between DOCA install profiles and DOCA majors; the on-disk .so basenames use underscores (libdoca_rdma.so), and pkg-config is the only thing that resolves both correctly. Hand-crafted -l lines silently break when DOCA upgrades. If this probe fails, fix the module name / PKG_CONFIG_PATH per ## build Step 0 — do NOT fall back to raw libibverbs.
grep -RHn 'DOCA_VERSION_' $(pkg-config --variable=includedir doca)/doca_version.h## configure step 1What macros does this DOCA install expose for compile-time version checks?A DOCA_VERSION_MAJOR, MINOR, PATCH triple matching the runtime version
doca_caps --list-devs## configure step 2Which devices on this host can be used as a doca_dev?One row per visible device with PCIe address and capability flags
doca_caps --version## configure step 1; ## test step 1What is the runtime DOCA version on this host?A semver string matching pkg-config --modversion doca
ls "$(pkg-config --variable=prefix doca)/samples/doca_rdma/" (substitute the resolved module)## modify slot 1Which RDMA samples ship in this install, and which is the closest starting point?A list of sample directories named after the task pattern they demonstrate
cat "$(pkg-config --variable=prefix doca)/applications/VERSION" (substitute the resolved module)## configure step 1; ## debug layer 1What does the install tree itself claim its version is?A semver string matching the other two version sources
`dmesgtail -n 40` (sudo)## debug layer 7What did the kernel / driver log around the last RDMA call?
`mlxconfig -d <pcie> qhead -n 40` (sudo)## debug layer 7What firmware config does the underlying NIC report?
ibv_devinfo (sudo)## configure step 2; ## debug layer 7What does the underlying libibverbs see for this device?One device row with state: PORT_ACTIVE and a sane MTU
DOCA_LOG_LEVEL=trace ./<binary>## run step 3What did the structured DOCA logger emit for the first failing call?A trace-level line on every lifecycle transition and every task submission. Silence after submission = PE not progressed
ldd <build-dir>/doca_rdma_send (unfiltered, own command)## build step 4; ## test evidence 1Does the binary I am about to run actually use DOCA RDMA?A libdoca_rdma.so => … line. Missing = not a DOCA RDMA build
ibdev2netdev, then ethtool -S <netdev> before and after## test evidence 4Did RDMA bytes really cross the receiving port?rx_vport_rdma_unicast_bytes delta ≥ payload bytes
ib_write_bw / rping / ibv_rc_pingpongfabric pre-check onlyDoes the verbs layer / fabric work at all?Passing says nothing about DOCA RDMA; never report it as the DOCA RDMA proof

For commands shared across libraries (pkg-config --modversion, doca_caps, the install-prefix applications/VERSION, DOCA_LOG_LEVEL) the cross-library overlay is in doca-debug TASKS.md ## Command appendix (doca-debug/TASKS.md#command-appendix); this table adds the RDMA-specific rows on top.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

The author says: Requires DOCA SDK on Linux (Ubuntu 22.04/24.04 or RHEL/SLES) with a BlueField DPU or ConnectX NIC. Resolves the local install and module via `pkg-config --list-all | grep -i doca` and `pkg-config --variable=prefix MODULE`, replacing `MODULE` with the exact name returned by the preceding query. The normal module is the umbrella `doca`, while split installs may expose a per-library module. The validation steps require a live DOCA install.

Security

What our scanner noticed· Medium risk

  • Large base64-encoded blobs

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
NVIDIA
Publisher
NVIDIA (Official)
Source
NVIDIA/skills · skills/doca-rdma · commit fce3cca
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE-APACHE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by NVIDIA.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download doca-rdma.zip