Three classes named *ParityTests that cannot detect the bug they exist for
C1 — zero quantisation-type assertions across ~20 named-quant end-to-end tests
tests/DotLLM.Tests.Integration/Vulkan/RealGgufVulkanParityTests.cs (tests at :75,91,111,138,157,169,187,215,234,246)
tests/DotLLM.Tests.Integration/Cuda/RealGgufCudaParityTests.cs (tests at :66,81,102,120,135,146,164,175,191,202)
grep -c QuantizationType returns 0 in both files. Each test is named <Model>_<QUANT>_VulkanForward_MatchesCpuReference and asserts only Architecture — trusting the filename and an env var. The doc at :162 explicitly invites substituting any GGUF via env var.
So a completely broken IQ1_S kernel passes when the env var points at a GGUF containing no IQ1_S tensor. The sibling file already warns about exactly this in prose: RealGgufQ3KDequantParityTests.cs:44-46 names a SmolLM-135M i1-Q3_K_M build that carries no Q3_K tensor at all. This is #344 mandate (4), violated in the files that most need it.
The tolerances are barely wider than a total scramble. :59-63 sets LogitsAbsTol = 3.0, TopKJaccardFloor = 0.5, StrictArgmaxFloor = 5/9. The same file records at :200-208 that #311 — a layout transposition producing weights with correlation 0.006 — measured L-inf 5.09 and Jaccard 0.40. Total garbage cleared the bound by 1.7x and 0.10. Any layout bug affecting a subset of sub-blocks fits inside. Constants duplicated at RealGgufCudaParityTests.cs:50-52.
C2 — a *ParityTests class whose only assertion is corpus length
tests/DotLLM.Tests.Integration/Cuda/CudaAttentionSplitKvGenerationParityTests.cs:123 and :314. The complete assertion set in both methods is Assert.True(fullCorpus.Length >= 1100). Every token, top1/top2 margin and both pre-/post-gate perplexities go to ITestOutputHelper and are never compared — not even a finiteness check.
Passes with attention_f32_split_kv returning zeros, un-softmaxed scores, a wrong hkv = hq % numKvHeads, or NaN, at every decode step at or above the gate.
C3 — GQA-split parity asserted only where the kernel is switched OFF
tests/DotLLM.Tests.Integration/Cuda/CudaAttentionMmaDecodeGqaSplitGenerationParityTests.cs:114,148,260. Three assertions total: corpus length, dispatched > 0, and Assert.Equal(0.0, maxPreGateStepDiff) — the last covering only depth < AttentionGqaSplitMinSeqKv, i.e. the region where the kernel under test is not called. Every post-gate step is log-only.
Passes for any implementation correct below the gate and wrong above it — specifically the kvHead = qHead % numKvHeads vs qHead / group swap, which is the kernel's entire purpose.
Fixes, all with in-repo precedent
- C1: lift the 5-line type-assertion block from
RealGgufQ3KCudaForwardParityTests.cs:74-79 into RunGgufParityTest, taking the expected QuantizationType alongside expectedArch, with a tensor-count floor so one stray tensor cannot satisfy it. CrossBackendQuantGateTests.cs:204 is the stronger model — it requires every transformer-block weight to be the expected type.
- C1 tolerances: re-derive from a clean distribution and document the reasoning, as
RealGgufQ5_0ParityTests.cs:44-64 does.
- C2: assert
pplPostOn / pplPostOff <= 1.01 plus token-for-token agreement — the shape VulkanSplitDecodeMoeParityTests.cs:118,137 already uses.
- C3: assert post-gate steps, not just pre-gate.
Per #417, each fix must be demonstrated to fail against the wrong implementation named above.
Source: .docs/test-discrimination-audit.md sections C1-C3. Related: #417, #344, #311.
Three classes named
*ParityTeststhat cannot detect the bug they exist forC1 — zero quantisation-type assertions across ~20 named-quant end-to-end tests
tests/DotLLM.Tests.Integration/Vulkan/RealGgufVulkanParityTests.cs(tests at:75,91,111,138,157,169,187,215,234,246)tests/DotLLM.Tests.Integration/Cuda/RealGgufCudaParityTests.cs(tests at:66,81,102,120,135,146,164,175,191,202)grep -c QuantizationTypereturns 0 in both files. Each test is named<Model>_<QUANT>_VulkanForward_MatchesCpuReferenceand asserts onlyArchitecture— trusting the filename and an env var. The doc at:162explicitly invites substituting any GGUF via env var.So a completely broken IQ1_S kernel passes when the env var points at a GGUF containing no IQ1_S tensor. The sibling file already warns about exactly this in prose:
RealGgufQ3KDequantParityTests.cs:44-46names a SmolLM-135Mi1-Q3_K_Mbuild that carries no Q3_K tensor at all. This is #344 mandate (4), violated in the files that most need it.The tolerances are barely wider than a total scramble.
:59-63setsLogitsAbsTol = 3.0,TopKJaccardFloor = 0.5,StrictArgmaxFloor = 5/9. The same file records at:200-208that #311 — a layout transposition producing weights with correlation 0.006 — measured L-inf 5.09 and Jaccard 0.40. Total garbage cleared the bound by 1.7x and 0.10. Any layout bug affecting a subset of sub-blocks fits inside. Constants duplicated atRealGgufCudaParityTests.cs:50-52.C2 — a
*ParityTestsclass whose only assertion is corpus lengthtests/DotLLM.Tests.Integration/Cuda/CudaAttentionSplitKvGenerationParityTests.cs:123and:314. The complete assertion set in both methods isAssert.True(fullCorpus.Length >= 1100). Every token, top1/top2 margin and both pre-/post-gate perplexities go toITestOutputHelperand are never compared — not even a finiteness check.Passes with
attention_f32_split_kvreturning zeros, un-softmaxed scores, a wronghkv = hq % numKvHeads, or NaN, at every decode step at or above the gate.C3 — GQA-split parity asserted only where the kernel is switched OFF
tests/DotLLM.Tests.Integration/Cuda/CudaAttentionMmaDecodeGqaSplitGenerationParityTests.cs:114,148,260. Three assertions total: corpus length,dispatched > 0, andAssert.Equal(0.0, maxPreGateStepDiff)— the last covering onlydepth < AttentionGqaSplitMinSeqKv, i.e. the region where the kernel under test is not called. Every post-gate step is log-only.Passes for any implementation correct below the gate and wrong above it — specifically the
kvHead = qHead % numKvHeadsvsqHead / groupswap, which is the kernel's entire purpose.Fixes, all with in-repo precedent
RealGgufQ3KCudaForwardParityTests.cs:74-79intoRunGgufParityTest, taking the expectedQuantizationTypealongsideexpectedArch, with a tensor-count floor so one stray tensor cannot satisfy it.CrossBackendQuantGateTests.cs:204is the stronger model — it requires every transformer-block weight to be the expected type.RealGgufQ5_0ParityTests.cs:44-64does.pplPostOn / pplPostOff <= 1.01plus token-for-token agreement — the shapeVulkanSplitDecodeMoeParityTests.cs:118,137already uses.Per #417, each fix must be demonstrated to fail against the wrong implementation named above.
Source:
.docs/test-discrimination-audit.mdsections C1-C3. Related: #417, #344, #311.