CultMath tests: a dense sweep pins cultmath_phacelle against C# bit for bit
The generic mirror comparison passes about a hundred inputs through the shader and missed a mirror whose prune cut was 2.0 instead of 2.25, because only a rare cell has a nonzero weight under that cut. Twenty thousand random arguments compare the shader text and math.phacelle field by field and kill that mutant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9f18a432cb
commit
2a3cab1bd7
1 changed files with 29 additions and 0 deletions
|
|
@ -134,6 +134,35 @@ public sealed class HlslSourceCompatibilityTests
|
|||
Assert.Equal(34, compared.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The generic comparison above passes about a hundred inputs through <c>cultmath_phacelle</c>, and
|
||||
/// its prune only changes an output for the rare cell whose weight is nonzero but whose lower
|
||||
/// bound sits just under the 2.25 cut (Soul's F6 lesson for cellular): a mirror whose cut is 2.0
|
||||
/// survives a hundred inputs. A dense sweep of realistic arguments closes that gap.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void PhacelleMirrorMatchesCSharpBitForBitAcrossADenseSweep()
|
||||
{
|
||||
var (assembly, errors) = CompileShaderMirror();
|
||||
Assert.True(assembly is not null, string.Join(Environment.NewLine, errors));
|
||||
var shaderType = assembly!.GetType("CultMathHlsl.HlslShader")!;
|
||||
var shader = Activator.CreateInstance(shaderType);
|
||||
var mirror = ShaderFunction(shaderType, "cultmath_phacelle", typeof(float3), typeof(float3), typeof(float), typeof(float))!;
|
||||
|
||||
var random = new System.Random(0x5EED2);
|
||||
float Next(float extent) => (random.NextSingle() * 2.0f - 1.0f) * extent;
|
||||
for (var i = 0; i < 20000; i++)
|
||||
{
|
||||
var p = new float3(Next(50.0f), Next(50.0f), Next(50.0f));
|
||||
var side = new float3(Next(9.0f), Next(9.0f), Next(9.0f));
|
||||
var offset = random.NextSingle();
|
||||
var normalization = random.NextSingle();
|
||||
var expected = Values(phacelle(p, side, offset, normalization));
|
||||
var actual = Values(mirror.Invoke(shader, new object[] { p, side, offset, normalization })!);
|
||||
Assert.True(BitwiseEqual(expected, actual), $"mirror differs from C# at p = {p}, side = {side}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A hand-built pair of structs standing in for a mirror struct return and its C# counterpart
|
||||
/// (invariant 8's one struct return shape, e.g. <see cref="CultCellular"/>): same field shape,
|
||||
|
|
|
|||
Loading…
Reference in a new issue