Skip to content

Commit ad254c6

Browse files
authored
Test truncation of subnormals (#4623)
Add a test that specifically captures the result of trunc() on a subnormal value which has been operated on to make it even smaller and no longer representable as subnormal. Whether the result of that operation is flushed to zero or not, the result of trunc() should still be zero. Before https://dawn-review.googlesource.com/c/dawn/+/302655 was landed in Tint, this CTS test would fail on a Windows 11 device with an Intel driver (the result would be 1.0). Now it should pass on all known devices.
1 parent 09fdb84 commit ad254c6

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

src/webgpu/listing_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,7 @@
17801780
"webgpu:shader,execution,expression,call,builtin,trunc:abstract_float:*": { "subcaseMS": 12197.517 },
17811781
"webgpu:shader,execution,expression,call,builtin,trunc:f16:*": { "subcaseMS": 120.204 },
17821782
"webgpu:shader,execution,expression,call,builtin,trunc:f32:*": { "subcaseMS": 48.544 },
1783+
"webgpu:shader,execution,expression,call,builtin,trunc:subnormal_division:*": { "subcaseMS": 103.258 },
17831784
"webgpu:shader,execution,expression,call,builtin,unpack2x16float:unpack:*": { "subcaseMS": 11.651 },
17841785
"webgpu:shader,execution,expression,call,builtin,unpack2x16snorm:unpack:*": { "subcaseMS": 9.275 },
17851786
"webgpu:shader,execution,expression,call,builtin,unpack2x16unorm:unpack:*": { "subcaseMS": 8.701 },

src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ Component-wise when T is a vector.
1010

1111
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
1212
import { AllFeaturesMaxLimitsGPUTest } from '../../../../../gpu_test.js';
13-
import { Type } from '../../../../../util/conversion.js';
14-
import { allInputSources, onlyConstInputSource, run } from '../../expression.js';
13+
import { kValue } from '../../../../../util/constants.js';
14+
import { Type, f32, f16 } from '../../../../../util/conversion.js';
15+
import { FP } from '../../../../../util/floating_point.js';
16+
import {
17+
allInputSources,
18+
onlyConstInputSource,
19+
run,
20+
basicExpressionBuilder,
21+
} from '../../expression.js';
1522

1623
import { abstractFloatBuiltin, builtin } from './builtin.js';
1724
import { d } from './trunc.cache.js';
@@ -60,3 +67,39 @@ g.test('f16')
6067
const cases = await d.get('f16');
6168
await run(t, builtin('trunc'), [Type.f16], Type.f16, t.params, cases);
6269
});
70+
71+
g.test('subnormal_division')
72+
.specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions')
73+
.desc(`truncate subnormals made even smaller to zero`)
74+
.params(u => u.combine('inputSource', allInputSources).combine('type', ['f32', 'f16'] as const))
75+
.fn(async t => {
76+
const type = t.params.type;
77+
if (type === 'f16') {
78+
t.skipIfDeviceDoesNotHaveFeature('shader-f16');
79+
}
80+
81+
const trait = FP[type as 'f32' | 'f16'];
82+
const scalarBuilder = type === 'f32' ? f32 : f16;
83+
const constant = kValue[type as 'f32' | 'f16'];
84+
const cases = [
85+
// Smallest subnormals (closest to zero)
86+
{
87+
input: [scalarBuilder(constant.negative.subnormal.max)],
88+
expected: trait.toInterval(constant.negative.zero),
89+
},
90+
{
91+
input: [scalarBuilder(constant.positive.subnormal.min)],
92+
expected: trait.toInterval(constant.positive.zero),
93+
},
94+
];
95+
96+
await run(
97+
t,
98+
// Divided by 10.0 to make subnormal even smaller and unrepresentable as subnormal, should truncate to zero
99+
basicExpressionBuilder(values => `trunc(${values[0]} / 10.0)`),
100+
[Type[type as 'f32' | 'f16']],
101+
Type[type as 'f32' | 'f16'],
102+
t.params,
103+
cases
104+
);
105+
});

0 commit comments

Comments
 (0)