Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

// META: title=WebNN reduceLogSum small, zero, and large sums
// META: global=window
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long
'use strict';
// reduceLogSum is log(sum(x)), without an added epsilon. All input values
// below are exactly representable in both input types. The large-sum case
// has a finite float16 result even though the sum exceeds float16's range.
// That case assumes at least float32 intermediate accumulation, or another
// algorithm that avoids float16 overflow before taking the logarithm.
const logSumSmallValueTests = [];
for (const dataType of ['float32', 'float16']) {
const expected = dataType === 'float32' ? {
tiny: -16.63553237915039,
small: [-13.862943649291992, -12.476649284362793],
large: 12.476161003112793,
two: 0.6931471824645996
} : {
tiny: -16.640625,
small: [-13.859375, -12.4765625],
large: 12.4765625,
two: 0.693359375
};
for (const constant of [false, true]) {
for (const test of [
{
label: 'small positive sums', shape: [2, 4],
data: [
2 ** -24, 3 * 2 ** -24, 5 * 2 ** -24, 7 * 2 ** -24,
4 * 2 ** -24, 12 * 2 ** -24, 20 * 2 ** -24, 28 * 2 ** -24
],
options: {axes: [1]}, outputShape: [2], output: expected.small
},
{
label: 'zero and cancelled sums with keepDimensions', shape: [2, 4],
data: [0, 0, 0, 0, 1, -1, 0, 0],
options: {axes: [1], keepDimensions: true}, outputShape: [2, 1],
output: [-Infinity, -Infinity]
},
{
label: 'finite result after large sum', shape: [4],
data: [65504, 65504, 65504, 65504], options: {}, outputShape: [],
output: [expected.large]
},
{
label: 'small scalar', shape: [], data: [2 ** -24], options: {},
outputShape: [], output: [expected.tiny]
},
{
label: 'empty axes', shape: [3], data: [2 ** -24, 0, 2],
options: {axes: []}, outputShape: [3],
output: [expected.tiny, -Infinity, expected.two]
}
]) {
logSumSmallValueTests.push({
name: `reduceLogSum ${dataType} ${constant ? 'constant' : 'runtime'} ` +
test.label,
graph: {
inputs: {
input: {
data: test.data, descriptor: {shape: test.shape, dataType},
constant
}
},
operators: [{
name: 'reduceLogSum',
arguments: [{input: 'input'}, {options: test.options}],
outputs: 'result'
}],
expectedOutputs: {
result: {
data: test.output,
descriptor: {shape: test.outputShape, dataType}
}
}
}
});
}
}
}
webnn_conformance_test(logSumSmallValueTests, buildAndExecuteGraph,
getPrecisionTolerance);