From 64b65f94db3a6c0155f4ed3ec5707bca84f77912 Mon Sep 17 00:00:00 2001 From: Wisbendji Fimerlus Date: Mon, 26 Oct 2026 19:52:13 -0400 Subject: [PATCH 1/2] packaging: backport LP E-core scheduling to OpenVINO 2026.2.1 Include LP efficiency cores in shared executor accounting and allocation so GPU compilation does not dereference an empty streams table when the process affinity contains only LP cores. Keep feasible homogeneous stream widths when unused pools are smaller, preserve unpinned ECORE_ONLY restrictions, and distinguish the E/LP pair from legacy two-type mappings. Retain precomputed tables and pinned mixed stream behavior. Add native regression coverage and prepared-source guards for the corrected executor, and advance the OpenVINO provider RPM release to 2. Tracks https://github.com/openvinotoolkit/openvino/issues/39088. Signed-off-by: Wisbendji Fimerlus --- packaging/fedora/44/package-gate.py | 2 +- packaging/fedora/44/rpm/openvino/SOURCES.md | 31 + .../openvino/check-lp-ecore-executor-guard.py | 68 ++ .../fedora/44/rpm/openvino/openvino.spec | 11 +- .../0016-schedule-lp-efficiency-cores.patch | 895 ++++++++++++++++++ scripts/ci/test_lp_ecore_guard.py | 113 +++ .../tests/fedora_openvino_package_contract.rs | 2 +- 7 files changed, 1119 insertions(+), 3 deletions(-) create mode 100644 packaging/fedora/44/rpm/openvino/check-lp-ecore-executor-guard.py create mode 100644 packaging/fedora/44/rpm/openvino/patches/0016-schedule-lp-efficiency-cores.patch create mode 100644 scripts/ci/test_lp_ecore_guard.py diff --git a/packaging/fedora/44/package-gate.py b/packaging/fedora/44/package-gate.py index 9b462e6..763b661 100644 --- a/packaging/fedora/44/package-gate.py +++ b/packaging/fedora/44/package-gate.py @@ -26,7 +26,7 @@ RECIPES = {'firmware': ('intel-npu-stack-firmware', '1.38.0-1.intelnpu.fc44', 'noarch'), 'driver': ('intel-npu-driver', '1.38.0-1.intelnpu.fc44', 'x86_64'), 'level-zero': ('oneapi-level-zero', '1.32.0-1.intelnpu.fc44', 'x86_64'), - 'openvino': ('openvino', '2026.2.1-1.intelnpu.fc44', 'x86_64')} + 'openvino': ('openvino', '2026.2.1-2.intelnpu.fc44', 'x86_64')} def require(value, message): diff --git a/packaging/fedora/44/rpm/openvino/SOURCES.md b/packaging/fedora/44/rpm/openvino/SOURCES.md index d574b76..21b6a24 100644 --- a/packaging/fedora/44/rpm/openvino/SOURCES.md +++ b/packaging/fedora/44/rpm/openvino/SOURCES.md @@ -285,6 +285,37 @@ behavior unchanged). The same defect is present in `npu_ud_2026_28_rc1` and `check-unbounded-reshape-guard.py` runs after `%prep` and refuses the unguarded spelling in the prepared source. +Patch 0016 schedules LP efficiency cores in the shared stream configuration. +With a process affinity mask holding only LP efficiency cores (Lunar Lake +`taskset -c 4-7` and `4,5`), `update_executor_config()` omitted +`LP_EFFICIENT_CORE_PROC` from its counts and allocation types, produced an +empty streams table and dereferenced element zero: the GPU plugin's +`compile_model` aborts before any inference. Reported upstream as openvino +issue 39088. The patch counts and allocates LP cores, selects the largest +feasible homogeneous stream width across core kinds and NUMA nodes, skips +unused pools too small for that width, scopes zero-count contribution rows +to their ALL_PROC header, and raises a clear exception +instead of reading an empty table. Precomputed streams tables are unchanged. +No-LP behavior is preserved except for the intended correction to mixed-stream +contribution accounting. Regression tests cover requested stream widths, +unused small pools, reservation, pinning and default configurations. +Generated unpinned `ECORE_ONLY` streams use one efficient core kind per stream, +since the existing arena interface cannot represent an E/LP union. A single +LP contribution becomes a typed LP row with its NUMA/socket locality retained. +Pinned mixed streams keep observer-based binding. Singleton TBB mapping also +handles the ordered `[LP, E]` pair only when the original table contains both +efficient kinds and no P/HT cores, without +assuming contiguous type IDs. This does not enable a new TBB union mode or +change precomputed-table contents. Physical enforcement of the core-type hint +depends on TBB topology support; process-affinity GPU tests do not prove it. +As with the existing mapping, OpenVINO and TBB must initialize against a +stable process affinity; changing it between their cached snapshots is not +covered by this backport. +Upstream acceptance is open; drop the patch when an upstream release carries +the fix. +`check-lp-ecore-executor-guard.py` runs after `%prep` and requires the +LP-aware scheduling in the prepared source. + The GPU component also installs its pinned `kernel_selector/cache/cache.json` tuning data beside the plugin. The Linux kernel selector looks up that exact path. `openvino-plugins` owns it and the staged-layout check requires it; the diff --git a/packaging/fedora/44/rpm/openvino/check-lp-ecore-executor-guard.py b/packaging/fedora/44/rpm/openvino/check-lp-ecore-executor-guard.py new file mode 100644 index 0000000..16e3371 --- /dev/null +++ b/packaging/fedora/44/rpm/openvino/check-lp-ecore-executor-guard.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: Apache-2.0 +"""Require LP-efficiency-core scheduling in the prepared OpenVINO source.""" +from pathlib import Path +import sys + +root = Path(sys.argv[1]).resolve(strict=True) +source = root / 'src/inference/src/dev/threading/istreams_executor.cpp' +text = source.read_text(encoding='utf-8') + +unguarded = 'core_types = {MAIN_CORE_PROC, EFFICIENT_CORE_PROC, HYPER_THREADING_PROC};' +required = { + 'std::vector core_types{MAIN_CORE_PROC, EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC, HYPER_THREADING_PROC};': 1, + 'core_types = {EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC};': 1, + 'proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 ? LP_EFFICIENT_CORE_PROC': 1, + 'OPENVINO_ASSERT(!_streams_info_table.empty(),': 1, + 'if (mixed_stream) {': 2, + 'proc_type_table[0][EFFICIENT_CORE_PROC] + proc_type_table[0][LP_EFFICIENT_CORE_PROC]': 2, + 'if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams)': 1, + '_streams > 1 || (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY && !_cpu_pinning);': 1, + '!homogeneous_streams && _streams == 1 &&': 1, + 'while (_threads_per_stream > 1)': 1, + 'if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams &&\n' + ' _threads_per_stream > proc_type_table[i][j]) {\n' + ' continue;\n' + ' }': 1, + 'streams_num += proc_type_table[i][type] / _threads_per_stream;': 1, + 'const auto num_cores = proc_type_table[0][MAIN_CORE_PROC] + proc_type_table[0][EFFICIENT_CORE_PROC] +\n' + ' proc_type_table[0][LP_EFFICIENT_CORE_PROC];': 1, + '_streams_info_table[0][PROC_TYPE] = LP_EFFICIENT_CORE_PROC;': 1, + '_streams_info_table[0][STREAM_NUMA_NODE_ID] = _streams_info_table[1][STREAM_NUMA_NODE_ID];': 1, + '_streams_info_table[0][STREAM_SOCKET_ID] = _streams_info_table[1][STREAM_SOCKET_ID];': 1, +} +requirements = { + 'src/inference/src/dev/threading/istreams_executor.cpp': required, + 'src/inference/src/dev/threading/cpu_streams_executor.cpp': { + 'const auto proc_types = get_org_proc_type_table();': 1, + 'get_tbb_core_type(core_type, core_types, proc_types);': 1, + }, + 'src/inference/src/dev/threading/cpu_streams_executor_internal.cpp': { + 'int get_tbb_core_type(int proc_type,': 1, + 'core_types.size() == 2 && !proc_type_table.empty() &&': 1, + 'proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 &&': 1, + 'proc_type_table[0][MAIN_CORE_PROC] == 0 && proc_type_table[0][HYPER_THREADING_PROC] == 0': 1, + }, + 'src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp': { + 'int get_tbb_core_type(int proc_type,': 1, + 'const std::vector>& proc_type_table);': 1, + }, +} + +if unguarded in text: + raise SystemExit(f'check-lp-ecore-executor-guard: LP-unaware core-type list present in {source}') +if '_threads_per_stream = std::min(_threads_per_stream, proc_type_table[i][type]);' in text: + raise SystemExit(f'check-lp-ecore-executor-guard: unused small pools still reduce stream width in {source}') +for relative, markers in requirements.items(): + source = root / relative + try: + text = source.read_text(encoding='utf-8') + except OSError as error: + raise SystemExit(f'check-lp-ecore-executor-guard: cannot read {source}: {error}') from error + for spelling, count in markers.items(): + if text.count(spelling) != count: + raise SystemExit( + f'check-lp-ecore-executor-guard: expected {count} occurrence(s) of {spelling!r} in {source}, ' + f'found {text.count(spelling)}' + ) +print('check-lp-ecore-executor-guard: ok') diff --git a/packaging/fedora/44/rpm/openvino/openvino.spec b/packaging/fedora/44/rpm/openvino/openvino.spec index 4bf3062..92f4b02 100644 --- a/packaging/fedora/44/rpm/openvino/openvino.spec +++ b/packaging/fedora/44/rpm/openvino/openvino.spec @@ -22,7 +22,7 @@ package or when debugging this package.\ Name: openvino Version: 2026.2.1 -Release: 1.intelnpu.fc44 +Release: 2.intelnpu.fc44 Summary: Toolkit for optimizing and deploying AI inference License: Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause) @@ -77,6 +77,8 @@ Source46: provider-license-evidence.tar Source47: json-3.12.0-LICENSE.MIT Source48: 0015-check-unbounded-reshape-input-bounds.patch Source49: check-unbounded-reshape-guard.py +Source50: 0016-schedule-lp-efficiency-cores.patch +Source51: check-lp-ecore-executor-guard.py ExclusiveArch: x86_64 @@ -251,6 +253,8 @@ mv intel-npu-nn-cost-model thirdparty/npu-compiler/thirdparty/vpucostmodel /usr/bin/patch --batch --forward --fuzz=0 -p1 \ -d thirdparty/npu-compiler < %{SOURCE48} /usr/bin/python3 %{SOURCE49} "$PWD" +/usr/bin/patch --batch --forward --fuzz=0 -p1 < %{SOURCE50} +/usr/bin/python3 %{SOURCE51} "$PWD" /usr/bin/python3 %{SOURCE44} --kind openvino \ --source "$PWD" --archives "$(dirname -- '%{SOURCE0}')" --spec %{_specdir}/openvino.spec \ @@ -438,6 +442,11 @@ cp -a ../provider-notices/openvino ../provider-notices/intel-npu-compiler \ %{_libdir}/libopenvino_tensorflow_lite_frontend.so.%{so_ver} %changelog +* Sat Oct 24 2026 Intel NPU Stack maintainers - 2026.2.1-2.intelnpu.fc44 +- Add 0016 to schedule LP efficiency cores in the shared stream config, so + GPU compile_model no longer aborts when the process affinity leaves only + LP efficiency cores (reported upstream as openvino issue 39088). +- Preserve feasible stream widths when unused core pools are smaller. * Wed Sep 30 2026 Intel NPU Stack maintainers - 2026.2.1-1.intelnpu.fc44 - OpenVINO 2026.2.1 (NPU plugin shared Level Zero command-queue priority fix) and the NPU compiler from npu_ud_2026_28_rc2. Add 0015 to reject an diff --git a/packaging/fedora/44/rpm/openvino/patches/0016-schedule-lp-efficiency-cores.patch b/packaging/fedora/44/rpm/openvino/patches/0016-schedule-lp-efficiency-cores.patch new file mode 100644 index 0000000..d829990 --- /dev/null +++ b/packaging/fedora/44/rpm/openvino/patches/0016-schedule-lp-efficiency-cores.patch @@ -0,0 +1,895 @@ +Subject: [PATCH] Schedule LP efficiency cores in the shared stream config + +When a process affinity mask leaves only LP efficiency cores, +update_executor_config() omitted LP_EFFICIENT_CORE_PROC from the little-core +count and allocation types. With more than one requested stream, the table +could remain empty and its first-element access aborted GPU compilation. +Reported upstream as openvinotoolkit/openvino issue 39088. + +Count LP cores as little cores, allocate them independently for ANY_CORE and +ECORE_ONLY, and keep PCORE_ONLY free of LP cores when P cores are available. +Choose the largest requested stream width that the eligible per-core-kind, +per-NUMA-node pools can supply. Skip smaller unused pools rather than reducing +otherwise feasible streams or emitting partial homogeneous rows. This also +preserves explicit P-core requests when an unused SMT pool is smaller. + +Contribution rows after an ALL_PROC header carry zero streams. The zero-stream +helper selects LP cores before hyperthreads, and an empty generated table +raises a clear exception instead of reading element zero. Precomputed tables +are unchanged. No-LP behavior is preserved except for the intended correction +to mixed-stream contribution accounting. + +Keep generated unpinned ECORE_ONLY streams homogeneous: the existing arena +interface cannot express an E/LP union. A single LP contribution becomes a +typed row with its original locality. Correct singleton TBB type selection +for the ordered [LP, E] pair only when the original table contains both +efficient kinds and no P/HT cores; preserve existing no-LP, P-present, +three-type and automatic mappings. Pinned mixed streams retain +their observer-based binding. This does not add a new TBB union mode. + +Native regression tests cover LP-only preferences, reservation, pinning, +fragmented pools, NUMA, default factories, arena routing, noncontiguous TBB +type IDs and precomputed tables. The source +guard runs after %prep; it does not replace these behavioral tests. +Upstream acceptance remains open. Drop this patch when a release carries the +corresponding fix. + +--- +diff --git a/src/inference/src/dev/threading/istreams_executor.cpp b/src/inference/src/dev/threading/istreams_executor.cpp +--- a/src/inference/src/dev/threading/istreams_executor.cpp ++++ b/src/inference/src/dev/threading/istreams_executor.cpp +@@ -95,7 +95,8 @@ + if (proc_type_table.empty()) { + return 1; + } +- const auto num_cores = proc_type_table[0][MAIN_CORE_PROC] + proc_type_table[0][EFFICIENT_CORE_PROC]; ++ const auto num_cores = proc_type_table[0][MAIN_CORE_PROC] + proc_type_table[0][EFFICIENT_CORE_PROC] + ++ proc_type_table[0][LP_EFFICIENT_CORE_PROC]; + if (0 == num_cores % 4) + return std::max(4, num_cores / 4); + else if (0 == num_cores % 5) +@@ -116,20 +117,22 @@ + } + + int num_cores = proc_type_table[0][ALL_PROC]; ++ const auto little_cores = proc_type_table[0][EFFICIENT_CORE_PROC] + proc_type_table[0][LP_EFFICIENT_CORE_PROC]; + +- if (proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && proc_type_table[0][MAIN_CORE_PROC] > 0) { ++ if (little_cores > 0 && proc_type_table[0][MAIN_CORE_PROC] > 0) { + if (streamConfig._thread_preferred_core_type == ov::hint::SchedulingCoreType::ANY_CORE) { + num_cores = proc_type_table[0][ALL_PROC]; + } else if (streamConfig._thread_preferred_core_type == ov::hint::SchedulingCoreType::PCORE_ONLY) { + num_cores = proc_type_table[0][MAIN_CORE_PROC]; + } else if (streamConfig._thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY) { +- num_cores = proc_type_table[0][EFFICIENT_CORE_PROC]; ++ num_cores = little_cores; + } + } + + const auto threads = streamConfig._threads ? streamConfig._threads : num_cores; + int threads_per_stream = streamConfig._streams ? std::max(1, threads / streamConfig._streams) : threads; +- if (proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && proc_type_table[0][MAIN_CORE_PROC] > 0 && ++ if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] == 0 && proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && ++ proc_type_table[0][MAIN_CORE_PROC] > 0 && + streamConfig._thread_preferred_core_type == ov::hint::SchedulingCoreType::ANY_CORE) { + if (streamConfig._streams > 1) { + threads_per_stream = +@@ -194,7 +197,8 @@ + + const auto total_num_cores = proc_type_table[0][ALL_PROC]; + const auto total_num_big_cores = proc_type_table[0][MAIN_CORE_PROC] + proc_type_table[0][HYPER_THREADING_PROC]; +- const auto total_num_little_cores = proc_type_table[0][EFFICIENT_CORE_PROC]; ++ const auto total_num_little_cores = ++ proc_type_table[0][EFFICIENT_CORE_PROC] + proc_type_table[0][LP_EFFICIENT_CORE_PROC]; + + if ((total_num_little_cores == 0 && _thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY) || + (total_num_big_cores == 0 && _thread_preferred_core_type == ov::hint::SchedulingCoreType::PCORE_ONLY) || +@@ -225,21 +229,54 @@ + return; + } + ++ const size_t start = proc_type_table.size() > 1 ? 1 : 0; ++ std::vector core_types{MAIN_CORE_PROC, EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC, HYPER_THREADING_PROC}; ++ if (_thread_preferred_core_type == ov::hint::SchedulingCoreType::PCORE_ONLY) { ++ core_types = {MAIN_CORE_PROC, HYPER_THREADING_PROC}; ++ } else if (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY) { ++ core_types = {EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC}; ++ } ++ // The unpinned arena interface selects one core kind, not an E/LP ++ // union. Keep an ECORE_ONLY stream representable by that interface. ++ const bool homogeneous_streams = ++ _streams > 1 || (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY && !_cpu_pinning); ++ if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams) { ++ // A typed stream must fit within one core kind and one NUMA node. ++ // Keep the requested width when the usable pools can supply it; ++ // an unused smaller pool must not reduce every stream's width. ++ while (_threads_per_stream > 1) { ++ int streams_num = 0; ++ for (int type : core_types) { ++ for (size_t i = start; i < proc_type_table.size(); ++i) { ++ streams_num += proc_type_table[i][type] / _threads_per_stream; ++ } ++ } ++ if (streams_num >= _streams) { ++ break; ++ } ++ --_threads_per_stream; ++ } ++ } ++ + // create stream_info_table based on core type + std::vector stream_info(CPU_STREAMS_TABLE_SIZE, 0); + stream_info[THREADS_PER_STREAM] = _threads_per_stream; + stream_info[STREAM_NUMA_NODE_ID] = 0; + stream_info[STREAM_SOCKET_ID] = 0; + int cur_threads = _streams * _threads_per_stream; +- if (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY) { ++ if (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY && ++ proc_type_table[0][LP_EFFICIENT_CORE_PROC] == 0) { + stream_info[PROC_TYPE] = EFFICIENT_CORE_PROC; + stream_info[NUMBER_OF_STREAMS] = _streams; + _streams_info_table.push_back(std::move(stream_info)); + } else { +- int start = proc_type_table.size() > 1 ? 1 : 0; +- std::vector core_types; + // Using cores crossed sockets or hyper threads when streams = 1 +- if (_streams == 1 && _threads_per_stream > proc_type_table[start][ov::MAIN_CORE_PROC]) { ++ const auto first_core_type = _thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY ++ ? EFFICIENT_CORE_PROC ++ : MAIN_CORE_PROC; ++ const bool mixed_stream = ++ !homogeneous_streams && _streams == 1 && _threads_per_stream > proc_type_table[start][first_core_type]; ++ if (mixed_stream) { + stream_info[NUMBER_OF_STREAMS] = _streams; + stream_info[PROC_TYPE] = ALL_PROC; + stream_info[STREAM_NUMA_NODE_ID] = proc_type_table.size() > 1 ? -1 : 0; +@@ -247,16 +284,19 @@ + _streams_info_table.push_back(stream_info); + stream_info[NUMBER_OF_STREAMS] = 0; + } +- if (_thread_preferred_core_type == ov::hint::SchedulingCoreType::PCORE_ONLY && +- proc_type_table[0][EFFICIENT_CORE_PROC] > 0) { +- core_types = {MAIN_CORE_PROC, HYPER_THREADING_PROC}; +- } else { +- core_types = {MAIN_CORE_PROC, EFFICIENT_CORE_PROC, HYPER_THREADING_PROC}; +- } + for (int j : core_types) { + for (size_t i = start; i < proc_type_table.size(); i++) { + if (proc_type_table[i][j] > 0 && cur_threads > 0) { +- if (_threads_per_stream > proc_type_table[i][j]) { ++ if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams && ++ _threads_per_stream > proc_type_table[i][j]) { ++ continue; ++ } ++ if (mixed_stream || _threads_per_stream > proc_type_table[i][j]) { ++ if (mixed_stream) { ++ // Rows after an ALL_PROC header contribute to ++ // that stream instead of naming new streams. ++ stream_info[NUMBER_OF_STREAMS] = 0; ++ } + stream_info[THREADS_PER_STREAM] = std::min(proc_type_table[i][j], cur_threads); + cur_threads -= stream_info[THREADS_PER_STREAM]; + } else { +@@ -272,8 +312,23 @@ + } + } + } ++ ++ if (_streams_info_table.size() == 2 && _streams_info_table[0][PROC_TYPE] == ALL_PROC && ++ _streams_info_table[0][NUMBER_OF_STREAMS] == 1 && ++ _streams_info_table[1][PROC_TYPE] == LP_EFFICIENT_CORE_PROC && ++ _streams_info_table[1][NUMBER_OF_STREAMS] == 0 && ++ _streams_info_table[0][THREADS_PER_STREAM] == _streams_info_table[1][THREADS_PER_STREAM]) { ++ // A single LP pool needs no mixed row; keep its arena restriction ++ // and locality even when explicit thread pinning is disabled. ++ _streams_info_table[0][PROC_TYPE] = LP_EFFICIENT_CORE_PROC; ++ _streams_info_table[0][STREAM_NUMA_NODE_ID] = _streams_info_table[1][STREAM_NUMA_NODE_ID]; ++ _streams_info_table[0][STREAM_SOCKET_ID] = _streams_info_table[1][STREAM_SOCKET_ID]; ++ _streams_info_table.pop_back(); ++ } + } + ++ OPENVINO_ASSERT(!_streams_info_table.empty(), "No streams could be configured for the available CPU resources."); ++ + if (_cpu_pinning || _cpu_reservation) { + reserve_available_cpus(_streams_info_table, _stream_processor_ids, _cpu_reservation ? CPU_USED : NOT_USED); + } +@@ -342,9 +397,10 @@ + int socket_id = 0; + + if (proc_type_table.size() > 0) { +- core_type = proc_type_table[0][MAIN_CORE_PROC] > 0 +- ? MAIN_CORE_PROC +- : (proc_type_table[0][EFFICIENT_CORE_PROC] > 0 ? EFFICIENT_CORE_PROC : HYPER_THREADING_PROC); ++ core_type = proc_type_table[0][MAIN_CORE_PROC] > 0 ? MAIN_CORE_PROC ++ : proc_type_table[0][EFFICIENT_CORE_PROC] > 0 ? EFFICIENT_CORE_PROC ++ : proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 ? LP_EFFICIENT_CORE_PROC ++ : HYPER_THREADING_PROC; + numa_id = std::max(0, proc_type_table[0][PROC_NUMA_NODE_ID]); + socket_id = std::max(0, proc_type_table[0][PROC_SOCKET_ID]); + } +diff --git a/src/inference/src/dev/threading/cpu_streams_executor.cpp b/src/inference/src/dev/threading/cpu_streams_executor.cpp +--- a/src/inference/src/dev/threading/cpu_streams_executor.cpp ++++ b/src/inference/src/dev/threading/cpu_streams_executor.cpp +@@ -152,13 +152,8 @@ + .set_max_threads_per_core(max_threads_per_core)}); + } else if (stream_type == STREAM_WITH_CORE_TYPE) { + const auto core_types = custom::info::core_types(); +- auto real_core_type = (core_type == MAIN_CORE_PROC || core_type == HYPER_THREADING_PROC) +- ? core_types.back() +- : core_types.front(); +- // core_types=[LPECore, Ecore, Pcore] +- if (core_type == EFFICIENT_CORE_PROC && core_types.size() >= MIN_CORE_TYPES_FOR_PTL) { +- real_core_type = *(core_types.end() - MIN_CORE_TYPES_FOR_PTL + 1); +- } ++ const auto proc_types = get_org_proc_type_table(); ++ const auto real_core_type = get_tbb_core_type(core_type, core_types, proc_types); + _taskArena.reset(new custom::task_arena{custom::task_arena::constraints{} + .set_core_type(real_core_type) + .set_max_concurrency(concurrency) +diff --git a/src/inference/src/dev/threading/cpu_streams_executor_internal.cpp b/src/inference/src/dev/threading/cpu_streams_executor_internal.cpp +--- a/src/inference/src/dev/threading/cpu_streams_executor_internal.cpp ++++ b/src/inference/src/dev/threading/cpu_streams_executor_internal.cpp +@@ -81,6 +81,22 @@ + } + } + ++int get_tbb_core_type(int proc_type, ++ const std::vector& core_types, ++ const std::vector>& proc_type_table) { ++ auto real_core_type = ++ (proc_type == MAIN_CORE_PROC || proc_type == HYPER_THREADING_PROC) ? core_types.back() : core_types.front(); ++ if (proc_type == EFFICIENT_CORE_PROC && core_types.size() >= 3) { ++ real_core_type = *(core_types.end() - 2); ++ } else if (proc_type == EFFICIENT_CORE_PROC && core_types.size() == 2 && !proc_type_table.empty() && ++ proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && ++ proc_type_table[0][MAIN_CORE_PROC] == 0 && proc_type_table[0][HYPER_THREADING_PROC] == 0) { ++ // Without P cores the ordered pair is [LP, E], not [E, P]. ++ real_core_type = core_types.back(); ++ } ++ return real_core_type; ++} ++ + void reserve_cpu_by_streams_info(const std::vector> _streams_info_table, + const int _numa_nodes, + std::vector>& _cpu_mapping_table, +diff --git a/src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp b/src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp +--- a/src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp ++++ b/src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp +@@ -45,6 +45,12 @@ + int& socket_id, + int& max_threads_per_core); + ++// Map OpenVINO's processor kind to the ordered, nonempty type list returned ++// by oneTBB. IDs are runtime values, not necessarily contiguous integers. ++int get_tbb_core_type(int proc_type, ++ const std::vector& core_types, ++ const std::vector>& proc_type_table); ++ + /** + * @brief Reserve cpu resource by streams info + * @param[in] _streams_info_table streams info table +@@ -74,4 +80,4 @@ + std::vector>& _proc_type_table); + + } // namespace threading +-} // namespace ov +\ No newline at end of file ++} // namespace ov +diff --git a/src/inference/tests/unit/executor_config_test.cpp b/src/inference/tests/unit/executor_config_test.cpp +--- a/src/inference/tests/unit/executor_config_test.cpp ++++ b/src/inference/tests/unit/executor_config_test.cpp +@@ -4,7 +4,10 @@ + + #include + ++#include ++ + #include "common_test_utils/test_common.hpp" ++#include "openvino/runtime/threading/cpu_streams_executor_internal.hpp" + #include "openvino/runtime/threading/cpu_streams_info.hpp" + #include "openvino/runtime/threading/istreams_executor.hpp" + #include "os/cpu_map_info.hpp" +@@ -17,6 +20,517 @@ + + #if defined(__linux__) || defined(_WIN32) + ++class LPExecutorConfigTest : public ov::test::TestsCommon { ++protected: ++ using Table = std::vector>; ++ using CoreType = ov::hint::SchedulingCoreType; ++ CPU& cpu = cpu_info(); ++ const Table saved_proc = cpu._proc_type_table; ++ const Table saved_org_proc = cpu._org_proc_type_table; ++ const Table saved_mapping = cpu._cpu_mapping_table; ++ const int saved_numa_nodes = cpu._numa_nodes; ++ const int saved_sockets = cpu._sockets; ++ ++ void TearDown() override { ++ cpu._proc_type_table = saved_proc; ++ cpu._org_proc_type_table = saved_org_proc; ++ cpu._cpu_mapping_table = saved_mapping; ++ cpu._numa_nodes = saved_numa_nodes; ++ cpu._sockets = saved_sockets; ++ } ++ ++ void set_topology(int main, int efficient, int lp, int hyper = 0) { ++ cpu._proc_type_table = {{main + efficient + lp + hyper, main, efficient, lp, hyper, 0, 0}}; ++ cpu._org_proc_type_table = cpu._proc_type_table; ++ cpu._cpu_mapping_table.clear(); ++ cpu._numa_nodes = cpu._sockets = 1; ++ for (int type = MAIN_CORE_PROC; type <= HYPER_THREADING_PROC; ++type) { ++ for (int n = 0; n < cpu._proc_type_table[0][type]; ++n) { ++ const int core = static_cast(cpu._cpu_mapping_table.size()); ++ const int physical_core = type == HYPER_THREADING_PROC ? n : core; ++ cpu._cpu_mapping_table.push_back({core + 4, 0, 0, physical_core, type, physical_core, NOT_USED}); ++ } ++ } ++ } ++ ++ void check_config(const IStreamsExecutor::Config& config, ++ const Table& expected_ids, ++ bool reservation = true, ++ bool pinning = true) { ++ EXPECT_EQ(reservation, config.get_cpu_reservation()); ++ EXPECT_EQ(pinning, config.get_cpu_pinning()); ++ const auto table = config.get_streams_info_table(); ++ ASSERT_FALSE(table.empty()); ++ std::vector typed_threads(HYPER_THREADING_PROC + 1, 0); ++ int streams = 0; ++ int threads = 0; ++ bool all_proc = false; ++ for (size_t i = 0; i < table.size(); ++i) { ++ const auto& row = table[i]; ++ ASSERT_EQ(CPU_STREAMS_TABLE_SIZE, row.size()); ++ ASSERT_GE(row[PROC_TYPE], ALL_PROC); ++ ASSERT_LE(row[PROC_TYPE], HYPER_THREADING_PROC); ++ EXPECT_GT(row[THREADS_PER_STREAM], 0); ++ EXPECT_GE(row[NUMBER_OF_STREAMS], 0); ++ if (row[NUMBER_OF_STREAMS] > 0) { ++ streams += row[NUMBER_OF_STREAMS]; ++ threads += row[NUMBER_OF_STREAMS] * row[THREADS_PER_STREAM]; ++ all_proc = row[PROC_TYPE] == ALL_PROC; ++ } else { ++ EXPECT_TRUE(all_proc); ++ } ++ if (row[PROC_TYPE] == ALL_PROC) { ++ ASSERT_LT(i + 1, table.size()); ++ EXPECT_EQ(0, table[i + 1][NUMBER_OF_STREAMS]); ++ } else { ++ typed_threads[row[PROC_TYPE]] += std::max(1, row[NUMBER_OF_STREAMS]) * row[THREADS_PER_STREAM]; ++ } ++ } ++ std::vector expected_typed_threads(HYPER_THREADING_PROC + 1, 0); ++ std::vector selected_ids; ++ for (const auto& ids : expected_ids) { ++ ASSERT_FALSE(ids.empty()); ++ for (int id : ids) { ++ ASSERT_GE(id, 4); ++ ASSERT_LT(static_cast(id - 4), cpu._cpu_mapping_table.size()); ++ ++expected_typed_threads[cpu._cpu_mapping_table[id - 4][CPU_MAP_CORE_TYPE]]; ++ selected_ids.push_back(id); ++ } ++ } ++ EXPECT_EQ(expected_ids.size(), static_cast(streams)); ++ EXPECT_EQ(streams, config.get_streams()); ++ EXPECT_EQ(selected_ids.size(), static_cast(threads)); ++ EXPECT_EQ(threads, config.get_threads()); ++ EXPECT_EQ(table[0][THREADS_PER_STREAM], config.get_threads_per_stream()); ++ EXPECT_EQ(expected_typed_threads, typed_threads); ++ EXPECT_EQ(pinning || reservation ? expected_ids : Table{}, config.get_stream_processor_ids()); ++ auto remaining = cpu._org_proc_type_table; ++ if (reservation) { ++ remaining[0][ALL_PROC] -= static_cast(selected_ids.size()); ++ for (int type = MAIN_CORE_PROC; type <= HYPER_THREADING_PROC; ++type) ++ remaining[0][type] -= expected_typed_threads[type]; ++ if (remaining[0][ALL_PROC] == 0) ++ remaining[0][PROC_SOCKET_ID] = -1; ++ } ++ EXPECT_EQ(remaining, cpu._proc_type_table); ++ for (const auto& row : cpu._cpu_mapping_table) { ++ const bool selected = ++ std::find(selected_ids.begin(), selected_ids.end(), row[CPU_MAP_PROCESSOR_ID]) != selected_ids.end(); ++ EXPECT_EQ(reservation && selected ? CPU_USED : NOT_USED, row[CPU_MAP_USED_FLAG]); ++ } ++ } ++}; ++ ++TEST(TbbCoreTypeMappingTest, RegularEfficiencyTypeWithoutPerformanceCores) { ++ const std::vector> topology{{3, 0, 2, 1, 0, 0, 0}}; ++ EXPECT_EQ(17, get_tbb_core_type(EFFICIENT_CORE_PROC, {5, 17}, topology)); ++ EXPECT_EQ(5, get_tbb_core_type(LP_EFFICIENT_CORE_PROC, {5, 17}, topology)); ++} ++ ++TEST(TbbCoreTypeMappingTest, NoLPCoresKeepLegacyMappingWithoutPerformanceCores) { ++ // OpenVINO can have a narrower cached topology than TBB. No LP cores in ++ // that snapshot must leave the legacy two-type mapping unchanged. ++ EXPECT_EQ(5, get_tbb_core_type(EFFICIENT_CORE_PROC, {5, 17}, {{2, 0, 2, 0, 0, 0, 0}})); ++} ++ ++TEST(TbbCoreTypeMappingTest, PreservesExistingTwoTypeMapping) { ++ const std::vector> topology{{4, 2, 2, 0, 0, 0, 0}}; ++ EXPECT_EQ(5, get_tbb_core_type(EFFICIENT_CORE_PROC, {5, 17}, topology)); ++ EXPECT_EQ(5, get_tbb_core_type(LP_EFFICIENT_CORE_PROC, {5, 17}, topology)); ++ EXPECT_EQ(17, get_tbb_core_type(MAIN_CORE_PROC, {5, 17}, topology)); ++ EXPECT_EQ(17, get_tbb_core_type(HYPER_THREADING_PROC, {5, 17}, topology)); ++} ++ ++TEST(TbbCoreTypeMappingTest, HyperThreadsPreventEfficiencyPairMapping) { ++ EXPECT_EQ(5, get_tbb_core_type(EFFICIENT_CORE_PROC, {5, 17}, {{4, 0, 2, 1, 1, 0, 0}})); ++} ++ ++TEST(TbbCoreTypeMappingTest, PreservesExistingThreeTypeMapping) { ++ const std::vector> topology{{6, 2, 2, 2, 0, 0, 0}}; ++ EXPECT_EQ(5, get_tbb_core_type(LP_EFFICIENT_CORE_PROC, {5, 11, 17}, topology)); ++ EXPECT_EQ(11, get_tbb_core_type(EFFICIENT_CORE_PROC, {5, 11, 17}, topology)); ++ EXPECT_EQ(17, get_tbb_core_type(MAIN_CORE_PROC, {5, 11, 17}, topology)); ++} ++ ++TEST(TbbCoreTypeMappingTest, PreservesSingleAutomaticType) { ++ const std::vector> topology{{3, 0, 2, 1, 0, 0, 0}}; ++ EXPECT_EQ(-1, get_tbb_core_type(LP_EFFICIENT_CORE_PROC, {-1}, topology)); ++ EXPECT_EQ(-1, get_tbb_core_type(EFFICIENT_CORE_PROC, {-1}, topology)); ++} ++ ++class LPOnlyExecutorConfigTest ++ : public LPExecutorConfigTest, ++ public testing::WithParamInterface> {}; ++ ++TEST_P(LPOnlyExecutorConfigTest, PreservesLPResourcesAndBinding) { ++ const auto core_type = std::get<0>(GetParam()); ++ const int streams = std::get<1>(GetParam()); ++ const bool reservation = std::get<2>(GetParam()); ++ const bool pinning = std::get<3>(GetParam()); ++ set_topology(0, 0, 4); ++ IStreamsExecutor::Config config{"lp only", streams, streams == 1 ? 4 : 1, core_type, reservation, pinning}; ++ check_config(config, streams == 1 ? Table{{4, 5, 6, 7}} : Table{{4}, {5}, {6}, {7}}, reservation, pinning); ++} ++ ++INSTANTIATE_TEST_SUITE_P(smoke_LPOnlyExecutorConfig, ++ LPOnlyExecutorConfigTest, ++ testing::Combine(testing::Values(ov::hint::SchedulingCoreType::ANY_CORE, ++ ov::hint::SchedulingCoreType::ECORE_ONLY, ++ ov::hint::SchedulingCoreType::PCORE_ONLY), ++ testing::Values(1, 4, 8), ++ testing::Bool(), ++ testing::Bool())); ++ ++TEST_F(LPExecutorConfigTest, PCoreOnlyExcludesLPCores) { ++ set_topology(2, 0, 4, 2); ++ IStreamsExecutor::Config config{"pcore only", 8, 1, CoreType::PCORE_ONLY, true, true}; ++ check_config(config, {{4}, {5}, {10}, {11}}); ++} ++ ++TEST_F(LPExecutorConfigTest, PCoreOnlyIgnoresUnusedSmallHyperThreadPool) { ++ for (bool reservation : {false, true}) { ++ for (bool pinning : {false, true}) { ++ SCOPED_TRACE(reservation); ++ SCOPED_TRACE(pinning); ++ set_topology(6, 1, 2, 1); ++ IStreamsExecutor::Config config{"pcore capacity", 2, 3, CoreType::PCORE_ONLY, reservation, pinning}; ++ check_config(config, {{4, 5, 6}, {7, 8, 9}}, reservation, pinning); ++ EXPECT_EQ(3, config.get_threads_per_stream()); ++ EXPECT_EQ((Table{{2, MAIN_CORE_PROC, 3, 0, 0}}), config.get_streams_info_table()); ++ } ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, DefaultPCoreOnlyKeepsFeasibleThreadCount) { ++ set_topology(6, 1, 2, 1); ++ IStreamsExecutor::Config initial{"default pcore capacity", 2, 0, CoreType::PCORE_ONLY, false, false}; ++ const auto config = IStreamsExecutor::Config::make_default_multi_threaded(initial); ++ check_config(config, {{4, 5, 6}, {7, 8, 9}}, false, false); ++ EXPECT_EQ(3, config.get_threads_per_stream()); ++ EXPECT_EQ((Table{{2, MAIN_CORE_PROC, 3, 0, 0}}), config.get_streams_info_table()); ++} ++ ++TEST_F(LPExecutorConfigTest, UnpinnedLPOnlyStreamKeepsEfficientArenaConstraint) { ++ set_topology(2, 0, 4); ++ IStreamsExecutor::Config config{"unpinned lp", 1, 4, CoreType::ECORE_ONLY, false, false}; ++ EXPECT_EQ((Table{{1, LP_EFFICIENT_CORE_PROC, 4, 0, 0}}), config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ false, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(4, concurrency); ++ EXPECT_EQ(STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(LP_EFFICIENT_CORE_PROC, core_type); ++ EXPECT_FALSE(config.get_cpu_pinning()); ++ EXPECT_FALSE(config.get_cpu_reservation()); ++ EXPECT_TRUE(config.get_stream_processor_ids().empty()); ++} ++ ++TEST_F(LPExecutorConfigTest, UnpinnedMixedEfficientStreamKeepsRestrictedArena) { ++ for (bool reservation : {false, true}) { ++ set_topology(2, 2, 2); ++ IStreamsExecutor::Config config{"unpinned mixed ecore", 1, 4, CoreType::ECORE_ONLY, reservation, false}; ++ check_config(config, {{6, 7}}, reservation, false); ++ EXPECT_EQ((Table{{1, EFFICIENT_CORE_PROC, 2, 0, 0}}), config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ false, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(2, concurrency); ++ EXPECT_EQ(STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(EFFICIENT_CORE_PROC, core_type); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, UnpinnedEfficientStreamUsesLargerLPPool) { ++ for (bool reservation : {false, true}) { ++ set_topology(2, 1, 6); ++ IStreamsExecutor::Config config{"unpinned large lp", 1, 4, CoreType::ECORE_ONLY, reservation, false}; ++ check_config(config, {{7, 8, 9, 10}}, reservation, false); ++ EXPECT_EQ((Table{{1, LP_EFFICIENT_CORE_PROC, 4, 0, 0}}), config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ false, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(4, concurrency); ++ EXPECT_EQ(STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(LP_EFFICIENT_CORE_PROC, core_type); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, UnpinnedRegularEfficiencyStreamWithoutPerformanceCores) { ++ for (bool reservation : {false, true}) { ++ set_topology(0, 2, 1); ++ IStreamsExecutor::Config config{"unpinned regular ecore", 1, 3, CoreType::ECORE_ONLY, reservation, false}; ++ check_config(config, {{4, 5}}, reservation, false); ++ EXPECT_EQ((Table{{1, EFFICIENT_CORE_PROC, 2, 0, 0}}), config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ false, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(2, concurrency); ++ EXPECT_EQ(STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(17, get_tbb_core_type(core_type, {5, 17}, cpu._org_proc_type_table)); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, UnpinnedNoLPEfficiencyStreamKeepsLegacyMapping) { ++ set_topology(0, 2, 0); ++ IStreamsExecutor::Config config{"unpinned no lp", 1, 2, CoreType::ECORE_ONLY, false, false}; ++ check_config(config, {{4, 5}}, false, false); ++ EXPECT_EQ((Table{{1, EFFICIENT_CORE_PROC, 2, 0, 0}}), config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ false, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(2, concurrency); ++ EXPECT_EQ(5, get_tbb_core_type(core_type, {5, 17}, cpu._org_proc_type_table)); ++} ++ ++TEST_F(LPExecutorConfigTest, PinnedMixedEfficientStreamKeepsObserver) { ++ for (bool reservation : {false, true}) { ++ set_topology(2, 2, 2); ++ IStreamsExecutor::Config config{"pinned mixed ecore", 1, 4, CoreType::ECORE_ONLY, reservation, true}; ++ check_config(config, {{6, 7, 8, 9}}, reservation, true); ++ EXPECT_EQ( ++ (Table{{1, ALL_PROC, 4, 0, 0}, {0, EFFICIENT_CORE_PROC, 2, 0, 0}, {0, LP_EFFICIENT_CORE_PROC, 2, 0, 0}}), ++ config.get_streams_info_table()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ true, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(4, concurrency); ++ EXPECT_EQ(STREAM_WITH_OBSERVE, type); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, SingleLPEfficiencyPoolPreservesLocality) { ++ const Table topology{{6, 2, 0, 4, 0, -1, -1}, {2, 2, 0, 0, 0, 0, 0}, {4, 0, 0, 4, 0, 1, 1}}; ++ for (bool pinning : {false, true}) { ++ cpu._proc_type_table = cpu._org_proc_type_table = topology; ++ cpu._numa_nodes = cpu._sockets = 2; ++ cpu._cpu_mapping_table = {{4, 0, 0, 0, MAIN_CORE_PROC, 0, NOT_USED}, ++ {5, 0, 0, 1, MAIN_CORE_PROC, 1, NOT_USED}, ++ {6, 1, 1, 2, LP_EFFICIENT_CORE_PROC, 2, NOT_USED}, ++ {7, 1, 1, 3, LP_EFFICIENT_CORE_PROC, 3, NOT_USED}, ++ {8, 1, 1, 4, LP_EFFICIENT_CORE_PROC, 4, NOT_USED}, ++ {9, 1, 1, 5, LP_EFFICIENT_CORE_PROC, 5, NOT_USED}}; ++ IStreamsExecutor::Config config{"local lp pool", 1, 4, CoreType::ECORE_ONLY, false, pinning}; ++ EXPECT_EQ((Table{{1, LP_EFFICIENT_CORE_PROC, 4, 1, 1}}), config.get_streams_info_table()); ++ EXPECT_EQ((pinning ? Table{{6, 7, 8, 9}} : Table{}), config.get_stream_processor_ids()); ++ EXPECT_EQ(topology, cpu._proc_type_table); ++ EXPECT_EQ(4, config.get_threads()); ++ StreamCreateType type = STREAM_WITHOUT_PARAM; ++ int concurrency = 0, core_type = 0, numa_node = 0, socket = 0, max_threads = 0; ++ get_cur_stream_info(0, ++ pinning, ++ cpu._org_proc_type_table, ++ config.get_streams_info_table(), ++ type, ++ concurrency, ++ core_type, ++ numa_node, ++ socket, ++ max_threads); ++ EXPECT_EQ(pinning ? STREAM_WITH_OBSERVE : STREAM_WITH_CORE_TYPE, type); ++ EXPECT_EQ(LP_EFFICIENT_CORE_PROC, core_type); ++ EXPECT_EQ(1, numa_node); ++ EXPECT_EQ(1, socket); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, PrecomputedMixedEfficientStreamsRemainUnchanged) { ++ set_topology(2, 2, 2); ++ const Table streams{{1, ALL_PROC, 4, 0, 0}, ++ {0, EFFICIENT_CORE_PROC, 2, 0, 0}, ++ {0, LP_EFFICIENT_CORE_PROC, 2, 0, 0}}; ++ IStreamsExecutor::Config config{"precomputed mixed ecore", 1, 4, CoreType::ECORE_ONLY, false, false, true, streams}; ++ EXPECT_EQ(streams, config.get_streams_info_table()); ++ check_config(config, {{6, 7, 8, 9}}, false, false); ++} ++ ++TEST_F(LPExecutorConfigTest, ECoreOnlySkipsUnusedSmallRegularCorePool) { ++ for (bool reservation : {false, true}) { ++ for (bool pinning : {false, true}) { ++ SCOPED_TRACE(reservation); ++ SCOPED_TRACE(pinning); ++ set_topology(0, 1, 6); ++ IStreamsExecutor::Config config{"ecore capacity", 2, 3, CoreType::ECORE_ONLY, reservation, pinning}; ++ check_config(config, {{5, 6, 7}, {8, 9, 10}}, reservation, pinning); ++ EXPECT_EQ(3, config.get_threads_per_stream()); ++ EXPECT_EQ((Table{{2, LP_EFFICIENT_CORE_PROC, 3, 0, 0}}), config.get_streams_info_table()); ++ } ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, SkipsUnusedSmallNumaPoolWithoutReducingThreads) { ++ const Table topology{{9, 7, 0, 2, 0, -1, -1}, {3, 1, 0, 2, 0, 0, 0}, {6, 6, 0, 0, 0, 1, 1}}; ++ cpu._proc_type_table = cpu._org_proc_type_table = topology; ++ cpu._numa_nodes = cpu._sockets = 2; ++ cpu._cpu_mapping_table = {{4, 0, 0, 0, MAIN_CORE_PROC, 0, NOT_USED}, ++ {5, 1, 1, 1, MAIN_CORE_PROC, 1, NOT_USED}, ++ {6, 1, 1, 2, MAIN_CORE_PROC, 2, NOT_USED}, ++ {7, 1, 1, 3, MAIN_CORE_PROC, 3, NOT_USED}, ++ {8, 1, 1, 4, MAIN_CORE_PROC, 4, NOT_USED}, ++ {9, 1, 1, 5, MAIN_CORE_PROC, 5, NOT_USED}, ++ {10, 1, 1, 6, MAIN_CORE_PROC, 6, NOT_USED}, ++ {11, 0, 0, 7, LP_EFFICIENT_CORE_PROC, 7, NOT_USED}, ++ {12, 0, 0, 8, LP_EFFICIENT_CORE_PROC, 8, NOT_USED}}; ++ IStreamsExecutor::Config config{"numa capacity", 2, 3, CoreType::ANY_CORE, false, true}; ++ EXPECT_EQ(2, config.get_streams()); ++ EXPECT_EQ(6, config.get_threads()); ++ EXPECT_EQ(3, config.get_threads_per_stream()); ++ EXPECT_EQ((Table{{2, MAIN_CORE_PROC, 3, 1, 1}}), config.get_streams_info_table()); ++ EXPECT_EQ((Table{{5, 6, 7}, {8, 9, 10}}), config.get_stream_processor_ids()); ++ EXPECT_EQ(topology, cpu._proc_type_table); ++} ++ ++TEST_F(LPExecutorConfigTest, ECoreOnlyIncludesBothEfficientKinds) { ++ for (int streams : {1, 4}) { ++ SCOPED_TRACE(streams); ++ set_topology(2, 2, 2); ++ IStreamsExecutor::Config config{"ecore only", streams, 4 / streams, CoreType::ECORE_ONLY, true, true}; ++ check_config(config, streams == 1 ? Table{{6, 7, 8, 9}} : Table{{6}, {7}, {8}, {9}}); ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, ZeroStreamsUsesLPHelperWithoutBindingOrReservation) { ++ set_topology(0, 0, 4); ++ IStreamsExecutor::Config config{"zero streams", 0, 4, CoreType::ANY_CORE, true, true}; ++ EXPECT_EQ(0, config.get_streams()); ++ EXPECT_EQ((Table{{1, LP_EFFICIENT_CORE_PROC, 1, 0, 0}}), config.get_streams_info_table()); ++ EXPECT_FALSE(config.get_cpu_pinning()); ++ EXPECT_FALSE(config.get_cpu_reservation()); ++ EXPECT_TRUE(config.get_stream_processor_ids().empty()); ++ EXPECT_EQ(cpu._org_proc_type_table, cpu._proc_type_table); ++} ++ ++TEST_F(LPExecutorConfigTest, PrecomputedLPStreamsOverrideCorePreference) { ++ set_topology(0, 0, 4); ++ const Table streams{{2, LP_EFFICIENT_CORE_PROC, 2, 0, 0}}; ++ IStreamsExecutor::Config config{"precomputed", 2, 2, CoreType::PCORE_ONLY, true, true, true, streams}; ++ EXPECT_EQ(streams, config.get_streams_info_table()); ++ check_config(config, {{4, 5}, {6, 7}}); ++} ++ ++TEST_F(LPExecutorConfigTest, RejectsOversubscribedPrecomputedLPStreams) { ++ set_topology(0, 0, 4); ++ const Table streams{{1, LP_EFFICIENT_CORE_PROC, 5, 0, 0}}; ++ EXPECT_THROW(IStreamsExecutor::Config("oversubscribed", 1, 5, CoreType::ANY_CORE, true, true, true, streams), ++ ov::Exception); ++ EXPECT_EQ(cpu._org_proc_type_table, cpu._proc_type_table); ++ for (const auto& row : cpu._cpu_mapping_table) ++ EXPECT_EQ(NOT_USED, row[CPU_MAP_USED_FLAG]); ++} ++ ++TEST_F(LPExecutorConfigTest, FragmentedEfficientKindsUseFeasibleStreams) { ++ for (bool reservation : {false, true}) { ++ for (bool pinning : {false, true}) { ++ SCOPED_TRACE(reservation); ++ SCOPED_TRACE(pinning); ++ set_topology(0, 1, 3); ++ IStreamsExecutor::Config config{"fragmented", 2, 2, CoreType::ECORE_ONLY, reservation, pinning}; ++ check_config(config, {{4}, {5}}, reservation, pinning); ++ EXPECT_EQ(1, config.get_threads_per_stream()); ++ } ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, FragmentedNumaNodesUseFeasibleStreams) { ++ const Table topology{{4, 0, 2, 2, 0, -1, -1}, {2, 0, 1, 1, 0, 0, 0}, {2, 0, 1, 1, 0, 1, 1}}; ++ for (bool reservation : {false, true}) { ++ for (bool pinning : {false, true}) { ++ SCOPED_TRACE(reservation); ++ SCOPED_TRACE(pinning); ++ cpu._proc_type_table = cpu._org_proc_type_table = topology; ++ cpu._numa_nodes = cpu._sockets = 2; ++ cpu._cpu_mapping_table = {{4, 0, 0, 0, EFFICIENT_CORE_PROC, 0, NOT_USED}, ++ {5, 0, 0, 1, LP_EFFICIENT_CORE_PROC, 1, NOT_USED}, ++ {6, 1, 1, 2, EFFICIENT_CORE_PROC, 2, NOT_USED}, ++ {7, 1, 1, 3, LP_EFFICIENT_CORE_PROC, 3, NOT_USED}}; ++ IStreamsExecutor::Config config{"fragmented numa", 2, 2, CoreType::ECORE_ONLY, reservation, pinning}; ++ EXPECT_EQ(2, config.get_streams()); ++ EXPECT_EQ(2, config.get_threads()); ++ EXPECT_EQ(1, config.get_threads_per_stream()); ++ EXPECT_EQ((Table{{1, EFFICIENT_CORE_PROC, 1, 0, 0}, {1, EFFICIENT_CORE_PROC, 1, 1, 1}}), ++ config.get_streams_info_table()); ++ EXPECT_EQ((reservation || pinning ? Table{{4}, {6}} : Table{}), config.get_stream_processor_ids()); ++ const Table remaining{{2, 0, 0, 2, 0, -1, -1}, {1, 0, 0, 1, 0, 0, 0}, {1, 0, 0, 1, 0, 1, 1}}; ++ EXPECT_EQ(reservation ? remaining : topology, cpu._proc_type_table); ++ } ++ } ++} ++ ++TEST_F(LPExecutorConfigTest, DefaultStreamCountIncludesLPCores) { ++ set_topology(2, 0, 6); ++ EXPECT_EQ(4, IStreamsExecutor::Config::get_default_num_streams()); ++ set_topology(0, 0, 4); ++ EXPECT_EQ(4, IStreamsExecutor::Config::get_default_num_streams()); ++ set_topology(1, 1, 2); ++ EXPECT_EQ(4, IStreamsExecutor::Config::get_default_num_streams()); ++} ++ ++TEST_F(LPExecutorConfigTest, NoLPPartialPoolKeepsIndependentStreams) { ++ for (bool reservation : {false, true}) { ++ for (bool pinning : {false, true}) { ++ SCOPED_TRACE(reservation); ++ SCOPED_TRACE(pinning); ++ set_topology(3, 1, 0); ++ IStreamsExecutor::Config config{"no lp partial pool", 2, 2, CoreType::ANY_CORE, reservation, pinning}; ++ check_config(config, {{4, 5}, {7}}, reservation, pinning); ++ } ++ } ++} ++ + struct ExecutorConfigTestCase { + std::vector> _proc_type_table; + std::vector> _cpu_mapping_table; +diff --git a/src/inference/tests/unit/make_default_multi_threaded_test.cpp b/src/inference/tests/unit/make_default_multi_threaded_test.cpp +--- a/src/inference/tests/unit/make_default_multi_threaded_test.cpp ++++ b/src/inference/tests/unit/make_default_multi_threaded_test.cpp +@@ -6,6 +6,7 @@ + + #include + ++#include "openvino/runtime/threading/cpu_streams_info.hpp" + #include "openvino/runtime/threading/istreams_executor.hpp" + #include "os/cpu_map_info.hpp" + +@@ -17,6 +18,73 @@ + + #if defined(__linux__) || defined(_WIN32) + ++struct LPDefaultMultiThreadsTestCase { ++ std::vector topology; ++ int threads; ++ std::vector> streams; ++}; ++ ++class LPDefaultMultiThreadsTest : public ov::test::TestsCommon, ++ public testing::WithParamInterface { ++protected: ++ CPU& cpu = cpu_info(); ++ const std::vector> saved_proc = cpu._proc_type_table; ++ const std::vector> saved_org_proc = cpu._org_proc_type_table; ++ const int saved_numa_nodes = cpu._numa_nodes; ++ const int saved_sockets = cpu._sockets; ++ ++ void TearDown() override { ++ cpu._proc_type_table = saved_proc; ++ cpu._org_proc_type_table = saved_org_proc; ++ cpu._numa_nodes = saved_numa_nodes; ++ cpu._sockets = saved_sockets; ++ } ++}; ++ ++TEST_P(LPDefaultMultiThreadsTest, UsesTwoFeasibleHomogeneousStreams) { ++ const auto& test_data = GetParam(); ++ const auto& topology = test_data.topology; ++ cpu._org_proc_type_table = cpu._proc_type_table = {topology}; ++ cpu._numa_nodes = cpu._sockets = 1; ++ const auto core_type = topology[EFFICIENT_CORE_PROC] > 0 ? ov::hint::SchedulingCoreType::ECORE_ONLY ++ : ov::hint::SchedulingCoreType::ANY_CORE; ++ IStreamsExecutor::Config initial{"lp default", 2, 0, core_type}; ++ const auto config = IStreamsExecutor::Config::make_default_multi_threaded(initial); ++ const auto table = config.get_streams_info_table(); ++ ASSERT_FALSE(table.empty()); ++ EXPECT_EQ(test_data.streams, table); ++ int streams = 0; ++ int threads = 0; ++ for (const auto& row : table) { ++ ASSERT_EQ(CPU_STREAMS_TABLE_SIZE, row.size()); ++ ASSERT_GT(row[PROC_TYPE], ALL_PROC); ++ ASSERT_LE(row[PROC_TYPE], HYPER_THREADING_PROC); ++ ASSERT_GT(row[NUMBER_OF_STREAMS], 0); ++ EXPECT_GT(row[THREADS_PER_STREAM], 0); ++ streams += row[NUMBER_OF_STREAMS]; ++ threads += row[NUMBER_OF_STREAMS] * row[THREADS_PER_STREAM]; ++ } ++ EXPECT_EQ(2, streams); ++ EXPECT_EQ(2, config.get_streams()); ++ EXPECT_EQ(test_data.threads, threads); ++ EXPECT_EQ(test_data.threads, config.get_threads()); ++ EXPECT_EQ(test_data.streams[0][THREADS_PER_STREAM], config.get_threads_per_stream()); ++ EXPECT_TRUE(config.get_stream_processor_ids().empty()); ++ EXPECT_EQ(cpu._org_proc_type_table, cpu._proc_type_table); ++} ++ ++INSTANTIATE_TEST_SUITE_P( ++ smoke_LPDefaultMultiThreads, ++ LPDefaultMultiThreadsTest, ++ testing::Values(LPDefaultMultiThreadsTestCase{{4, 0, 0, 4, 0, 0, 0}, 4, {{2, LP_EFFICIENT_CORE_PROC, 2, 0, 0}}}, ++ // Width four cannot supply two streams; width three can ++ // use the LP pool without consuming the smaller MAIN pool. ++ LPDefaultMultiThreadsTestCase{{8, 2, 0, 6, 0, 0, 0}, 6, {{2, LP_EFFICIENT_CORE_PROC, 3, 0, 0}}}, ++ LPDefaultMultiThreadsTestCase{ ++ {4, 0, 1, 3, 0, 0, 0}, ++ 2, ++ {{1, EFFICIENT_CORE_PROC, 1, 0, 0}, {1, LP_EFFICIENT_CORE_PROC, 1, 0, 0}}})); ++ + struct MakeDefaultMultiThreadsTestCase { + std::vector> _proc_type_table; + int _num_streams; diff --git a/scripts/ci/test_lp_ecore_guard.py b/scripts/ci/test_lp_ecore_guard.py new file mode 100644 index 0000000..1cdb1b5 --- /dev/null +++ b/scripts/ci/test_lp_ecore_guard.py @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: Apache-2.0 +"""Prepared-source guard contracts; runtime behavior is tested in OpenVINO.""" +from pathlib import Path +import subprocess +import sys +import tempfile +import unittest + +ROOT = Path(__file__).resolve().parents[2] +GUARD = ROOT / 'packaging/fedora/44/rpm/openvino/check-lp-ecore-executor-guard.py' +SOURCE = Path('src/inference/src/dev/threading/istreams_executor.cpp') +MARKERS = [ + 'std::vector core_types{MAIN_CORE_PROC, EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC, HYPER_THREADING_PROC};', + 'core_types = {EFFICIENT_CORE_PROC, LP_EFFICIENT_CORE_PROC};', + 'proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 ? LP_EFFICIENT_CORE_PROC', + 'OPENVINO_ASSERT(!_streams_info_table.empty(),', + 'if (mixed_stream) {', + 'if (mixed_stream) {', + 'proc_type_table[0][EFFICIENT_CORE_PROC] + proc_type_table[0][LP_EFFICIENT_CORE_PROC]', + 'proc_type_table[0][EFFICIENT_CORE_PROC] + proc_type_table[0][LP_EFFICIENT_CORE_PROC]', + 'if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams)', + '_streams > 1 || (_thread_preferred_core_type == ov::hint::SchedulingCoreType::ECORE_ONLY && !_cpu_pinning);', + '!homogeneous_streams && _streams == 1 &&', + 'while (_threads_per_stream > 1)', + 'if (proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 && homogeneous_streams &&\n' + ' _threads_per_stream > proc_type_table[i][j]) {\n' + ' continue;\n' + ' }', + 'streams_num += proc_type_table[i][type] / _threads_per_stream;', + 'const auto num_cores = proc_type_table[0][MAIN_CORE_PROC] + proc_type_table[0][EFFICIENT_CORE_PROC] +\n' + ' proc_type_table[0][LP_EFFICIENT_CORE_PROC];', + '_streams_info_table[0][PROC_TYPE] = LP_EFFICIENT_CORE_PROC;', + '_streams_info_table[0][STREAM_NUMA_NODE_ID] = _streams_info_table[1][STREAM_NUMA_NODE_ID];', + '_streams_info_table[0][STREAM_SOCKET_ID] = _streams_info_table[1][STREAM_SOCKET_ID];', +] +EXTRA_MARKERS = { + Path('src/inference/src/dev/threading/cpu_streams_executor.cpp'): [ + 'const auto proc_types = get_org_proc_type_table();', + 'get_tbb_core_type(core_type, core_types, proc_types);', + ], + Path('src/inference/src/dev/threading/cpu_streams_executor_internal.cpp'): [ + 'int get_tbb_core_type(int proc_type,', + 'core_types.size() == 2 && !proc_type_table.empty() &&', + 'proc_type_table[0][EFFICIENT_CORE_PROC] > 0 && proc_type_table[0][LP_EFFICIENT_CORE_PROC] > 0 &&', + 'proc_type_table[0][MAIN_CORE_PROC] == 0 && proc_type_table[0][HYPER_THREADING_PROC] == 0', + ], + Path('src/inference/dev_api/openvino/runtime/threading/cpu_streams_executor_internal.hpp'): [ + 'int get_tbb_core_type(int proc_type,', + 'const std::vector>& proc_type_table);', + ], +} + + +class LPExecutorGuardTest(unittest.TestCase): + def run_guard(self, markers, extra_markers=None): + with tempfile.TemporaryDirectory() as directory: + for relative, lines in {SOURCE: markers, **(EXTRA_MARKERS if extra_markers is None else extra_markers)}.items(): + source = Path(directory) / relative + source.parent.mkdir(parents=True, exist_ok=True) + source.write_text('\n'.join(lines), encoding='utf-8') + return subprocess.run( + [sys.executable, str(GUARD), directory], + capture_output=True, text=True, timeout=10, + ) + + def test_accepts_complete_prepared_source_markers(self): + result = self.run_guard(MARKERS) + self.assertEqual(result.returncode, 0, result.stderr) + + def test_rejects_each_missing_requirement(self): + for index, marker in enumerate(MARKERS): + with self.subTest(marker=marker): + result = self.run_guard(MARKERS[:index] + MARKERS[index + 1:]) + self.assertNotEqual(result.returncode, 0, marker) + self.assertIn('check-lp-ecore-executor-guard:', result.stderr) + + def test_rejects_duplicate_requirement(self): + result = self.run_guard(MARKERS + [MARKERS[0]]) + self.assertNotEqual(result.returncode, 0) + + def test_rejects_legacy_core_list(self): + result = self.run_guard(MARKERS + [ + 'core_types = {MAIN_CORE_PROC, EFFICIENT_CORE_PROC, HYPER_THREADING_PROC};', + ]) + self.assertNotEqual(result.returncode, 0) + + def test_rejects_unused_small_pool_clamp(self): + result = self.run_guard(MARKERS + [ + '_threads_per_stream = std::min(_threads_per_stream, proc_type_table[i][type]);', + ]) + self.assertNotEqual(result.returncode, 0) + self.assertIn('unused small pools', result.stderr) + + def test_rejects_each_missing_mapping_requirement(self): + for path, markers in EXTRA_MARKERS.items(): + for index, marker in enumerate(markers): + with self.subTest(path=path, marker=marker): + sources = dict(EXTRA_MARKERS) + sources[path] = markers[:index] + markers[index + 1:] + result = self.run_guard(MARKERS, sources) + self.assertNotEqual(result.returncode, 0) + self.assertIn('check-lp-ecore-executor-guard:', result.stderr) + + def test_rejects_missing_mapping_source(self): + sources = dict(EXTRA_MARKERS) + del sources[next(iter(sources))] + result = self.run_guard(MARKERS, sources) + self.assertNotEqual(result.returncode, 0) + self.assertIn('check-lp-ecore-executor-guard:', result.stderr) + + +if __name__ == '__main__': + unittest.main() diff --git a/xtask/tests/fedora_openvino_package_contract.rs b/xtask/tests/fedora_openvino_package_contract.rs index 35fb275..939e37d 100644 --- a/xtask/tests/fedora_openvino_package_contract.rs +++ b/xtask/tests/fedora_openvino_package_contract.rs @@ -735,7 +735,7 @@ fn production_spec_declares_the_source_built_openvino_npu_boundary() { for required in [ "Name: openvino", "Version: 2026.2.1", - "Release: 1.intelnpu.fc44", + "Release: 2.intelnpu.fc44", "ExclusiveArch: x86_64", "openvino.tar", "npu-compiler.tar", From a7cc9e926eb51b68492db2784ad2d94586e2b6ae Mon Sep 17 00:00:00 2001 From: Wisbendji Fimerlus Date: Mon, 26 Oct 2026 19:52:13 -0400 Subject: [PATCH 2/2] packaging: bind candidate tools to LP-fixed providers Regenerate the candidate manifest from the verified OpenVINO 2026.2.1-2 provider RPMs, retaining the three unchanged driver, firmware and loader providers. Align exact package dependencies and profile-generation policy with that provider set. Bump the candidate tools and metapackage release to 0.2.0-4 because their dependencies and embedded manifest change. Keep the CLI version, candidate stack release, production profiles and qualification status unchanged. Signed-off-by: Wisbendji Fimerlus --- packaging/fedora/44/installed-manifest.toml | 84 +++++++++---------- .../44/rpm/intel-npu-stack/check-packages.py | 12 +-- .../intel-npu-stack-tools.spec | 17 ++-- .../intel-npu-stack/test-package-contract.py | 12 +-- .../fedora/44/test-profile-generation.py | 10 +-- xtask/src/fedora_profile.rs | 8 +- .../native_opensvino_version_contract.rs | 2 +- 7 files changed, 75 insertions(+), 70 deletions(-) diff --git a/packaging/fedora/44/installed-manifest.toml b/packaging/fedora/44/installed-manifest.toml index 9f04f28..6950353 100644 --- a/packaging/fedora/44/installed-manifest.toml +++ b/packaging/fedora/44/installed-manifest.toml @@ -8,17 +8,17 @@ source_lock_sha256 = "3701e9913758f724998dc9b201a5a3d694257d5c3db65464609bbe70a3 [[providers]] name = "intel-npu-compiler" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "intel-npu-compiler-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "b23747b356f5c5bf9d1a91a2d821dc51d5cb425d2907cd2ef444666dab19b0a6" +rpm_filename = "intel-npu-compiler-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "42acda9c94ffeb9f453a391a1d0a84a9f32f1aba2708d4f8d70bd4a002bdbae1" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause) AND (Apache-2.0 WITH LLVM-exception) AND NCSA AND BSD-2-Clause AND ISC AND Spencer-94 AND Unicode-DFS-2015 AND LicenseRef-LLVM-MD5" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_intel_npu_compiler.so" -sha256 = "75c20d701d54ab05d8b2d6a0d6f0095c8b560664671fc7b89e18dcc479de1ced" +sha256 = "d43d99034d4c377794e5581aab1b111ff1410dd8faa21226b8c6d7ba9500b545" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_intel_npu_compiler_loader.so" -sha256 = "95103389cadb22f06987f549449de1d88c930585c782a690584b45b9e045f9c0" +sha256 = "6ff2df0f103e2f33df3ea1de287ca20d37e3ab4bbed542fa9e47bb32b2cee775" [[providers]] name = "intel-npu-driver" @@ -44,69 +44,69 @@ sha256 = "cdfe2ebd66aaec21d896134c93d82d60de2d8eede75a2c62898aeb9006e5a26f" [[providers]] name = "libopenvino-ir-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-ir-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "2ee3a30bf624827c7f977d57037edd4b9c54a3ab8ab4189b96a8f2298a74ca8c" +rpm_filename = "libopenvino-ir-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "7c266da799a146982158cfc5cb778e2a405570b8f96c4a324aa378c004770c67" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_ir_frontend.so.2026.2.1" -sha256 = "7f1fc805bafbd90ba1a73e973b09b3b69da9f33deebd9b6ccb833fa4d3f5431d" +sha256 = "328e7e47c945360bb2afff390c57e315581ab67307fa6f10e7eabef6ef1da497" [[providers]] name = "libopenvino-onnx-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-onnx-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "1e195d7e261ab219026e1fcc7db28b853234b8ab7240f997ad0a203521507cf7" +rpm_filename = "libopenvino-onnx-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "013bf6bd75f8a73dc52158452be4c7c345d06ee8b67be4b70b5a82f5410b6df2" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_onnx_frontend.so.2026.2.1" -sha256 = "d32c762615683baa1e7ab23314bacd7482f14e094c09b5f3dcd4974125ed2ebf" +sha256 = "9f6750418a4561de3d16a0793aecad28518124d7d054c02fdccd1db3844d7c21" [[providers]] name = "libopenvino-paddle-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-paddle-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "f74b2b946a1a522e89684d9d55e909d198d27b70574af1cd11f06282772f06e8" +rpm_filename = "libopenvino-paddle-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "ca9d8c2c1a990391ff180fceec943d883ac7c39736c266ddd49395c7588357d6" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_paddle_frontend.so.2026.2.1" -sha256 = "383c183f7b02fa54f0cf408cb32af53e11883bd71a9dde634561985a8a887e8e" +sha256 = "30708d122c220aad3899b11dc6f8c01da370ee195e3e12e7225effbf55796cfe" [[providers]] name = "libopenvino-pytorch-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-pytorch-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "e03c0572ecbde4d7b2728f65c43781908475f7f17d7ed3abbb5d26d5fadd16da" +rpm_filename = "libopenvino-pytorch-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "63497c0db3269099e34594ce2cd83400f82a078a825c203a25c53b28d0156116" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_pytorch_frontend.so.2026.2.1" -sha256 = "48d7ca02fcbee8e8d6a3e98fe43af79c47e1b571e937159f6dc759abfc44f091" +sha256 = "71454f2effcb98e6b95713a201ed0f32dd793a0b6c53e174b56c87e6f8e01177" [[providers]] name = "libopenvino-tensorflow-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-tensorflow-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "f92f6aa71f27b4826cb8766c4b4bfa6f0eccee5a26dc37991bd76b6fa7c3d80c" +rpm_filename = "libopenvino-tensorflow-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "a8d7ea5fc3df982f61e68b087b1b292b5c7a4411636370ac0ab9b367d3caeef1" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_tensorflow_frontend.so.2026.2.1" -sha256 = "42ee551ce3de0e6cc633ae689d66a5fb30a4a4b7cc84b21f83a10e27931b4b12" +sha256 = "f98ddc0f2b0230bfff9bbc681a16ee074882d6cfd177fd4e71263c5afe6260a4" [[providers]] name = "libopenvino-tensorflow-lite-frontend" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "libopenvino-tensorflow-lite-frontend-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "bb8422862f68a05b47de024eb1665b2e1bc445d3e8ebae72e93d7c5792a72960" +rpm_filename = "libopenvino-tensorflow-lite-frontend-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "108948c9a1fdaf7a114d44386e5f177fbc60d97271913c1728616d3953513696" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino_tensorflow_lite_frontend.so.2026.2.1" -sha256 = "4c5b17ea4c7729137cc4f37419c9fa9cfe54ab101695a0857b162577c6d22096" +sha256 = "12ca49aeb343b6d8c40b53ee6ea073c5e1bda8b869fc009d54cab39915b4c198" [[providers]] name = "oneapi-level-zero" @@ -127,40 +127,40 @@ sha256 = "cb40020b63fba2ce06dd24d86b0379ecb3deb46e1e0aa7bc78ecdae1d529db17" [[providers]] name = "openvino" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "openvino-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "6b21decd0fd9a9b869786f292fc666673c711994dafc54a134edd49a88e983cc" +rpm_filename = "openvino-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "7a931d6a0de76f0fdfbd8d2cbe842366d048a7ba6957701174faaa0da845e0fb" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/libopenvino.so.2026.2.1" -sha256 = "c88fbb03e1eba6ec1f84ab60e1fbf1df343469d10143b035f1e68478ae7f73a6" +sha256 = "4951bfb32b088acc72aca1a3eca55de571349e03ddfd47e5d233eb7697e688f9" [[providers.files]] path = "/usr/lib64/libopenvino_c.so.2026.2.1" -sha256 = "2874084046c324bd8e18d3e2771c62f4075910a123888b5d000958eb36764f18" +sha256 = "bee6060131115df7705d95acfeceef31169c7f073a038b3b0d60afbd4dd5a620" [[providers]] name = "openvino-plugins" -nevr = "0:2026.2.1-1.intelnpu.fc44" +nevr = "0:2026.2.1-2.intelnpu.fc44" arch = "x86_64" -rpm_filename = "openvino-plugins-2026.2.1-1.intelnpu.fc44.x86_64.rpm" -rpm_sha256 = "b65db4a9409ea6ee002ba532371457e4ad3dcd7bf651e552d0da73e826b3c05f" +rpm_filename = "openvino-plugins-2026.2.1-2.intelnpu.fc44.x86_64.rpm" +rpm_sha256 = "8313df55462af8e452245c0cca021e7482e5384d2d0c00e0e99917a14972ee21" license = "Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause)" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/cache.json" sha256 = "0b2ad2a99516a3411ce3fef274e8ae2880b41a6f00c9bac6768cd4a94b87c41c" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_auto_plugin.so" -sha256 = "0772f409d80caef2610c829541af3aaf25380e30da0499a522add1f629b028db" +sha256 = "dc9782da46e6c63e6568fb2dc939d7050bb26d100caca8bc8f8c65b562d22e95" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_hetero_plugin.so" -sha256 = "eea13817f0da4e04c95a35c2580399a93e526038ea3b8a6c39bfa4bef458e66a" +sha256 = "2ad2981519570814da602170395fe092382f2daa38b3e95042caf07b8a1db877" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_intel_cpu_plugin.so" -sha256 = "fa47affa46b208453fb8a1aef22fbbc9a0c84bd7fc98a649a3b351fb61370a37" +sha256 = "3a96453588ef09c472f7d6a273ecfe819fe68f9f579db12144870282dbb1f7dd" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_intel_gpu_plugin.so" -sha256 = "eb17e2afef4814891eeaf688f254265c5c7c8dbce61142f40fd3e368c8dcf53a" +sha256 = "07013bb06a6faeae9d8f11fc3ba35e33a136a8f8a91f4e4be39ab9120908c7d9" [[providers.files]] path = "/usr/lib64/openvino-2026.2.1/libopenvino_intel_npu_plugin.so" -sha256 = "8c36e7618aaa81480f859a24e67d91b02f3870914d83d2fbd88c710ad1908233" +sha256 = "7254e45867fe993196b058d607bc2be98e45132b688619f818da657477604738" diff --git a/packaging/fedora/44/rpm/intel-npu-stack/check-packages.py b/packaging/fedora/44/rpm/intel-npu-stack/check-packages.py index 3ecdc83..8968fd3 100644 --- a/packaging/fedora/44/rpm/intel-npu-stack/check-packages.py +++ b/packaging/fedora/44/rpm/intel-npu-stack/check-packages.py @@ -37,16 +37,16 @@ def sha(path): and manifest.get('reboot_required') is True, 'manifest candidate/activation policy') required = { 'intel-npu-stack': { - ('intel-npu-stack-tools(x86-64)', '=', '0.2.0-3.intelnpu.fc44'), + ('intel-npu-stack-tools(x86-64)', '=', '0.2.0-4.intelnpu.fc44'), ('intel-npu-driver(x86-64)', '=', '1.38.0-1.intelnpu.fc44'), ('intel-npu-stack-firmware', '=', '1.38.0-1.intelnpu.fc44'), ('oneapi-level-zero(x86-64)', '=', '1.32.0-1.intelnpu.fc44'), - ('openvino(x86-64)', '=', '2026.2.1-1.intelnpu.fc44'), - ('openvino-plugins(x86-64)', '=', '2026.2.1-1.intelnpu.fc44'), - ('intel-npu-compiler(x86-64)', '=', '2026.2.1-1.intelnpu.fc44'), + ('openvino(x86-64)', '=', '2026.2.1-2.intelnpu.fc44'), + ('openvino-plugins(x86-64)', '=', '2026.2.1-2.intelnpu.fc44'), + ('intel-npu-compiler(x86-64)', '=', '2026.2.1-2.intelnpu.fc44'), }, 'intel-npu-stack-tools': { - ('openvino(x86-64)', '=', '2026.2.1-1.intelnpu.fc44'), + ('openvino(x86-64)', '=', '2026.2.1-2.intelnpu.fc44'), ('oneapi-level-zero(x86-64)', '=', '1.32.0-1.intelnpu.fc44'), }, } @@ -69,7 +69,7 @@ def sha(path): require(name in required and name not in packages, 'exact two distinct package identities') packages.add(name) expected_arch = 'noarch' if name == 'intel-npu-stack' else 'x86_64' - require(nevr == '0:0.2.0-3.intelnpu.fc44' and arch == expected_arch and algorithm == '8', 'RPM version/arch/SHA256') + require(nevr == '0:0.2.0-4.intelnpu.fc44' and arch == expected_arch and algorithm == '8', 'RPM version/arch/SHA256') for option in ['--scripts', '--triggers', '--filetriggers']: require(not query(rpm, option).strip(), 'script-free package: ' + name) relations = set() diff --git a/packaging/fedora/44/rpm/intel-npu-stack/intel-npu-stack-tools.spec b/packaging/fedora/44/rpm/intel-npu-stack/intel-npu-stack-tools.spec index 7863904..3c69269 100644 --- a/packaging/fedora/44/rpm/intel-npu-stack/intel-npu-stack-tools.spec +++ b/packaging/fedora/44/rpm/intel-npu-stack/intel-npu-stack-tools.spec @@ -5,7 +5,7 @@ Name: intel-npu-stack-tools Version: 0.2.0 -Release: 3.intelnpu.fc44 +Release: 4.intelnpu.fc44 Summary: Read-only Intel NPU stack status and diagnostic tools License: Apache-2.0 AND Artistic-2.0 AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND Unicode-3.0 AND (Apache-2.0 WITH LLVM-exception) Source0: intel-npu-stack-0.1.0.tar @@ -22,11 +22,11 @@ BuildRequires: gcc-c++ = 16.2.1-2.fc44 BuildRequires: ninja-build = 1.13.2-2.fc44 BuildRequires: python3 = 3.14.7-1.fc44 BuildRequires: oneapi-level-zero-devel = 1.28.6-1.fc44 -BuildRequires: openvino-devel = 2026.2.1-1.intelnpu.fc44 +BuildRequires: openvino-devel = 2026.2.1-2.intelnpu.fc44 BuildRequires: util-linux-core = 2.41.5-1.fc44 Requires: oneapi-level-zero%{?_isa} = 1.32.0-1.intelnpu.fc44 -Requires: openvino%{?_isa} = 2026.2.1-1.intelnpu.fc44 +Requires: openvino%{?_isa} = 2026.2.1-2.intelnpu.fc44 %description Read-only status CLI, isolated native probes, documentation and a manifest @@ -41,9 +41,9 @@ Requires: intel-npu-stack-tools(x86-64) = %{version}-%{release} Requires: intel-npu-driver(x86-64) = 1.38.0-1.intelnpu.fc44 Requires: intel-npu-stack-firmware = 1.38.0-1.intelnpu.fc44 Requires: oneapi-level-zero(x86-64) = 1.32.0-1.intelnpu.fc44 -Requires: openvino(x86-64) = 2026.2.1-1.intelnpu.fc44 -Requires: openvino-plugins(x86-64) = 2026.2.1-1.intelnpu.fc44 -Requires: intel-npu-compiler(x86-64) = 2026.2.1-1.intelnpu.fc44 +Requires: openvino(x86-64) = 2026.2.1-2.intelnpu.fc44 +Requires: openvino-plugins(x86-64) = 2026.2.1-2.intelnpu.fc44 +Requires: intel-npu-compiler(x86-64) = 2026.2.1-2.intelnpu.fc44 %description -n intel-npu-stack Metadata-only package selecting the exact candidate provider versions. @@ -104,6 +104,11 @@ ctest --test-dir %{__cmake_builddir} --output-on-failure --no-tests=error %{_datadir}/intel-npu-stack/installed-manifest.toml %changelog +* Mon Oct 26 2026 Wisbendji Fimerlus - 0.2.0-4.intelnpu.fc44 +- Bind the candidate tools and metapackage to the reproducible OpenVINO + 2026.2.1-2 provider set with the LP-efficiency-core scheduling correction. +- Refresh the embedded candidate manifest; keep the CLI workspace version + and unqualified candidate status unchanged. * Tue Oct 06 2026 Wisbendji Fimerlus - 0.2.0-3.intelnpu.fc44 - Move the tools and metapackage to 0.2.0-3 on the 2026.2.1-1 provider set: the openvino 2026.2.1-1 rebuild whose compiler subpackage pins the 1.38.0 diff --git a/packaging/fedora/44/rpm/intel-npu-stack/test-package-contract.py b/packaging/fedora/44/rpm/intel-npu-stack/test-package-contract.py index a6de2bb..8a935fb 100644 --- a/packaging/fedora/44/rpm/intel-npu-stack/test-package-contract.py +++ b/packaging/fedora/44/rpm/intel-npu-stack/test-package-contract.py @@ -37,23 +37,23 @@ def case(mutation): spec.write_text('''%global debug_package %{nil} Name: intel-npu-stack-tools Version: 0.2.0 -Release: 3.intelnpu.fc44 +Release: 4.intelnpu.fc44 Summary: Contract fixture License: Apache-2.0 -Requires: openvino(x86-64) = 2026.2.1-1.intelnpu.fc44 +Requires: openvino(x86-64) = 2026.2.1-2.intelnpu.fc44 Requires: oneapi-level-zero(x86-64) = 1.32.0-1.intelnpu.fc44 %description Tool fixture. %package -n intel-npu-stack Summary: Metadata fixture BuildArch: noarch -Requires: intel-npu-stack-tools(x86-64) = 0.2.0-3.intelnpu.fc44 +Requires: intel-npu-stack-tools(x86-64) = 0.2.0-4.intelnpu.fc44 Requires: intel-npu-driver(x86-64) = ''' + requirement + '''-1.intelnpu.fc44 Requires: intel-npu-stack-firmware = 1.38.0-1.intelnpu.fc44 Requires: oneapi-level-zero(x86-64) = 1.32.0-1.intelnpu.fc44 -Requires: openvino(x86-64) = 2026.2.1-1.intelnpu.fc44 -Requires: openvino-plugins(x86-64) = 2026.2.1-1.intelnpu.fc44 -Requires: intel-npu-compiler(x86-64) = 2026.2.1-1.intelnpu.fc44 +Requires: openvino(x86-64) = 2026.2.1-2.intelnpu.fc44 +Requires: openvino-plugins(x86-64) = 2026.2.1-2.intelnpu.fc44 +Requires: intel-npu-compiler(x86-64) = 2026.2.1-2.intelnpu.fc44 %description -n intel-npu-stack Metadata fixture. %install diff --git a/packaging/fedora/44/test-profile-generation.py b/packaging/fedora/44/test-profile-generation.py index 79e4c7d..23ab060 100644 --- a/packaging/fedora/44/test-profile-generation.py +++ b/packaging/fedora/44/test-profile-generation.py @@ -8,20 +8,20 @@ manifest=tomllib.loads(Path('packaging/fedora/44/installed-manifest.toml').read_text()) packages={p['name']:p for p in manifest['providers']} packages['intel-npu-driver']['license'] = 'MIT AND Apache-2.0 AND (GPL-2.0-only WITH Linux-syscall-note)' -packages['intel-npu-stack-tools']={'nevr':'0:0.2.0-3.intelnpu.fc44','arch':'x86_64','license':'Apache-2.0 AND Artistic-2.0 AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND Unicode-3.0 AND (Apache-2.0 WITH LLVM-exception)', +packages['intel-npu-stack-tools']={'nevr':'0:0.2.0-4.intelnpu.fc44','arch':'x86_64','license':'Apache-2.0 AND Artistic-2.0 AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND Unicode-3.0 AND (Apache-2.0 WITH LLVM-exception)', 'files':[{'path':'/usr/bin/intel-npu-stack'}, {'path':'/usr/libexec/intel-npu-stack/intel-npu-level-zero-probe'}, {'path':'/usr/libexec/intel-npu-stack/intel-npu-openvino-probe'}, {'path':'/usr/share/intel-npu-stack/installed-manifest.toml'}]} -packages['intel-npu-stack']={'nevr':'0:0.2.0-3.intelnpu.fc44','arch':'noarch','license':'Apache-2.0','files':[]} +packages['intel-npu-stack']={'nevr':'0:0.2.0-4.intelnpu.fc44','arch':'noarch','license':'Apache-2.0','files':[]} packages['intel-npu-compiler']['license'] = 'Apache-2.0 AND MIT AND BSL-1.0 AND HPND AND BSD-3-Clause AND (GPL-2.0-only OR BSD-3-Clause) AND (Apache-2.0 WITH LLVM-exception) AND NCSA AND BSD-2-Clause AND ISC AND Spencer-94 AND Unicode-DFS-2015 AND LicenseRef-LLVM-MD5' license_owners={'intel-npu-stack-tools','intel-npu-driver','intel-npu-stack-firmware','oneapi-level-zero','openvino','intel-npu-compiler'} with tempfile.TemporaryDirectory(prefix='profile-rpm-contract-') as temporary: root=Path(temporary) for name in ['BUILD','SOURCES','SPECS','RPMS','SRPMS','tmp']:(root/name).mkdir() - spec=['%global debug_package %{nil}', 'Name: intel-npu-stack-tools', 'Version: 0.2.0', 'Release: 3.intelnpu.fc44', + spec=['%global debug_package %{nil}', 'Name: intel-npu-stack-tools', 'Version: 0.2.0', 'Release: 4.intelnpu.fc44', 'Summary: Profile generation fixture','License: '+packages['intel-npu-stack-tools']['license'], 'Requires: oneapi-level-zero(x86-64) = 1.32.0-1.intelnpu.fc44', - 'Requires: openvino(x86-64) = 2026.2.1-1.intelnpu.fc44','%description','Fixture.'] + 'Requires: openvino(x86-64) = 2026.2.1-2.intelnpu.fc44','%description','Fixture.'] for name,p in sorted(packages.items()): if name=='intel-npu-stack-tools':continue version,release=p['nevr'].split(':')[1].split('-',1) @@ -29,7 +29,7 @@ 'Release: '+release,'License: '+p['license']] if p['arch']=='noarch':spec.append('BuildArch: noarch') if name.startswith('libopenvino-') or name in ['intel-npu-compiler','openvino-plugins']: - spec.append('Requires: openvino(x86-64) = 2026.2.1-1.intelnpu.fc44') + spec.append('Requires: openvino(x86-64) = 2026.2.1-2.intelnpu.fc44') if name=='intel-npu-stack': for dependency in ['intel-npu-stack-tools','intel-npu-driver','intel-npu-stack-firmware', 'oneapi-level-zero','openvino','openvino-plugins','intel-npu-compiler']: diff --git a/xtask/src/fedora_profile.rs b/xtask/src/fedora_profile.rs index 0fdaf52..f928d49 100644 --- a/xtask/src/fedora_profile.rs +++ b/xtask/src/fedora_profile.rs @@ -128,7 +128,7 @@ fn expected_packages() -> BTreeMap { ] { packages.insert( name.to_owned(), - ("0:2026.2.1-1.intelnpu.fc44".to_owned(), "x86_64".to_owned()), + ("0:2026.2.1-2.intelnpu.fc44".to_owned(), "x86_64".to_owned()), ); } for (name, nevr, arch) in [ @@ -139,8 +139,8 @@ fn expected_packages() -> BTreeMap { "noarch", ), ("oneapi-level-zero", "0:1.32.0-1.intelnpu.fc44", "x86_64"), - ("intel-npu-stack", "0:0.2.0-3.intelnpu.fc44", "noarch"), - ("intel-npu-stack-tools", "0:0.2.0-3.intelnpu.fc44", "x86_64"), + ("intel-npu-stack", "0:0.2.0-4.intelnpu.fc44", "noarch"), + ("intel-npu-stack-tools", "0:0.2.0-4.intelnpu.fc44", "x86_64"), ] { packages.insert(name.to_owned(), (nevr.to_owned(), arch.to_owned())); } @@ -374,7 +374,7 @@ fn license_provider<'a>( let relationship = ( "openvino(x86-64)".to_owned(), "=".to_owned(), - "2026.2.1-1.intelnpu.fc44".to_owned(), + "2026.2.1-2.intelnpu.fc44".to_owned(), ); require( shared_family diff --git a/xtask/tests/native_opensvino_version_contract.rs b/xtask/tests/native_opensvino_version_contract.rs index 4351009..6904684 100644 --- a/xtask/tests/native_opensvino_version_contract.rs +++ b/xtask/tests/native_opensvino_version_contract.rs @@ -2,7 +2,7 @@ //! Regression contract for the native SDK probe's OpenVINO version acceptance. //! -//! The tools package builds against the 2026.2.1-1 providers while local SDK +//! The tools package builds against the 2026.2.1 providers while local SDK //! checks against an installed 0.1.1 stack resolve OpenVINO 2026.2.0, so the //! native configure step must accept exactly those two versions and refuse //! any other one instead of silently taking whatever the SDK ships.