Determinant and Inverse return wrong values when called from more than one thread
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 35/100
- Issue 類型
- 缺陷
- 描述清晰度
- 描述清楚
- 活躍度
- 停滯
- 技術堆疊
- csharp
- 領域
- performance
研究方向
先從 SquareMatrixFactory<T, TWrapper>.GetMatrix 和 ExpressionCompiler<T, TWrapper>.storage 開始,然後使用 Parallel.For 重現回報的行列式/反矩陣失敗,包括冷快取情況。完成標準是並行矩陣操作回傳經過循序驗證的值,且不會出現集合例外或共用緩衝區損毀。
由索引模型根據 Issue 內容生成。
描述
Two process-wide statics are read and written with no synchronisation, so matrix operations called from more than one thread return wrong numbers. Nothing throws, nothing is malformed, and no result looks suspicious.
I found this from the other side: AngouriMath uses GenTensor for its symbolic matrices, and a determinant computed on a background thread was coming back numerically wrong. AngouriMath's issue is #1219.
1. The scratch-matrix pool
SquareMatrixFactory<T, TWrapper>.GetMatrix hands every caller the same GenTensor for a given size, and the caller then writes into it — Inversion.GetCofactorMatrix(t, temp, ...) fills the matrix it is given. Two threads taking a determinant or an inverse of the same size get the same buffer and overwrite each other's minors between the write and the read.
Sixty 5×5 int matrices, each computed once sequentially for truth and then rebuilt and recomputed under Parallel.For:
DeterminantLaplace 53 of 60 disagree
Adjoint 60 of 60 disagree
Around 10 ms, every run. This is not a rare interleaving, it is the normal case.
DeterminantGaussianSafeDivision is unaffected — it works on its own copy and never asks the pool for anything.
The lock inside GetMatrix does not help and is itself incomplete: the list is indexed after the lock is released, so a concurrent Add can reallocate the backing array underneath the reader.
2. The compiled-operation cache
ExpressionCompiler<T, TWrapper>.storage is a plain Dictionary, written by whichever thread first asks for a given (operation, rank, parallel). Dictionary<,> is documented as safe for concurrent readers only while nobody is writing.
Reached cold from several threads it fails with the runtime's own diagnostic:
System.InvalidOperationException: Operations that change non-concurrent collections must
have exclusive access. A concurrent update was performed on this collection and corrupted
its state. The collection's state is no longer correct.
...
The given key '(Subtraction, 1, False)' was not present in the dictionary.
Worth noting that this one hides easily. My first test computed its expected values sequentially and only then went parallel, which populated every key before the threads started — the cache holds a handful of entries, so a warm-up makes the defect invisible and the test passes against the broken code.
Fix
I have opened a PR. Both are small: [ThreadStatic] for the pool, since a scratch buffer has nothing to share between threads, and ConcurrentDictionary for the cache. The Laplace determinant comes out about 5% faster, because the pool is now taken once at the top of the recursion instead of re-checked and re-indexed at every one of its n! nodes.
- 主要語言
- C#
- 星號
- 52
- 分支
- 6
- PR 合併指標
- 30 天內沒有已合併 PR
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
ASC-Community/GenericTensor 的其他 Issue
-
good first issue
難度 4/5 3-5 天 新手友好度 25/100
-
proposal
難度 4/5 3-5 天 新手友好度 35/100
ASC-Community/GenericTensor#36 · 1 則留言 ·
-
Opinions wanted proposal
難度 5/5 一週以上 新手友好度 25/100
ASC-Community/GenericTensor#31 · 2 則留言 ·
-
Will this package support MKL or OpenBlas as backend to accelerate matrix inverse computing speed未關閉
難度 5/5 一週以上 新手友好度 25/100
ASC-Community/GenericTensor#30 · 1 則留言 ·
-
難度 5/5 一週以上 新手友好度 20/100
ASC-Community/GenericTensor#29 · 1 則留言 ·
查看 ASC-Community/GenericTensor 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 68/100
stryker-mutator/stryker-net#3892 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 65/100
MobiFlight/MobiFlight-Connector#3419 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 82/100
Kryptos-FR/MarkView.Avalonia#105 ·
維護者通常 1 天內回覆
-
[辞書]未關閉提案 辞書
難度 2/5 1-3 小時 新手友好度 65/100
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 76/100
microsoft/fluentui-blazor#5410 ·
維護者通常 1 天內回覆