[NPU]Move part DynamicGraph func toDynamicPipeline and refactor dynamic graph#36099
[NPU]Move part DynamicGraph func toDynamicPipeline and refactor dynamic graph#36099DanLiu2Intel wants to merge 30 commits into
Conversation
ced3359 to
8638db5
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors the Intel NPU plugin “dynamic graph” path by removing the IDynamicGraph interface, introducing a shared GraphArguments/MemRefType API in common, and moving VM-runtime execution + shape prediction logic into the Level Zero dynamic pipeline. Build wiring is updated so VM utils are a standalone static library target (openvino::npu_vm_utils) and linked where needed.
Changes:
- Replace
IDynamicGraphwithIGraphextensions (get_vm_runtime_handle(),get_num_subgraphs()), and simplifyDynamicGraphaccordingly. - Introduce
dynamic_graph_arguments.hpp(+ impl header) and migrate argument/VM MemRef tracking to the backend pipeline. - Update CMake targets to build/link/install
openvino_npu_vm_utilsas a static library and link it from dependent components.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/plugins/intel_npu/src/utils/src/vm/CMakeLists.txt | Switch VM utils from OBJECT → STATIC lib, add alias and install rule |
| src/plugins/intel_npu/src/compiler_adapter/src/dynamic_graph.cpp | Remove per-call binding/execute/predict logic; expose VM runtime handle |
| src/plugins/intel_npu/src/compiler_adapter/include/dynamic_graph.hpp | Move from IDynamicGraph to IGraph, drop old dynamic-graph-specific APIs |
| src/plugins/intel_npu/src/compiler_adapter/CMakeLists.txt | Stop consuming VM utils as object files; link openvino::npu_vm_utils |
| src/plugins/intel_npu/src/common/src/igraph.cpp | Add default get_vm_runtime_handle() / get_num_subgraphs() implementations |
| src/plugins/intel_npu/src/common/include/intel_npu/common/igraph.hpp | Extend IGraph interface with VM-runtime handle + subgraph count |
| src/plugins/intel_npu/src/common/src/dynamic_graph_arguments.cpp | Move MemRef/GraphArguments implementation out of removed IDynamicGraph |
| src/plugins/intel_npu/src/common/include/intel_npu/common/dynamic_graph_arguments.hpp | New shared MemRefType + GraphArguments API |
| src/plugins/intel_npu/src/common/include/intel_npu/common/dynamic_graph_arguments_impl.hpp | New header-only impl for VM MemRef + execute params lifetime tracking |
| src/plugins/intel_npu/src/common/CMakeLists.txt | Link common against VM utils |
| src/plugins/intel_npu/src/backend/src/zero_dynamic_pipeline.cpp | Implement VM-runtime execute + predict-shape in pipeline |
| src/plugins/intel_npu/src/backend/include/zero_dynamic_pipeline.hpp | Rework binding to use new GraphArguments; add predict-shape API |
| src/plugins/intel_npu/src/backend/src/zero_dynamic_infer_request.cpp | Route predict-shape through pipeline static helper; use new MemRefType |
| src/plugins/intel_npu/src/backend/include/zero_dynamic_infer_request.hpp | Update signatures to new MemRefType |
| src/plugins/intel_npu/src/backend/src/zero_device.cpp | Detect dynamic graphs via get_vm_runtime_handle() rather than RTTI |
| src/plugins/intel_npu/src/common/include/intel_npu/common/idynamic_graph.hpp | Remove obsolete interface |
Comments suppressed due to low confidence (2)
src/plugins/intel_npu/src/common/src/dynamic_graph_arguments.cpp:138
- [BLOCKER] GraphArguments::setArgumentProperties() can read past the end of the provided strides vector.
In assign_slot(), when _dimsCount==0 the code resizes slot._strides to strides.size(), but then unconditionally loops i < slot._dimsCount (== sizes.size()) and indexes strides[i]. If strides.size() != sizes.size() (e.g. empty strides for scalar/unknown-strides tensors), this is out-of-bounds and will crash in the dynamic pipeline/predict-shape paths.
Please validate strides.size() == sizes.size() (or treat empty strides as contiguous and compute them from sizes), and always size slot._strides to sizes.size().
src/plugins/intel_npu/src/utils/src/vm/CMakeLists.txt:27
- [MEDIUM] openvino_npu_vm_utils was converted from an OBJECT library to a standalone STATIC library, but it still doesn't declare its link dependencies.
npu_vm_runtime_api.cpp uses ov::util (make_plugin_library_name/load_shared_object/get_symbol). With a STATIC library, relying on every consumer to link the right OpenVINO utility targets is brittle and can cause link-order failures when openvino::npu_vm_utils is consumed independently.
Please add an explicit target_link_libraries(openvino_npu_vm_utils ...) (at least openvino::util; and any other required libs) to make the target self-contained.
add_library(${TARGET_NAME} STATIC ${SOURCES})
add_library(openvino::npu_vm_utils ALIAS ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO}
EXPORT_NAME npu_vm_utils)
ov_add_clang_format_target(${TARGET_NAME}_clang FOR_TARGETS ${TARGET_NAME})
target_include_directories(${TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${NPU_UTILS_SOURCE_DIR}/include>
$<TARGET_PROPERTY:openvino::util,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::core::dev,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::runtime::dev,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:npu_vm_runtime_api,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino_npu_zero_utils,INTERFACE_INCLUDE_DIRECTORIES>
)
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
src/plugins/intel_npu/src/common/src/dynamic_graph_arguments.cpp:138
- [BLOCKER] GraphArguments::setArgumentProperties() can read past the end of
strides(and write past_strides) when the caller passes an empty strides vector (common for continuous tensors / tensors withget_strides().empty()).slot._stridesis resized tostrides.size()(possibly 0), but the subsequent loop indexesstrides[i]fori < _dimsCount.
Fix: require strides.empty() || strides.size() == sizes.size(), and when strides.empty() compute contiguous element-strides (e.g., fill _sizes then call slot.updateStride()), otherwise resize _strides to sizes.size() before filling.
src/plugins/intel_npu/src/common/src/dynamic_graph_arguments.cpp:70
- [HIGH] MemRefType::set() assumes
tensor->get_strides()has rank elements and indexes it unconditionally. For OpenVINO tensors,get_strides()can be empty (e.g., sub-byte element types), which would cause out-of-bounds access here.
Fix: if tensor->get_strides().empty(), populate _strides via updateStride() (contiguous row-major) instead of indexing the empty stride vector; otherwise validate strides.size() == _dimsCount before reading.
8d63054 to
be04321
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/plugins/intel_npu/src/compiler_adapter/src/dynamic_graph.cpp:131
- [BLOCKER] prepare_metadata() passes upperBound.data() from a vector that is only reserved (size==0).
upperBound.data()will be nullptr, sonpuVMRuntimeGetMetadatamay write through a null pointer / out of bounds.
Allocate the buffer with the required size (e.g., ZE_MAX_GRAPH_ARGUMENT_DIMENSIONS_SIZE) before passing its data pointer.
ze_graph_argument_properties_3_t arg;
ze_graph_argument_metadata_t meta;
std::vector<int64_t> upperBound;
upperBound.reserve(ZE_MAX_GRAPH_ARGUMENT_DIMENSIONS_SIZE);
if (npuVMRuntimeGetMetadata(_engine, i, &arg, &meta, upperBound.data()) != NPU_VM_RUNTIME_RESULT_SUCCESS) {
614935e to
3aa3eff
Compare
3aa3eff to
5eb56d0
Compare
2be36d3 to
ac57af8
Compare
Details:
Refactor DynamicGraph interface, move vm_execution logic and add static predict_shape func to DynamicPipeline
Details:
Tickets:
AI Assistance: