Commit c2f79a1
authored
Graph node follow-ups: repr, containment, empty(), registry docs (#1859)
* Reorganize graph test files for clarity
Rename test files to reflect what they actually test:
- test_basic -> test_graph_builder (stream capture tests)
- test_conditional -> test_graph_builder_conditional
- test_advanced -> test_graph_update (moved child_graph and
stream_lifetime tests into test_graph_builder)
- test_capture_alloc -> test_graph_memory_resource
- test_explicit* -> test_graphdef*
Made-with: Cursor
* Enhance Graph.update() and add whole-graph update tests
- Extend Graph.update() to accept both GraphBuilder and GraphDef sources
- Surface CUgraphExecUpdateResultInfo details on update failure instead
of a generic CUDA_ERROR_GRAPH_EXEC_UPDATE_FAILURE message
- Release the GIL during cuGraphExecUpdate via nogil block
- Add parametrized happy-path test covering both GraphBuilder and GraphDef
- Add error-case tests: unfinished builder, topology mismatch, wrong type
Made-with: Cursor
* Add AdjacencySet proxy for pred/succ and GraphNode.remove()
Replace cached tuple-based pred/succ with mutable AdjacencySet backed
by direct CUDA driver calls. Add GraphNode.remove() wrapping
cuGraphDestroyNode.
Made-with: Cursor
* Add edge mutation support and MutableSet interface for GraphNode adjacencies
Enable adding/removing edges between graph nodes via AdjacencySet (a
MutableSet proxy on GraphNode.pred/succ), node removal via discard(),
and property setters for bulk edge replacement. Includes comprehensive
mutation and interface tests.
Closes part of #1330 (step 2: edge mutation on GraphDef).
Made-with: Cursor
* Use requires_module mark for numpy version checks in mutation tests
Replace inline skipif version check with requires_module(np, "2.1")
from the shared test helpers, consistent with other test files.
Made-with: Cursor
* Fix empty-graph return type: return set() instead of () for nodes/edges
Made-with: Cursor
* Rename AdjacencySet to AdjacencySetProxy, add bulk ops and safety guards
Rename class and file to AdjacencySetProxy to clarify write-through
semantics. Add bulk-efficient clear(), __isub__(), __ior__() overrides
and remove_edges() on the Cython core. Guard GraphNode.discard() against
double-destroy via membership check. Filter duplicates in update(). Add
error-path tests for wrong types, cross-graph edges, and self-edges.
Made-with: Cursor
* Add destroy() method with handle invalidation, remove GRAPH_NODE_SENTINEL
Replace discard() with destroy() which calls cuGraphDestroyNode and then
zeroes the CUgraphNode resource in the handle box via
invalidate_graph_node_handle. This prevents stale memory access on
destroyed nodes. Properties (type, pred, succ, handle) degrade gracefully
to None/empty for destroyed nodes.
Remove the GRAPH_NODE_SENTINEL (0x1) approach in favor of using NULL for
both sentinels and destroyed nodes, which is simpler and avoids the risk
of passing 0x1 to driver APIs that treat it as a valid pointer.
Made-with: Cursor
* Add GraphNode identity cache for stable Python object round-trips
Nodes retrieved via GraphDef.nodes(), edges(), or pred/succ traversal
now return the same Python object that was originally created, enabling
identity checks with `is`. A C++ HandleRegistry deduplicates
CUgraphNode handles, and a Cython WeakValueDictionary caches the
Python wrapper objects.
Made-with: Cursor
* Purge node cache on destroy to prevent stale identity lookups
Made-with: Cursor
* Skip NULL nodes in graph_node_registry to fix sentinel identity collision
Sentinel (entry) nodes use NULL as their CUgraphNode, so caching them
under a NULL key caused all sentinels across different graphs to share
the same handle. This made nodes built from the wrong graph's entry
point, causing CUDA_ERROR_INVALID_VALUE for conditional nodes and hash
collisions in equality tests.
Made-with: Cursor
* Unregister destroyed nodes from C++ graph_node_registry
When a node is destroyed, the driver may reuse its CUgraphNode pointer
for a new node. Without unregistering the old entry, the registry
returns a stale handle pointing to the wrong node type and graph.
Made-with: Cursor
* Add dedicated test for node identity preservation through round-trips
Made-with: Cursor
* Add handle= to all GraphNode subclass __repr__ for debugging
Every subclass repr now starts with handle=0x... (the CUgraphNode
pointer) followed by type-specific identity/parameter data. Dynamic
queries (pred counts, subnode counts) are removed in favor of
deterministic, cheap fields. This makes set comparison failures in
test output readable when debugging graph mutation tests.
Made-with: Cursor
* Rename _node_cache/_cached to _node_registry/_registered
Aligns Python-side terminology with the C++ graph_node_registry.
Made-with: Cursor
* Fix unregister_handle and rename invalidate_graph_node_handle
unregister_handle: remove the expired() guard that prevented erasure
when the shared_ptr was still alive. This caused stale registry
entries after destroy(), leading to CUDA_ERROR_INVALID_VALUE when
the driver reused CUgraphNode pointer values.
Rename invalidate_graph_node_handle -> invalidate_graph_node for
consistency with the rest of the graph node API.
Made-with: Cursor
* Add cheap containment test and early type check for AdjacencySetProxy
Add _AdjacencySetCore.contains() that checks membership by comparing
raw CUgraphNode handles at the C level, avoiding Python object
construction. Uses a 16-element stack buffer for a single driver call
in the common case.
Move the type check in update() inline next to the extend loop so
invalid input is rejected immediately.
Made-with: Cursor
* Add GraphDef.empty(), stack-buffer query optimization, and registry test
- Add GraphDef.empty() for creating entry-point empty nodes; replace
all no-arg join() calls on GraphDef with empty() in tests.
- Optimize _AdjacencySetCore.query() to use a 16-element stack buffer,
matching the contains() optimization.
- Add test_registry_cleanup exercising destroy(), graph deletion, and
weak-reference cleanup of the node registry.
Made-with: Cursor
* Document the two-level handle and object registry design
Add REGISTRY_DESIGN.md explaining how the C++ HandleRegistry (Level 1)
and Cython _node_registry (Level 2) work together to preserve Python
object identity through driver round-trips. Add cross-references at
each registry instantiation site.
Made-with: Cursor
* Fix import formatting in test_registry_cleanup
Made-with: Cursor
* Optimize GraphDef.nodes() and edges() to try a single driver call
Pre-allocate vectors to 128 entries and pass them on the first call.
Only fall back to a second call if the graph exceeds 128 nodes/edges.
Made-with: Cursor1 parent 5064470 commit c2f79a1
File tree
10 files changed
+235
-84
lines changed- cuda_core
- cuda/core
- _cpp
- _graph/_graph_def
- tests
- graph
10 files changed
+235
-84
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
388 | 388 | | |
389 | 389 | | |
390 | 390 | | |
| 391 | + | |
391 | 392 | | |
392 | 393 | | |
393 | 394 | | |
| |||
894 | 895 | | |
895 | 896 | | |
896 | 897 | | |
| 898 | + | |
897 | 899 | | |
898 | 900 | | |
899 | 901 | | |
| |||
964 | 966 | | |
965 | 967 | | |
966 | 968 | | |
| 969 | + | |
967 | 970 | | |
968 | 971 | | |
969 | 972 | | |
| |||
Lines changed: 42 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| |||
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
90 | | - | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
91 | 95 | | |
92 | 96 | | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| |||
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
146 | | - | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
147 | 149 | | |
148 | | - | |
149 | | - | |
150 | | - | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
151 | 154 | | |
152 | 155 | | |
153 | 156 | | |
| |||
156 | 159 | | |
157 | 160 | | |
158 | 161 | | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
159 | 191 | | |
160 | 192 | | |
161 | 193 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
162 | 172 | | |
163 | 173 | | |
164 | 174 | | |
| |||
322 | 332 | | |
323 | 333 | | |
324 | 334 | | |
325 | | - | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
326 | 338 | | |
327 | 339 | | |
328 | | - | |
| 340 | + | |
329 | 341 | | |
330 | 342 | | |
331 | 343 | | |
332 | 344 | | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
337 | 349 | | |
338 | 350 | | |
339 | 351 | | |
| |||
346 | 358 | | |
347 | 359 | | |
348 | 360 | | |
349 | | - | |
350 | | - | |
351 | | - | |
352 | | - | |
353 | | - | |
354 | | - | |
355 | | - | |
356 | | - | |
357 | | - | |
358 | | - | |
359 | | - | |
360 | 361 | | |
361 | 362 | | |
362 | | - | |
363 | | - | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
364 | 367 | | |
365 | 368 | | |
366 | 369 | | |
| |||
369 | 372 | | |
370 | 373 | | |
371 | 374 | | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
372 | 389 | | |
373 | 390 | | |
374 | 391 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
66 | 67 | | |
67 | 68 | | |
68 | 69 | | |
| |||
0 commit comments