Skip to content

SHARP: in-network reduction

S3·E3The server they want to delete · NVIDIA briefing room, the first scalable unit on the whiteboard

S3·E3Analyze~30 minsources checked todayverified against NVIDIA SHARP 3.16.0 Introduction and Installation; SHARP 3.12.0 installation; SHARP 3.8.0 environment, dynamic trees and testing pages; SHARP 3.0.0 testing page; UFM Enterprise 6.24.1 and 6.25.1; MLNX-OS 3.12.6200 LTS; IBUtils2 2.24.0. Research notes fetched 2026-09-07

Builds on: Routing engines and how OpenSM picks a path, Adaptive routing, SHIELD and hash-based forwarding

Before you read: what do you already know?

3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.

After this lesson you can

  • Name every prerequisite SHARP has before a single collective can be offloaded, and say which component owns each one.
  • Label every field of a `sharp_hello -v 3` transcript and state what each one proves.
  • Order a five-step SHARP triage and give the exact command for each step.
  • Explain why a clean `ibdiagnet` says nothing about whether SHARP works.
  • Match a customer's ASIC and adapter generation to the tree limits and tree types they can actually use.

Episode 3 — The server they want to delete

The situation · NVIDIA briefing room, the first scalable unit on the whiteboard

The design review has the 64-node NDR pod on the whiteboard and the struck-out server on the table. Procurement asks the only two questions procurement asks, and on price they are ahead: a managed switch can run the subnet manager, so delete the box. The Dell SE is nodding, because a server is a number on a page and this one looks free. The network lead writes it down.

You draw the box back in. The aggregation manager is a central entity running on a dedicated server with a master subnet manager, and that dedicated server cannot serve as a compute node.[3] The switch-embedded subnet manager is not an alternative either: the MLNX-OS SM does not support SHARP at all, and the SHARP prerequisites say to disable the onboard subnet manager in the managed switches.[11][3]

SHARP exists because a collective was paying for the network twice. It improves the performance of MPI and machine-learning collective operations by offloading collective operations from CPUs and GPUs to the network, eliminating the need to send data multiple times between endpoints.[1] The reduction happens in the switch on the way past, so the data crosses the fabric once.

The NVIDIA PM, in for a roadmap slide, is asked what the next generation changes and says “not announced” twice, pleasantly.

The free-looking line in an AI-fabric quote is usually the one the feature runs on.

Then the network lead asks what else has to be true. The list is longer than the room expects, and only part of it is about switches.

1What SHARP is, and the two pieces that must both exist

SHARP improves the performance of MPI and machine-learning collective operations by offloading collective operations from CPUs and GPUs to the network and eliminating the need to send data multiple times between endpoints.[1] With the third generation, multiple aggregation trees can be built over the same topology, so many parallel jobs get the in-network computing benefit over the same infrastructure.[1]

There are exactly two software pieces: sharp_am, which runs in UFM, and libsharp, which is linked to client applications running on the compute nodes; the recommended setup is to enable SHARP in UFM and install libsharp on the compute nodes using HPC-X.[2][7] The aggregation manager has a placement rule that ends several design conversations early: it is a central entity running on a dedicated server with a master subnet manager, and this dedicated server cannot serve as a compute node.[3] On a Dell quote, that is a server line item, not a footnote.

Two facts about packaging trip people up. SHARP binaries ship as part of HPC-X, MLNX_OFED and UFM, where UFM includes the Aggregation Manager only; with MLNX_OFED the default install path is /opt/mellanox/sharp and HPCX_SHARP_DIR points at it.[3] And on the DOCA side, the DOCA-Host page lists opensm, ibutils2, hcoll and sharp as proprietary packages requiring separate installation - installing a doca-* profile alone gives you neither a subnet manager nor SHARP.[14]

a cabling contract, not a switch feature
Rail-optimized fat tree — one slice: 3 nodes × 4 rails, 4 leaf, 2 spineS0spine (root)aggregation nodeS1spine (root)aggregation nodeL0leaf — rail 0aggregation nodeL1leaf — rail 1aggregation nodeL2leaf — rail 2aggregation nodeL3leaf — rail 3aggregation nodenode n0 — 4 of 8 rails shownr0libsharpr1libsharpr2libsharpr3libsharpnode n1 — 4 of 8 rails shownr0libsharpr1libsharpr2libsharpr3libsharpnode n2 — 4 of 8 rails shownr0libsharpr1libsharpr2libsharpr3libsharp
2 SU
Path

Click one HCA for the source, another for the destination. Hops are counted as switch ASICs traversed — a link count is hops + 1.

Rail-optimized fat tree

  • Every GPU's rail-N port lands on leaf N: "Traffic per rail of the DGX H200 systems is always one hop away from the other 31 nodes in a SU. Traffic between nodes, or between rails, traverses the spine layer."
  • Same rail, different node = 1 switch hop. Different rail = 3 hops through a spine.
  • H200 SuperPOD compute fabric: QM9700 NDR, "Rail-optimized, non-blocking, full fat-tree network with eight NDR400 connections per system".
  • Nothing is enabled on the switch to get this. It is decided by where the technician plugs the cable.

FAE angle. On an eight-rail PowerEdge XE9680 the rail map is the deliverable. Dell's slot priority for NDR400 1P cards is 33, 37, 35, 39, 32, 36, 34, 38, leaving 31 and 40 for the storage NIC or a BlueField-3 — DPUs over 75 W are legal only in 31/40. Check it against ibdev2netdev and each card's numa_node, then validate with ibdiagnet --rail_validation (→ ibdiagnet2.rails).

DGX H200 SuperPOD RA — Network Fabrics

SHARP aggregation trees on the same switches
  • SHARP offloads collective operations from CPUs and GPUs into the switches. The switches highlighted here are the aggregation nodes.
  • Two pieces: "sharp_am, which runs in UFM, and libsharp, which is linked to client applications running on the compute nodes." The AM is "a central entity running on a dedicated server with a master Subnet Manager. This dedicated server cannot serve as a compute node."
  • Routing engine is a hard prerequisite: "Tree based topologies: updn, ar_updn, ftree, ar_ftree; DragonFly+ topology: dfp; Hypercube topologies: dor routing engine with dor_hyper_cube_mode enabled."
  • IPoIB must be up on the compute nodes — SHARP uses UD multicast for result distribution.
  • Per-ASIC ceilings: Quantum up to 126 trees in the subnet (63 low-latency + 63 streaming, one active streaming tree per switch); Quantum-2 up to 1023 (511 + 511, one active tree per port). ConnectX-5 does low-latency trees only; ConnectX-6 and above add streaming.
  • Dynamic trees are the default from SHARP 3.4 — built per job, deleted when the job ends — and are "not supported for Hypercube topologies".
  • FAE angle: a clean ibdiagnet proves nothing about SHARP. It "does not verify communication between libsharp and sharp_am, nor whether SHARP jobs can be successfully created."
sharp_hello -d mlx5_0:1 -v 3   # expect  type:LLT …  and  Test Passed.
SHARP_COLL_ENABLE_SAT=1        # adds a type:SAT streaming tree
ibdiagnet --sharp              # Fabric Summary → IB Aggregation Nodes

NVIDIA SHARP 3.16.0 — Installation

Scalable-unit arithmetic — 2 SU

DGX H200 SuperPOD compute fabric — QM9700 NDR

Sources: opensm(8) · UFM SM defaults · MLNX-OS Subnet Manager · SHARP environment · Quantum-X800 switches · MCA4J80 ACC · ibdiagnet · ibdiagnet dump files · Dell XE9680 technical guide

SHARP overlay: the highlighted switches are the aggregation nodes, and the tree is built out of the same links your routing engine already uses. Switch to the SLG shape and read what the panel says about which engine that topology forces.

2Turning it on, and the prerequisites that are not switches

Enabling SHARP in UFM Enterprise is a config edit plus a restart. The gv.cfg block is [Sharp] with sharp_enabled = true, and optionally sharp_allocation_enabled = true; on the UFM Appliance the equivalent is the CLI enable command, and in both cases a UFM restart is required after making the change.[8][2] The current documentation adds a version note worth remembering on an upgrade call: starting UFM v6.23.0, sharp_enabled is set to true by default, and a UFM Enterprise upgrade maintains the previous configuration.[2]

Separately, the subnet manager has its own parameter: sharp_enabled defaults to 2, where 0 means ignore SHARP with no SHARP support, 1 means disable SHARP on all supporting switches, and 2 means enable SHARP on all supporting switches.[9] On the appliance CLI these are ib sm sharp enable, no ib sm sharp enable and ib sm sharp ignore, the last of which does not change the current switch configuration; and it is not possible to modify the SHARP support parameter while OpenSM is running.[10]

The prerequisites list from the environment page is the one to work through with a customer, because most of it is not about switches at all. Run sharp_am as root. Make sure the onboard subnet manager is disabled in the managed switches. The AM needs a dedicated server with a master SM that cannot be a compute node. Configure TCP/IP, because the AM and the clients talk over TCP/IP. And enable IPoIB on the compute servers in order to enable using UD multicast for result distribution in SHARP.[3] On the transport itself: by default sharp_am communicates with libsharp clients over IPoIB using TCP port 6126, and setting smx_protocol = 1 in sharp_am.cfg switches to native IB via UCX; on a UFM Appliance Gen 3.x the firewall blocks 6126 until you open it.[7]

The routing requirement is quoted verbatim because it is a design constraint, not a tuning knob: tree based topologies use updn, ar_updn, ftree or ar_ftree; DragonFly+ topology uses dfp; hypercube topologies use the dor routing engine with dor_hyper_cube_mode enabled.[3] Combine that with the previous lesson: an engine chosen for deadlock-freedom on an irregular fabric, such as LASH or Nue, is not on this list.[3]

3What the ASIC and the adapter allow

Two ceilings decide how many jobs can use SHARP at once, and they are per generation. NVIDIA Quantum supports up to 126 aggregation trees in the subnet, 63 low-latency trees and 63 streaming aggregation trees, and the number of SHARP streaming aggregation operations is limited to one active tree per switch. NVIDIA Quantum-2 supports up to 1023 aggregation trees in the subnet, 511 low-latency and 511 streaming, and the limit is one active tree per port.[3] The generation mapping from the product side is that QM9700 and Quantum-2 introduce the third generation of SHARP, SHARPv3.[15]

The adapter matters as much as the switch: ConnectX-5 supports SHARP low latency operation only, while ConnectX-6 and above support both SHARP low latency and streaming aggregation operations.[3] On a mixed customer pool, the oldest adapter in the job sets what that job can use.

Tree allocation has changed default once, and the last explicit statement found is in the 3.8 documentation: in SHARP v3.3 and earlier, sharp_am used to operate in static trees mode by default, and as of SHARP v3.4 the default operation mode is dynamic trees, which is recommended as the preferred option.[4] Dynamic trees are created per job and deleted when the job ends.[4] Their parameters are dynamic_tree_allocation, dynamic_tree_algorithm (FatTree-oriented by default, with a QFT or Dragonfly variant), and the note that if the number of root switches in the fabric is larger than 126 when using the FatTree-oriented algorithm, it is desirable to modify max_trees_to_build to equal the number of root switches; a sharp_am restart is required.[4] The limitation is explicit: dynamic trees are available for Fat-Tree, Quasi-Fat-Tree and Dragonfly topologies and are not supported for Hypercube topologies.[4] Treat the SHARP 3.16 behaviour as most likely unchanged but state it as of the 3.8 documentation, which is the last page that says it outright.[4][1]

A useful definition to carry to a customer call: a SHARP tree is a set of switches and their connected links to be used by one or more SHARP jobs; a single tree can be used by multiple jobs as long as they use different areas of the tree, and a single job can use multiple trees when it operates on multiple rails, each rail using a different tree.[4]

4Reading a sharp_hello transcript field by field

sharp_hello verifies that a SHARP client can communicate with sharp_am and successfully create a SHARP job; it checks job creation only and does not perform data aggregation.[2] Its usage is sharp_hello <-d | --ib_dev> <device> [OPTIONS] with -v setting the libsharp collective verbosity level, default 2, on a scale of 0 fatal, 1 error, 2 warn, 3 info, 4 debug, 5 trace.[2] The documented invocation and its output:

$ sharp_hello -d mlx5_0:1 -v 3
[thor001:0:15042 - context.c:751] INFO tree_info: type:LLT tree idx:0 treeID:0x0 caps:0x6 quota: ( osts:167 user_data_per_ost:1024 max_groups:167 max_qps:1 max_group_channels:1)
Test Passed.

[2] Field by field: type:LLT is a low-latency tree, and type:SAT is the streaming aggregation tree that appears as a second line when you set SHARP_COLL_ENABLE_SAT=1, in the documented example as type:SAT tree idx:1 treeID:0x3f caps:0x16.[2] treeID identifies which tree the AM handed this job. The quota block is the resource grant - osts, user_data_per_ost, max_groups, max_qps, max_group_channels - and is what shrinks when the fabric’s trees are already busy. The log lines also expose rail_idx per rail and an mlid per group, the multicast LID over which results are distributed.[2] Test Passed. means one thing only: a job was created.[2]

Two expected-output markers from the 3.0 testing page make good grep targets in a script: INFO job (ID: ...) and INFO tree_info: type:LLT, followed by Test Passed.[6] The next rung of proof is sharp_coll_test, which measures bandwidth between the node’s HCA and its connected switch and also verifies SHARP data transfer, and then $HPCX_SHARP_DIR/sbin/sharp_benchmark.sh, whose mandatory environment is sharp_ib_dev="mlx5_0:1" plus sharp_hostlist, with sharp_ppn defaulting to 1 and sharp_test_iters to 10000.[2][6]

One environment gotcha that costs an afternoon: by default sharp_am blocks libsharp from running on management nodes, including the active and standby UFM machines; to run a client there you set ignore_sm_guids = False in conf/sharp/sharp_am.cfg and restart sharp_am.[2] So testing from the UFM box itself is the one place where a correct setup still fails.

SymptomBlueField-3 on a Dell Pow…SymptomDev / environment: build,…SymptomSample runs, exits cleanl…CheckAre hugepages allocated…
Symptom

Sample runs, exits cleanly, but zero throughput

The shipped tree is the BlueField platform tree, not a SHARP tree. Walk its throughput branch to rehearse the check, expected output, if-not discipline, then apply that exact shape to the five SHARP steps in the next segment.

5The five-step triage, in fixed order

The order matters because the first two steps are answered from the SM configuration, before anyone touches a compute node.

Step Question Command or evidence Rule
1 Is the routing engine on the accepted list? Read routing_engine in the SM configuration Tree topologies need updn, ar_updn, ftree or ar_ftree; dfp for DragonFly+; dor with dor_hyper_cube_mode for hypercubes[3]
2 Is the master SM the switch-embedded one? sminfo, and ibdiagnet2.sm for every SM seen The MLNX-OS SM does not support SHARP; the SHARP prerequisites say to disable the onboard SM in managed switches[11][3]
3 Is IPoIB up on the compute nodes? ip -br addr show ib0, plus reachability to the AM host on TCP 6126 IPoIB is required for UD multicast result distribution, and the AM-client transport defaults to IPoIB TCP 6126[3][7]
4 Can a client create a job? sharp_hello -d mlx5_0:1 -v 3 Expect type:LLT and Test Passed.; it checks job creation only[2]
5 Does aggregation actually happen? sharp_coll_test, then sharp_benchmark.sh sharp_coll_test verifies SHARP data transfer; only a benchmark shows the effect on a collective[2][6]

Fabric-side, ibdiagnet --sharp collects SHARP configuration, with --sharp_control_version <0|1|2> defaulting to 0 meaning all, and --sharp_opt accepting csc, dsc, dscp, ad_hoc, trees; the results land in ibdiagnet2.sharp.[12][13] The documented worked command on the SHARP side is ibdiagnet --sharp --fabric_summary followed by cat /var/tmp/ibdiagnet2/ibdiagnet2.sharp | grep -c TreeID.[6] Two cautions before you paste that into a customer runbook: NVIDIA pages disagree on ibdiagnet’s default output directory, so read the tool’s own tail line rather than assuming a path; and --fabric_summary appears in the SHARP guide’s worked command but not in the IBUtils2 flag table, so check ibdiagnet -h on the build in front of you.[6][12] The Fabric Summary itself is what you are after, and its aggregation-node line is the number to read:

Fabric Summary
Total Nodes            : 24
IB Switches            : 4
IB Channel Adapters    : 16
IB Aggregation Nodes   : 4
IB Routers             : 0
[5]
From transcript to verdict

A customer sends this, with the note “it says passed, so why is our all-reduce no faster?”

$ sharp_hello -d mlx5_0:1 -v 3
[node07:0:20114 - context.c:751] INFO tree_info: type:LLT tree idx:0 treeID:0x0 caps:0x6 quota: ( osts:167 user_data_per_ost:1024 max_groups:167 max_qps:1 max_group_channels:1)
Test Passed.

Reading it:

  1. A job was created, so the control path works: the client reached sharp_am over the IPoIB transport and the AM allocated a tree.[2]
  2. type:LLT means a low-latency tree only. There is no type:SAT line, so streaming aggregation was not requested. Ask them to re-run with SHARP_COLL_ENABLE_SAT=1 and compare; if SAT still does not appear, check the adapter generation, because ConnectX-5 supports low-latency operation only.[2][3]
  3. treeID:0x0 and tree idx:0 say which tree; on a multi-rail job you would expect one entry per rail, each with its own rail_idx.[2][4]
  4. The quota block is a grant, not a measurement. Nothing here is evidence of throughput.[2]
  5. Therefore the answer to their question is that this transcript cannot answer it: sharp_hello checks job creation only and does not perform data aggregation. The next command is sharp_coll_test, then sharp_benchmark.sh with sharp_ib_dev and sharp_hostlist set.[2][6]
  6. In parallel, ask for the routing engine and the master SM. If the engine is not in the accepted list, or the master SM is switch-embedded, the transcript above could not have come from the fabric they think it did - which is itself worth checking.[3][11]

What goes back in the proposal

How it ended

The proposal returns with the aggregation-manager server restored as a line item, the consultant’s dor replaced by an engine on SHARP’s accepted list, IPoIB enabled on the compute nodes for UD multicast result distribution, and the eight ConnectX-5 boxes flagged as low-latency operation only.[3] Handover ends in sharp_coll_test and the benchmark script, not in sharp_hello, which checks job creation only.[2]

The sentence you actually say: your clean ibdiagnet is real, and NVIDIA’s own documentation says it does not verify communication between libsharp and sharp_am, nor whether SHARP jobs can be successfully created.[2]

The proposal goes to the board with the server in it. The board approves the fabric and about 50 nodes instead of 63, and the SE has already redrawn the tree.

Lab

Goal: confirm on the Dell lab every client-side SHARP prerequisite you can control, and document the ones you cannot.

Pre-flight inventory (read-only). ibstat for device, port state and rate; ibdev2netdev for the device-to-interface mapping; ip -br addr for IPoIB addresses; rpm -q ibutils2 opensm or dpkg -l | grep -E 'ibutils2|opensm' for the diagnostic and SM packages. Save all four.

  1. ibdev2netdev - expected: a line per port mapping mlx5_N to an interface, with the IB ports showing an ib interface. Record the mlx5_N:1 form, which is what sharp_hello -d wants. If the mapping shows only Ethernet interfaces, the ports are not in IB mode and the rest of this lab does not apply.
  2. ip -br addr show ib0 - expected: state UP with an address. IPoIB is a SHARP prerequisite for UD multicast result distribution, so a down interface is a finding, not a detail.[3]
  3. cat /sys/class/net/ib0/mtu and cat /sys/class/net/ib0/pkey - expected: the IPoIB MTU and the partition key the interface is using. Record both; they belong in any SHARP escalation you open later.
  4. Check the client package: ls $HPCX_SHARP_DIR if the variable is set, otherwise ls /opt/mellanox/sharp - expected: a bin directory containing sharp_hello. If neither exists, libsharp is not installed here, which is the documented HPC-X responsibility rather than a fabric fault.[3][7]
  5. Test reachability to a would-be AM host on the SHARP control port without changing anything: nc -vz <ufm-host-ipoib> 6126 (or timeout 3 bash -c '</dev/tcp/<ufm-host-ipoib>/6126'). Expected in the Dell lab with no UFM: connection refused or timeout - record it. That is the evidence you would ask a customer for, and on a UFM Appliance Gen 3.x the answer may simply be the firewall.[7]
  6. sharp_hello -d mlx5_0:1 -v 3 - expected in a lab with no sharp_am: a failure to reach the manager. Capture the exact text. Knowing what the failure looks like is worth as much as knowing what success looks like, and this is the only place you can safely collect it.[2]
  7. Write the one-paragraph summary for a customer: which prerequisites you verified locally, which require UFM plus a Quantum switch and therefore cannot be shown on this lab, and what you would ask them to run instead. Re-run the pre-flight commands and diff; expected: no change, since every step above is read-only.
  8. Optional, only in a customer or NVIDIA lab with UFM and a Quantum switch, and with written permission: enable SHARP by setting sharp_enabled = true in the [Sharp] block of conf/gv.cfg and restarting UFM, then run sharp_hello -d mlx5_0:1 -v 3 and ibdiagnet --sharp, then grep -c TreeID on ibdiagnet2.sharp.[8][2][6] Rollback: set sharp_enabled back to its previous value and restart UFM again; capture ibdiagnet --sharp before and after so the diff proves the fabric returned to its original state.

Retrieval check

10 questions from memory. Answer before looking anything up; misses become flashcards.

Explain it to a Dell SE

Explain to a Dell SE, in five sentences, what SHARP moves off the GPUs, what has to be true about the fabric before it can do that, and why a clean fabric diagnostic is not evidence that it works.

14 flashcards for this lesson — 0 in deck. Spaced review lives at /review.

Sources

Facts in this lesson were checked against NVIDIA SHARP 3.16.0 Introduction and Installation; SHARP 3.12.0 installation; SHARP 3.8.0 environment, dynamic trees and testing pages; SHARP 3.0.0 testing page; UFM Enterprise 6.24.1 and 6.25.1; MLNX-OS 3.12.6200 LTS; IBUtils2 2.24.0. Research notes fetched 2026-09-07. Dates are when each page was fetched.

  1. NVIDIA SHARP 3.16.0: Introduction · fetched 2026-09-07
  2. NVIDIA SHARP 3.16.0: NVIDIA SHARP Installation · fetched 2026-09-07
  3. NVIDIA SHARP 3.8.0: Setting up NVIDIA SHARP Environment · fetched 2026-09-07
  4. NVIDIA SHARP 3.8.0: Operating in Dynamic Trees Allocation Mode · fetched 2026-09-07
  5. NVIDIA SHARP 3.8.0: Testing NVIDIA SHARP Setup · fetched 2026-09-07
  6. Testing NVIDIA SHARP Setup | NVIDIA SHARP 3.0.0 · fetched 2026-09-07
  7. NVIDIA SHARP Installation | NVIDIA SHARP 3.12.0 · fetched 2026-09-07
  8. NVIDIA SHARP Integration | UFM Enterprise User Manual 6.25.1 · fetched 2026-09-07
  9. UFM Enterprise 6.24.1 User Manual: UFM Subnet Manager Default Properties · fetched 2026-09-07
  10. UFM Enterprise Appliance Software 1.6.0: InfiniBand Commands · fetched 2026-09-07
  11. Subnet Manager | NVIDIA MLNX-OS User Manual v3.12.6200 LTS · fetched 2026-09-07
  12. ibdiagnet Basic Commands | IBUtils2 · fetched 2026-09-07
  13. ibdiagnet Dump Files | IBUtils2 · fetched 2026-09-07
  14. DOCA-Host Installation and Upgrade | DOCA 3.5.0 · fetched 2026-09-07
  15. QM97XX 1U NDR 400Gbps InfiniBand Switch Systems User Manual: Introduction · fetched 2026-09-07

The same idea elsewhere

Other lessons that cover this ground, sometimes from another course's angle.