BUG: KMeans hangs when the mask selects only the final tuple
メンテナーはふだん 4 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 30/100
- issue の種類
- バグ
- 明瞭さ
- 説明が足りない
- 活発さ
- 活発
- 技術スタック
- cpp
- 領域
- backend, data, testing-qa
調査の方向性
Start with src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/ComputeKMeansDirect.cpp and ComputeKMeansScanline.cpp, then read ComputeKMeansTest.cpp and the ComputeKMeansFilter.md documentation. Reproduce the described boundary case only with a bounded harness, and resolve the A, B, or C policy before implementation. Done requires deterministic coverage across Direct, Scanline, resident, and OOC paths, including cancellation and mask cases.
索引モデルが issue の本文から書いたものです。
説明
Brief description and expected behavior
Compute K Means can run indefinitely during initial centroid selection when the mask selects only the final input tuple. The problem exists in both the in-memory Direct and out-of-core Scanline implementations. Direct also has no cancellation check inside this selection loop.
The sampling formula excludes the final tuple from the intended candidate range. The preceding mask validation accepts the input because at least one tuple is selected. The algorithm then keeps drawing candidates that the mask rejects.
For a valid two-tuple input with mask {false, true} and one requested cluster, the filter should complete with the selected tuple as its cluster center. At minimum, it must return a contextual error and respond to cancellation instead of running indefinitely. The intended sampling behavior and compatibility policy need a decision before implementation.
Version, platform, and evidence
- Source reviewed locally: simplnx
07aaee6704ea8c0a35c1d3a8fbd6fb875bdfb36f. - Rechecked against upstream
developon 2026-09-29:92fc6b073020c11db2c90abd0efb0186f00de111. Both implementations still contain the formula. - Area: SimplnxCore filter algorithm; affects resident and disk-backed execution.
- Review host: Windows. The selection logic is shared across platforms; no platform-specific cause is required.
- Evidence is source analysis, not a runtime reproduction. No current test binary was run to induce the hang, and no runtime log or application build result is claimed.
- Existing issues were searched for
KMeansand"K Means"; no matching defect report was found.
Root cause and source references
Both implementations use the equivalent of:
const usize rangeMax = tupleCount - 1;
std::uniform_real_distribution<float64> distribution(0.0, 1.0);
while(selected < clusters)
{
const usize index = std::floor(distribution(generator) * rangeMax);
if(mask[index])
{
centroidIndices[selected++] = index;
}
}
The real distribution's intended range is [0,1). For two tuples, rangeMax is exactly one, so the sampled index is zero. If only index one is selected, the loop never increments selected.
- Direct sampling and lack of an initialization cancellation check.
- Direct whole-mask validation.
- Scanline validation and sampling. This loop checks cancellation but cannot complete normally for the stated input.
The existing all-false-mask rejection does not cover this case: the mask contains a selected tuple, but the sampler cannot reach it. Even when execution terminates on other inputs, the final tuple is excluded from ordinary initial-center sampling. This introduces a position-dependent restriction that is absent from the filter's stated algorithm.
Minimal reproduction to implement
Use a small array and avoid any large-data requirement:
- Create a two-tuple, one-component Float32 input with values
{10.0, 20.0}. - Create a Bool mask
{false, true}. Repeat with a UInt8 mask{0, 1}. - Configure Compute K Means with one cluster, mask enabled, Euclidean distance, and an explicit seed such as
5489. - Execute through Direct with resident stores.
- Repeat through Scanline with resident stores using the existing test scenario helper, then with actual OOC stores.
Source-predicted result: both paths remain in initial-center selection. Direct does not observe cancellation inside that loop; Scanline can leave the loop when cancellation is requested.
Test the unfixed behavior in an isolated process or another bounded-execution harness so a nonterminating baseline cannot hang the main test process.
History and reason for compatibility concern
This defect predates the recent OOC work. It is present in the original KMeans addition, PR #580, merged on 2023-07-13, at commit 03ea5f0ef. The pre-OOC implementation already has the same formula. The Scanline implementation preserved it.
The current OOC algorithm documentation explicitly retains the same seed, candidate draw order, distance tie rule, and tuple-order accumulation. Both source files also describe the exclusion as legacy behavior. This establishes a compatibility reason for retaining the formula during the rewrite.
No algorithmic reason to exclude the final tuple was found in the original source, commit description, or inspected documentation. The likely original cause is an off-by-one error, but that is an inference about intent. The final input tuple is not documented as a sentinel. KMedoids, introduced in the same PR, uses an inclusive integer distribution over 0..N-1.
Proposed fixes and repercussions
Option A: Correct the candidate range in both implementations (recommended)
Allow every valid input index, including the final tuple, to participate in initial-center sampling. Retain mask filtering and the existing duplicate-center policy. Add cancellation checking to Direct initialization and preserve it in Scanline.
Benefits
- Corrects the underlying index-range defect and accepts the valid last-only-selected input.
- Removes the final tuple's position-based exclusion from ordinary sampling.
- Provides one consistent algorithm contract for resident and OOC execution.
Repercussions
- Existing inputs can choose different initial centers for the same seed. That can change final cluster membership, centers, convergence iterations, and cluster IDs; differences need not be limited to relabeling.
- Saved seeds remain usable, but do not guarantee the old seed-to-output mapping after the change.
- Changing the random-distribution type as well as the range can change the generator draw sequence further. Choose and document the implementation deliberately.
- Update the algorithm documentation and release notes. Review existing expected outputs against independent clustering requirements; do not regenerate expected values from observed results solely to make tests pass.
- Keep OOC memory bounded. Do not allocate a full list of all selected tuple indices just to fix this range error.
- This correction alone does not guarantee identical random sequences across operating systems or standard-library implementations.
Option B: Preserve legacy sampling and add a last-only fallback
Retain the current random sampler whenever an eligible tuple exists in its legacy candidate range. If the final tuple is the only selected tuple, use that tuple for initialization under the existing duplicate-center policy. Add Direct cancellation checking.
Benefits
- Fixes the hang for the valid last-only-selected input.
- Can preserve the existing seed-to-output mapping for previously terminating inputs, provided the eligibility check does not consume random draws or change ordinary execution order.
- Avoids a broad compatibility change for established pipelines.
Repercussions
- Retains the final tuple's exclusion in normal initial-center sampling. The underlying selection bias remains.
- Adds a compatibility special case that must be documented and maintained in both paths.
- Determining whether the legacy candidate range contains a selected tuple requires mask inspection. Reuse the existing scan where possible, with bounded bulk reads and cancellation for OOC data.
- For more than one requested cluster, the fallback must retain or explicitly redefine the existing duplicate-center and empty-cluster behavior. It must not silently add a new policy.
Option C: Preserve legacy sampling and reject the unsupported mask
Detect that no tuple is eligible within the legacy candidate range and return a clear error before entering the selection loop. Add Direct cancellation checking.
Benefits
- Prevents the hang while preserving the existing sampler and seeded results for accepted inputs.
- Provides an explicit failure instead of nontermination.
Repercussions
- Rejects an otherwise valid clustering input. For one cluster and one selected tuple, a straightforward result exists.
- Retains the final tuple's exclusion for all accepted inputs.
- Adds a documented restriction tied to tuple position. Users must alter the data order or mask to proceed.
- Detection requires inspecting mask values; it belongs in execution-time validation where those values are available, rather than relying only on metadata preflight.
No option has been selected yet. Option A is the proposed correctness repair; B or C would be explicit compatibility policies.
Existing tests and formal V&V status
The current public tests cover an exemplar cluster pattern, masked Direct/Scanline comparison, all-false-mask rejection, and legacy JSON conversion. Additional disk-backed fixtures exist in the OOC test suite. None of the inspected cases covers the last-only-selected boundary above.
No completed filter-specific V&V report or sign-off was found in the inspected repositories/history. Compute K Means is not among the 40 filters listed in the local OOC V&V audit record. The completed documentation-review entry is not a formal V&V sign-off. This does not establish that no offline validation record exists.
Acceptance criteria
- Choose and document A, B, or C, including the seed-compatibility policy.
- Add a deterministic regression for two tuples with only the last selected, using Bool and UInt8 masks.
- Cover a single selected tuple, an all-false mask, a mask with the final tuple excluded, and ordinary multiple-selected-tuple inputs.
- Verify initialization cancellation in both implementations without an unbounded test hang.
- Verify the same selected policy through Direct/resident, Scanline/resident, and Scanline/actual-OOC execution, with explicit path/store witnesses.
- For A, demonstrate final-tuple eligibility and review numerical changes against independent requirements. For B/C, verify unchanged seeded results for previously terminating accepted inputs.
- Preserve bounded OOC memory and propagate storage-read failures during any new eligibility scan.
- Update user documentation and release notes for any changed sampling behavior or input restriction.
This issue concerns sampling and initialization termination. The separately identified zero-cluster Direct/Scanline mismatch and other convergence concerns require their own decisions; they are not implicitly included in this fix.
- 主要言語
- C++
- スター
- 18
- フォーク
- 13
- 平均マージ
- 8日 3時間
- マージ済み PR(30日)
- 13
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
BlueQuartzSoftware/simplnx のほかの issue
-
Write Abaqus Hexahedron Filter Enhancements対応中かも @imikejackson が 20 日前に担当しました。 オープンFeature Request
BlueQuartzSoftware/simplnx#1740 · コメント 3 件 · 担当者 1 名 ·
メンテナーはふだん 4 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
BlueQuartzSoftware/simplnx#1707 ·
メンテナーはふだん 4 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
BlueQuartzSoftware/simplnx#1705 ·
メンテナーはふだん 4 日以内に返信
-
ENH: Add executable to dump the DataStructure Hierarchy either to standard out or to a file対応中かも @imikejackson が 19 日前に担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
BlueQuartzSoftware/simplnx#1681 · コメント 1 件 ·
メンテナーはふだん 4 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
BlueQuartzSoftware/simplnx#1678 ·
メンテナーはふだん 4 日以内に返信
BlueQuartzSoftware/simplnx の issue をすべて見る
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
microsoft/onnxruntime#33018 ·
メンテナーはふだん 2 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
customer-reported needs-triage question
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
Azure/azure-sdk-for-cpp#7435 ·
メンテナーはふだん 1 日以内に返信
-
ChromieCraft Generic Confirmed World Event
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
azerothcore/azerothcore-wotlk#27882 ·
メンテナーはふだん 1 日以内に返信
-
MacOS build failureオープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
aristocratos/btop#1874 ·
メンテナーはふだん 1 日以内に返信