Skip to content

Commit fc1e103

Browse files
authored
[UIL] Add patch file for flagcx integration into nixl v1.1.0 (#473)
1 parent 166ba3a commit fc1e103

2 files changed

Lines changed: 1783 additions & 0 deletions

File tree

plugin/nixl/README.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# FlagCX → NIXL v1.1.0 Integration Patch
2+
3+
This directory ships `flagcx_p2p_on_nixl_v1.1.0.patch`, a patch that integrates the FlagCX P2P engine into [NIXL](https://github.com/ai-dynamo/nixl) v1.1.0 as a new backend plugin named **`FLAGCX`**.
4+
5+
---
6+
7+
## 1. What the Patch Does
8+
9+
The patch adds a NIXL backend plugin that wraps FlagCX's P2P engine, allowing any NIXL agent to perform one-sided RDMA `READ` between GPUs (or host buffers) using FlagCX as the transport. It is delivered as a single drop-in patch against the v1.1.0 tag.
10+
11+
**Files added** (under `nixl/`):
12+
13+
| Path | Purpose |
14+
|------|---------|
15+
| `src/plugins/flagcx/flagcx_backend.h` / `.cpp` | `nixlFlagcxEngine` — implements the `nixlBackendEngine` virtual interface (`registerMem`, `getConnInfo`, `loadRemoteConnInfo`, `prepXfer`, `postXfer`, `checkXfer`, `getNotifs`, …). |
16+
| `src/plugins/flagcx/flagcx_plugin.cpp` | Plugin entry point (`nixl_plugin_init` / `nixl_plugin_fini`) that the NIXL plugin manager dlopens. |
17+
| `src/plugins/flagcx/meson.build` | Build rules producing `libplugin_FLAGCX.so`, linked against `libflagcx`. |
18+
| `src/plugins/flagcx/README.md` | Plugin-level usage notes inside the NIXL tree. |
19+
| `test/gtest/plugins/flagcx/flagcx_test.cpp` + `meson.build` | gtest-based correctness tests (`BasicXfer` for `READ`). |
20+
21+
**Files modified:**
22+
23+
| Path | Change |
24+
|------|--------|
25+
| `meson.build` (top level) | Adds `'FLAGCX'` to `all_plugins`. |
26+
| `src/plugins/meson.build` | Probes for `libflagcx` via `cc.find_library('flagcx', ...)`; if found and enabled, descends into `src/plugins/flagcx/`. |
27+
| `test/gtest/plugins/meson.build` | Wires the FlagCX gtest into the test build. |
28+
| `examples/python/expanded_two_peers.py` | Tightens the metadata-exchange handshake so the example works correctly with FlagCX. |
29+
30+
**Capabilities (preview release):**
31+
32+
- Internode GPU-to-GPU transfers over RDMA (one-sided `READ`).
33+
- Vectorized transfers via `flagcxP2pEngineReadVector`.
34+
- Auto NIC selection based on PCIe topology at memory-registration time.
35+
- Out-of-band completion notifications via FlagCX's own notif channel.
36+
37+
---
38+
39+
## 2. Applying the Patch
40+
41+
The patch is authored against NIXL **v1.1.0**. Apply it on a fresh checkout of that tag.
42+
43+
```bash
44+
# Clone upstream NIXL and check out v1.1.0
45+
git clone https://github.com/ai-dynamo/nixl.git
46+
cd nixl
47+
git checkout v1.1.0
48+
49+
# Apply the patch (adjust the path to where your FlagCX checkout lives)
50+
git apply /path/to/FlagCX/plugin/nixl/flagcx_p2p_on_nixl_v1.1.0.patch
51+
52+
# Sanity check
53+
git status # should show 11 changed/added files under src/plugins/flagcx, test/gtest/plugins/flagcx, etc.
54+
```
55+
56+
If you prefer a non-`git` workflow, `patch -p1 < flagcx_p2p_on_nixl_v1.1.0.patch` from the NIXL repo root works as well.
57+
58+
---
59+
60+
## 3. Installation
61+
62+
Two stages: build & install **FlagCX** first, then build & install **NIXL** with the FlagCX plugin enabled.
63+
64+
### 3.1 Build FlagCX
65+
66+
```bash
67+
git clone --recursive https://github.com/FlagOpen/FlagCX.git
68+
cd FlagCX
69+
make USE_NVIDIA=1 -j32 # nvidia for example
70+
```
71+
72+
The build produces `libflagcx.so` and the public headers under `FlagCX/build/{lib,include}/`.
73+
74+
(Optional) Verify the FlagCX build with the P2P unit tests:
75+
76+
```bash
77+
cd test/unittest/p2p && make -j32 && ./build/bin/p2p_unit_tests
78+
```
79+
80+
### 3.2 Configure environment
81+
82+
Create an `env.sh` and `source` it before each build/run. Adjust the prefixes to match your layout; do **not** commit credentials.
83+
84+
```bash
85+
#!/bin/bash
86+
# --- FlagCX ---
87+
export FLAGCX_PREFIX=/path/to/FlagCX/build
88+
export LIBRARY_PATH=$FLAGCX_PREFIX/lib:$LIBRARY_PATH
89+
export CPATH=$FLAGCX_PREFIX/include:$CPATH
90+
export LDFLAGS="-L$FLAGCX_PREFIX/lib -Wl,-rpath,$FLAGCX_PREFIX/lib"
91+
export CPPFLAGS="-I$FLAGCX_PREFIX/include"
92+
93+
# --- NIXL install destination ---
94+
export NIXL_PREFIX=/path/to/install_nixl
95+
export LD_LIBRARY_PATH=$NIXL_PREFIX/lib:$FLAGCX_PREFIX/lib:$LD_LIBRARY_PATH
96+
export NIXL_PLUGIN_DIR=$NIXL_PREFIX/lib/x86_64-linux-gnu/plugins
97+
```
98+
99+
```bash
100+
source env.sh
101+
```
102+
103+
### 3.3 Build & install NIXL with the FlagCX plugin
104+
105+
```bash
106+
cd /path/to/nixl # the patched v1.1.0 checkout from §2
107+
108+
meson setup --wipe build \
109+
--prefix=$NIXL_PREFIX \
110+
-Denable_plugins=FLAGCX \
111+
-Dcudapath_inc=/usr/local/cuda/include \
112+
-Dcudapath_lib=/usr/local/cuda/lib64
113+
114+
ninja -C build
115+
ninja -C build install # installs into $NIXL_PREFIX (no sudo required)
116+
```
117+
118+
Verify the plugin shared library landed in the expected location:
119+
120+
```bash
121+
ls $NIXL_PREFIX/lib/x86_64-linux-gnu/plugins/libplugin_FLAGCX.so
122+
```
123+
124+
### 3.4 Install the NIXL Python bindings
125+
126+
> Run this on every machine that will host a NIXL agent (target and initiator).
127+
128+
```bash
129+
cd /path/to/nixl
130+
pip install .
131+
# or, equivalently:
132+
pip install build/src/bindings/python/nixl-meta/nixl-*-py3-none-any.whl
133+
```
134+
135+
---
136+
137+
## 4. Sanity Check
138+
139+
### 4.1 Agent instantiation smoke test
140+
141+
Confirms that the FLAGCX plugin loads and a NIXL agent can be created.
142+
143+
```bash
144+
python3 -c "
145+
from nixl._api import nixl_agent, nixl_agent_config
146+
a = nixl_agent('test', nixl_agent_config(True, True, 0, backends=['FLAGCX']))
147+
print('FLAGCX agent OK')
148+
"
149+
```
150+
151+
Expected output ends with `FLAGCX agent OK`. Logs should also show `Backend FLAGCX was instantiated`.
152+
153+
### 4.2 Two-peer end-to-end transfer
154+
155+
Run the bundled example on two hosts that share an RDMA-capable network. Replace `<HOST_A_IP>` with the target's IP.
156+
157+
```bash
158+
# --- Host A (target) ---
159+
cd /path/to/nixl
160+
python3 examples/python/expanded_two_peers.py \
161+
--mode=target --backend=FLAGCX --use_cuda=true \
162+
--ip=<HOST_A_IP> --port=4242
163+
```
164+
165+
```bash
166+
# --- Host B (initiator) ---
167+
cd /path/to/nixl
168+
python3 examples/python/expanded_two_peers.py \
169+
--mode=initiator --backend=FLAGCX --use_cuda=true \
170+
--ip=<HOST_A_IP> --port=4242
171+
```
172+
173+
A successful run prints, on **both** hosts:
174+
175+
```
176+
NIXL INFO _api.py:369 Backend FLAGCX was instantiated
177+
NIXL INFO _api.py:247 Initialized NIXL agent: <target|initiator>
178+
...
179+
NIXL INFO expanded_two_peers.py:148 Target data verification passed # target only
180+
NIXL INFO expanded_two_peers.py:342 Initiator final data verification passed # initiator only
181+
NIXL INFO expanded_two_peers.py:360 Test Complete.
182+
```
183+
184+
### 4.3 (Optional) P2P throughput benchmark
185+
186+
For a quick perf gut-check, run the FlagCX-backed NIXL benchmark from the FlagCX repo.
187+
188+
```bash
189+
source env.sh
190+
cd /path/to/FlagCX/test/perf/p2p
191+
192+
# --- Server ---
193+
python3 benchmark_flagcx.py --role=server --remote-ip=<SERVER_IP> \
194+
--device=gpu --local-gpu-idx=1 --op-type=read \
195+
--sizes=1048576,4194304,16777216,104857600,1073741824 --iters=20
196+
197+
# --- Client ---
198+
python3 benchmark_flagcx.py --role=client --remote-ip=<SERVER_IP> \
199+
--device=gpu --local-gpu-idx=1 --op-type=read \
200+
--sizes=1048576,4194304,16777216,104857600,1073741824 --iters=20
201+
```
202+
203+
---
204+
205+
## Troubleshooting
206+
207+
- **`flagcx library not found` during `meson setup`** — the plugin's meson rule probes `cc.find_library('flagcx')`. Make sure `LIBRARY_PATH` and `CPATH` from `env.sh` are exported in the same shell that runs `meson setup`.
208+
- **`libplugin_FLAGCX.so: cannot open shared object file`** at runtime — confirm `LD_LIBRARY_PATH` includes both `$NIXL_PREFIX/lib` and `$FLAGCX_PREFIX/lib`, and that `NIXL_PLUGIN_DIR` points at `$NIXL_PREFIX/lib/x86_64-linux-gnu/plugins`.
209+
- **Handshake hangs in the two-peer example** — verify the target's IP is reachable from the initiator and that the chosen `--port` is not blocked by a firewall. FlagCX uses TCP for bootstrap and the configured RDMA fabric for the data path.

0 commit comments

Comments
 (0)