[NNCFGraph] Migrate from nx.DiGraph to nx.MultiDiGraph#3843
Open
daniil-lyakhov wants to merge 1 commit intoopenvinotoolkit:developfrom
Open
[NNCFGraph] Migrate from nx.DiGraph to nx.MultiDiGraph#3843daniil-lyakhov wants to merge 1 commit intoopenvinotoolkit:developfrom
daniil-lyakhov wants to merge 1 commit intoopenvinotoolkit:developfrom
Conversation
9437ebb to
bf47f71
Compare
40c2053 to
8b4c822
Compare
daniil-lyakhov
commented
Feb 5, 2026
2be12e8 to
51401fc
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates NNCF graph representations from nx.DiGraph to nx.MultiDiGraph to support parallel/multi-edges, and updates quantization/hardware-fusing/ignored-pattern logic (notably SDPA and RoPE) plus corresponding tests and reference graphs.
Changes:
- Switched core graph utilities, pattern matching, and insertion-point graphs to
nx.MultiDiGraphand adapted edge handling APIs (get_edges, keyed edges in.dotfiles). - Updated HW fused patterns (
conv -> arithmetic) and ignored patterns (RoPE + SDPA) to account for parallel edges/branching. - Added/updated synthetic models, test fixtures, and many
.dot/JSON references to validate multi-edge behavior across Torch/FX, OpenVINO, and ONNX.
Reviewed changes
Copilot reviewed 97 out of 114 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/render_dot_to_svg.py | Uses nx.MultiDiGraph when rendering .dot graphs to preserve multi-edges. |
| tools/clip_dot.py | Uses nx.MultiDiGraph for reading and producing clipped graphs with possible parallel edges. |
| tests/torch/utils.py | Updates comparable graph conversion to output nx.MultiDiGraph. |
| tests/torch/test_graph_analysis.py | Updates mock graph to MultiDiGraph and edge construction without parallel-port field. |
| tests/torch/fx/test_weights_compression.py | Updates edge retrieval for multi-edge API and parameterizes RoPE degree. |
| tests/torch/fx/test_quantizer_config.py | Adds fixtures for degree-2 arithmetic patterns and split-based transformer graphs. |
| tests/torch/fx/test_quantizer.py | Removes parallel_input_port_ids usage in normalization helper. |
| tests/torch/fx/test_models.py | Adds YOLO26 attention block to FX model cases. |
| tests/torch/function_hook/quantization/test_weights_compression.py | Parameterizes RoPE model creation with degree. |
| tests/torch/function_hook/quantization/test_quantizer_config.py | Adds fixtures mirroring FX config tests (degree-2 + split transformer). |
| tests/torch/function_hook/quantization/test_quantized_graphs.py | Adds models for parallel edges + YOLO26; updates RoPE to degree=2. |
| tests/torch/function_hook/quantization/helper.py | Adds builder for degree-2 conv->arithmetic graph template. |
| tests/torch/data/fx/yolo26_attn_block.dot | Adds FX reference .dot for YOLO26 attention block. |
| tests/torch/data/fx/reference_metatypes/yolo26_attn_block.json | Adds metatype reference for YOLO26 attention block. |
| tests/torch/data/function_hook/sparsify_activations/three_linear_sparse_activations.dot | Updates .dot format to include multi-edge key= and non-strict header. |
| tests/torch/data/function_hook/sparsify_activations/three_linear_int8_sym_weights_sparse_activations.dot | Same .dot updates for int8 sparse-activations reference. |
| tests/torch/data/function_hook/sparsify_activations/three_linear_ignore1_sparse_activations.dot | Same .dot updates for ignore-scope reference. |
| tests/torch/data/function_hook/sparsify_activations/three_linear_ignore1_int8_sym_weights_sparse_activations.dot | Same .dot updates for ignore-scope + int8 reference. |
| tests/torch/data/function_hook/sparsify_activations/linear_sparse_activations.dot | Same .dot updates for single-linear sparse reference. |
| tests/torch/data/function_hook/sparsify_activations/linear_int8_sym_weights_sparse_activations.dot | Same .dot updates for single-linear + int8 reference. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/yolo26_attn_block.dot | Adds quantized-graph .dot reference for YOLO26 attention block. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/unbind_scaled_dot_product_attention_model.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/shared_model.dot | Replaces parallel_input_port_ids with explicit parallel edges via key. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/scaled_dot_product_attention_model.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/rope_model.dot | Updates RoPE .dot to represent parallel concat inputs as multi-edges. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/parallel_edges_model.dot | Adds .dot reference for explicit parallel-edge model. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/lenet.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/quantization/test_quantized_graphs/embedding_model.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/pruning_and_quantization/prune_ptq_model.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/nncf_graph/model_graph_with_shared_parameters.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/nncf_graph/model_graph_gru.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/nncf_graph/convert_to_nncf_graph_multi_edges.dot | Updates reference from “parallel ports” to explicit multi-edges. |
| tests/torch/data/function_hook/nncf_graph/convert_to_nncf_graph.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/compress_weights/fq_lora/shared_weights_all_layers_True.dot | Updates .dot to keyed multi-edges. |
| tests/torch/data/function_hook/compress_weights/fq_lora/shared_weights_all_layers_False.dot | Updates .dot to keyed multi-edges. |
| tests/openvino/native/test_nncf_graph_builder.py | Removes parallel_input_port_ids from edge fixtures. |
| tests/openvino/native/test_model_utils.py | Updates direct edge-attr access to include MultiDiGraph edge key. |
| tests/openvino/native/quantization/test_weights_compression.py | Parameterizes RoPE model creation with degree. |
| tests/openvino/native/quantization/test_quantizer_config.py | Adds split + degree-2 graph fixtures and includes OVSplitMetatype. |
| tests/openvino/native/quantization/test_graphs.py | Updates transformer model paramization to use partial(RoPEModel, degree=2). |
| tests/openvino/native/models.py | Updates RoPE model to represent concat degree and adds YOLO26 attention block model. |
| tests/openvino/native/data/2025.4/reference_scales/YOLO26AttentionBlock_performance.json | Adds reference scales for YOLO26 attention block. |
| tests/openvino/native/data/2025.4/reference_scales/YOLO26AttentionBlock_mixed.json | Adds mixed reference scales for YOLO26 attention block. |
| tests/openvino/native/data/2025.4/reference_graphs/quantized/YOLO26AttentionBlock.dot | Adds quantized reference .dot for YOLO26 attention block with keyed edges. |
| tests/openvino/native/data/2025.4/reference_graphs/original_nncf_graph/YOLO26AttentionBlock.dot | Adds original-graph reference .dot for YOLO26 attention block with keyed edges. |
| tests/openvino/native/data/2024.4/reference_graphs/quantized/RoPEModel.dot | Updates RoPE reference .dot to keyed multi-edges and renamed nodes. |
| tests/onnx/test_nncf_graph_builder.py | Adds ONNX multi-edge conversion test using Split. |
| tests/onnx/quantization/test_weights_compression.py | Parameterizes RoPE concat degree for ONNX model builder. |
| tests/onnx/quantization/test_quantizer_config.py | Adds split + degree-2 fixtures and includes ONNXSplitMetatype. |
| tests/onnx/models.py | Adds synthetic ONNX model with parallel edges via repeated Concat inputs. |
| tests/onnx/data/reference_graphs/quantization/synthetic/multi_input_output_parallel_edges_model.dot | Adds keyed-edge reference graph for ONNX parallel-edges synthetic model. |
| tests/onnx/data/reference_graphs/original_nncf_graph/synthetic/multi_input_output_parallel_edges_model.dot | Adds keyed-edge original-graph reference for ONNX parallel-edges model. |
| tests/onnx/common.py | Adds ModelBuilder.add_split helper for Split-based models. |
| tests/cross_fw/test_templates/test_quantizer_config.py | Adds template tests/states for degree-2 conv+arith and split-transformer patterns. |
| tests/cross_fw/test_templates/template_test_weights_compression.py | Parameterizes RoPE compression test by concat degree. |
| tests/cross_fw/test_templates/models.py | Adds graph templates for arithmetic degree-2 and split-transformer. |
| tests/cross_fw/test_templates/helpers.py | Updates torch RoPE model to accept degree; adds ParallelEdgesModel + YOLO26AttentionBlock. |
| tests/cross_fw/shared/nx_graph.py | Updates DOT sorting + graph comparison to MultiDiGraph and keyed edges. |
| tests/common/quantization/test_quantizer_propagation_solver.py | Converts mock graphs to MultiDiGraph and updates edge indexing to include keys. |
| tests/common/quantization/test_quantizer_propagation_graph.py | Converts mock graphs to MultiDiGraph and updates edge indexing to include keys. |
| tests/common/quantization/mock_graphs.py | Converts mock graph utilities to MultiDiGraph; ensures in_edges/out_edges use keys. |
| tests/common/graph/test_nncf_graph.py | Adds explicit multi-edge tests and duplicate-edge validation test. |
| tests/common/graph/test_dot_file_rw.py | Updates DOT read/write test graph type to MultiDiGraph. |
| tests/common/data/reference_graphs/dot_rw_reference.dot | Updates DOT reference to non-strict digraph and keyed edge format. |
| src/nncf/torch/quantization/ignored_patterns.py | Reuses shared RoPE pattern builder to support parallel edges. |
| src/nncf/torch/model_graph_manager.py | Updates constant-input resolution for multi-edge graph API. |
| src/nncf/torch/hardware/fused_patterns.py | Updates HW fused patterns to include parallel-edge degree alternatives. |
| src/nncf/torch/graph/graph.py | Updates insertion-point shape extraction using edge-by-port APIs. |
| src/nncf/torch/function_hook/nncf_graph/nncf_graph_builder.py | Emits explicit edges for each meta edge instead of parallel-port encoding. |
| src/nncf/quantization/passes.py | Updates node-removal reconnect logic to handle multi-edges. |
| src/nncf/quantization/ignored_patterns.py | Introduces shared create_rope_pattern supporting concat degree alternatives. |
| src/nncf/quantization/algorithms/weight_compression/torch_fx_backend.py | Updates weight-shape/axes helpers to handle multi-edge APIs and validates edge uniqueness. |
| src/nncf/quantization/algorithms/weight_compression/torch_backend.py | Updates weight/activation port resolution to iterate over multiple edges. |
| src/nncf/quantization/algorithms/smooth_quant/algorithm.py | Updates grouping logic to validate and use a single edge between nodes. |
| src/nncf/openvino/quantization/ignored_patterns.py | Reuses shared RoPE pattern builder and updates SDPA ignored pattern to include split. |
| src/nncf/openvino/hardware/fused_patterns.py | Updates HW fused patterns to include parallel-edge degree alternatives. |
| src/nncf/openvino/graph/nncf_graph_builder.py | Emits explicit edges per OpenVINO input port instead of parallel-port encoding. |
| src/nncf/onnx/quantization/ignored_patterns.py | Reuses shared RoPE pattern builder and updates SDPA ignored pattern to include split. |
| src/nncf/onnx/hardware/fused_patterns.py | Updates HW fused patterns to include parallel-edge degree alternatives. |
| src/nncf/onnx/graph/onnx_helper.py | Updates input-port lookup to return all matching input ports for parallel edges. |
| src/nncf/onnx/graph/nncf_graph_builder.py | Updates ONNX graph builder to create explicit multi-edges and disambiguate repeated inputs. |
| src/nncf/experimental/torch/sparsify_activations/torch_backend.py | Updates activation-port resolution to iterate over multiple edges. |
| src/nncf/common/utils/dot_file_rw.py | Updates DOT reader to return nx.MultiDiGraph. |
| src/nncf/common/insertion_point_graph.py | Migrates insertion-point graph to MultiDiGraph and updates edge/key handling. |
| src/nncf/common/graph/patterns/patterns.py | Migrates GraphPattern to MultiDiGraph and adds join_patterns_parallel. |
| src/nncf/common/graph/graph_matching.py | Uses MultiDiGraphMatcher for pattern matching on MultiDiGraph graphs. |
| src/nncf/common/graph/graph.py | Migrates core NNCFGraph to MultiDiGraph; replaces parallel-port encoding with explicit multi-edges. |
Comments suppressed due to low confidence (1)
src/nncf/common/utils/dot_file_rw.py:1
read_dot_graphnow returnsnx.MultiDiGraph, butwrite_dot_graphstill type-annotatesnx.DiGraph. Consider widening the annotation (e.g.,nx.MultiDiGraphor a union of graph types) to reflect actual usage and prevent confusion in downstream call sites.
# Copyright (c) 2026 Intel Corporation
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
daniil-lyakhov
commented
Feb 13, 2026
485ee5a to
8337ef2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
nx.MultiDiGraphinstead ofnx.DiGraphconv -> arithmeticis updated to have 1 and 2 degrees edges like on this picture:Reason for changes
Related tickets
174691
179960
Tests
(Could not quantize yolo26 SDPA subgraph correctly due to the issue [TorchFX] Do not propagate quantizers through
__get_item__when input/output has different numel #3109)Jobs
Test WC: https://github.com/openvinotoolkit/nncf/actions/runs/21724379639 - Green
Test examples: https://github.com/openvinotoolkit/nncf/actions/runs/21724373555 - Green
PTQ: NNCF/job/manual/job/post_training_quantization/804/ - Green