Skip to content

test: migrate blas/base/wasm/srotm to ULP-based assertions - #16060

Merged
kgryte merged 1 commit into
developfrom
kgryte/ulp-blas-base-wasm-srotm
Oct 11, 2026
Merged

kgryte merged 1 commit into
developfrom
kgryte/ulp-blas-base-wasm-srotm

Conversation

@kgryte

@kgryte kgryte commented Oct 11, 2026

Copy link
Copy Markdown
Member

Resolves a part of #11352.

Description

What is the purpose of this pull request?

This pull request:

Concretely, in each of test/test.main.js, test/test.ndarray.js, test/test.module.main.js, and test/test.module.ndarray.js, the following helper

function isApprox( t, actual, expected, rtol ) {
	var delta;
	var tol;
	var i;

	t.strictEqual( actual.length, expected.length, 'returns expected value' );
	for ( i = 0; i < expected.length; i++ ) {
		if ( actual[ i ] === expected[ i ] ) {
			t.strictEqual( actual[ i ], expected[ i ], 'returns expected value' );
		} else {
			delta = abs( actual[ i ] - expected[ i ] );
			tol = rtol * EPS * abs( expected[ i ] );
			t.ok( delta <= tol, 'within tolerance. actual: '+actual[ i ]+'. expected: '+expected[ i ]+'. delta: '+delta+'. tol: '+tol+'.' );
		}
	}
}

is replaced by

function isApprox( t, actual, expected, ulp ) {
	var i;

	t.strictEqual( actual.length, expected.length, 'returns expected value' );
	for ( i = 0; i < expected.length; i++ ) {
		t.strictEqual( isAlmostSameValuef( actual[ i ], expected[ i ], ulp ), true, 'returns expected value' );
	}
}

along with adding the @stdlib/number/float32/base/assert/is-almost-same-value require and dropping the now-unused @stdlib/math/base/special/abs and @stdlib/constants/float32/eps requires.

As this package operates on single-precision floating-point numbers, the tests use the single-precision assertion utility (isAlmostSameValuef), matching the convention already established by the sibling packages blas/base/srotm (the non-WASM implementation of the same routine), blas/base/wasm/srot, and blas/base/wasm/drotm, whose converted test files use the same isApprox( t, actual, expected, ulp ) helper shape with a per-call-site integer ULP bound.

ULP bounds

Every tolerance-based assertion in this package compares a Float32Array against expected Float32Array values, in x/y pairs (actualX/actualY in the module test files). The measured minimum differs between the two members of a pair and between test cases, so each assertion carries its own bound rather than a single uniform value. The non-zero bounds are:

File Test case x ULP y ULP
test/test.main.js applies a modified Givens plane rotation (sx=1, sy=1) 1 0
test/test.main.js applies a modified Givens plane rotation (sx=2, sy=-2) 0 1
test/test.main.js applies a modified Givens plane rotation (sx=-2, sy=1) 1 2
test/test.main.js applies a plane rotation (sx=-1, sy=-2) 1 0
test/test.ndarray.js applies a modified Givens plane rotation (sx=1, sy=1) 1 0
test/test.ndarray.js applies a modified Givens plane rotation (sx=2, sy=-2) 0 1
test/test.ndarray.js applies a modified Givens plane rotation (sx=-2, sy=1) 1 2
test/test.ndarray.js applies a plane rotation (sx=-1, sy=-2) 1 0
test/test.module.main.js applies a modified Givens plane rotation (sx=1, sy=1) 1 0
test/test.module.main.js applies a modified Givens plane rotation (sx=2, sy=-2) 0 1
test/test.module.ndarray.js applies a modified Givens plane rotation (sx=1, sy=1) 1 0
test/test.module.ndarray.js applies a modified Givens plane rotation (sx=2, sy=-2) 0 1

All remaining assertions (the stride, offset, negative stride, and complex access pattern test cases) are bit-exact against their expected values and so carry a bound of 0. In the module test files, the (sx=1, sy=1) case asserts twice (long and short datasets), and both assertion pairs require the same bounds. In total, 84 of the 100 call sites are exact (0), 14 require 1, and 2 require 2. This replaces the previous non-uniform relative tolerances of 1.0, 2.0, 4.0, 5.0, and 10.0 (i.e., rtol * EPS * abs( expected )).

The bounds were tightened empirically rather than guessed. The test helper was instrumented to report, for every call site, the smallest integer u for which isAlmostSameValuef( actual[ i ], expected[ i ], u ) holds for all elements, maximized over every invocation of that call site (several call sites are exercised repeatedly inside a loop over N). Each call site then received exactly that measured maximum, so 2 is the largest bound required anywhere in the package.

Minimality was confirmed in both directions:

  • at the chosen bounds, all seven test files pass with 0 failures;
  • decrementing every non-zero bound by one (16 call sites) produces failures in all four files — 11, 11, 4, and 4 failing assertions in test/test.main.js, test/test.ndarray.js, test/test.module.main.js, and test/test.module.ndarray.js, respectively — so none of the chosen bounds can be lowered.

The full test suite was run twice at the final values to confirm the result is stable (no FMA/arch-dependent variation); both runs report identical passing counts and 0 failures.

Related Issues

Does this pull request have any related issues?

This pull request has the following related issues:

Questions

Any questions for reviewers of this pull request?

One: whether per-call-site bounds are preferred over a single uniform bound per test case. The issue asks for the minimum required ULP value, which is what is used here, and this matches blas/base/wasm/srot. The sibling blas/base/srotm instead declares a single ULP variable per test and uses it for both the x and y assertions. If reviewers prefer that shape, it is a small change and I am happy to make it.

Other

Any other information relevant to this pull request? This may include screenshots, references, and/or implementation notes.

Only the four test files containing tolerance-based assertions are modified; no source, documentation, benchmark, or fixture files are touched. test/test.js, test/test.module.js, and test/test.routine.js contain no tolerance-based assertions and are left unchanged. The assertion count is unchanged by this migration, as the removed exact/approximate branch emitted exactly one assertion per element either way.

Verification performed:

  • make test TESTS_FILTER=".*/blas/base/wasm/srotm/.*" — 1129 passing, 0 failing across all seven test files (416, 440, 128, 104, 27, 8, and 6). Run twice, with identical results.
  • Minimality confirmed by re-running the suite with every non-zero bound decremented by one, which fails as expected (30 failing assertions).
  • ESLint using etc/eslint/.eslintrc.tests.js — 0 errors. The four reported max-len warnings are pre-existing and present identically on develop.
  • EditorConfig compliance (LF endings, UTF-8, no trailing whitespace, final newline, tab indentation) verified directly against .editorconfig, as the editorconfig-checker binary could not be downloaded in the sandbox used to author this change.

Checklist

Please ensure the following tasks are completed before submitting this pull request.

AI Assistance

When authoring the changes proposed in this PR, did you use any kind of AI assistance?

  • Yes
  • No

If you answered "yes" above, how did you use AI assistance?

  • Code generation (e.g., when writing an implementation or fixing a bug)
  • Test/benchmark generation
  • Documentation (including examples)
  • Research and understanding

Disclosure

If you answered "yes" to using AI assistance, please provide a short disclosure indicating how you used AI assistance. This helps reviewers determine how much scrutiny to apply when reviewing your contribution. Example disclosures: "This PR was written primarily by Claude Code." or "I consulted ChatGPT to understand the codebase, but the proposed changes were fully authored manually by myself.".

This PR was authored by Claude Code running as an unattended task. It studied the migration idiom from previously converted sibling packages in the same family (blas/base/srotm, blas/base/wasm/srot, blas/base/wasm/drotm), applied the mechanical substitution to the four affected test files, and determined the ULP bounds by instrumenting the test helper to report the minimum passing ULP distance per call site, then confirming that lower bounds fail while the chosen bounds pass and re-running the suite to confirm the result is deterministic.


@stdlib-js/reviewers

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nmq7FgD5jskQ5tmDrLor8K


Generated by Claude Code

Replaces the computed relative tolerance assertions in the test files for
`blas/base/wasm/srotm` with ULP-based assertions using
`@stdlib/number/float32/base/assert/is-almost-same-value`.

Each ULP bound was measured as the minimum integer number of ULPs which
passes over the full set of test fixtures.

Ref: #11352

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nmq7FgD5jskQ5tmDrLor8K
@stdlib-bot stdlib-bot added BLAS Issue or pull request related to Basic Linear Algebra Subprograms (BLAS). Good First PR A pull request resolving a Good First Issue. labels Oct 11, 2026
@stdlib-bot

Copy link
Copy Markdown
Contributor

Coverage Report

Package Statements Branches Functions Lines
blas/base/wasm/srotm $\\color{green}684/684$
$\\color{green}+100.00\\%$
$\\color{green}17/17$
$\\color{green}+100.00\\%$
$\\color{green}6/6$
$\\color{green}+100.00\\%$
$\\color{green}684/684$
$\\color{green}+100.00\\%$

The above coverage report was generated for the changes in this PR.

@kgryte kgryte added the Tests Pull requests specifically adding tests. label Oct 11, 2026
@kgryte
kgryte marked this pull request as ready for review October 11, 2026 12:23
@kgryte
kgryte requested a review from a team October 11, 2026 12:23
@stdlib-bot stdlib-bot added the Needs Review A pull request which needs code review. label Oct 11, 2026
@kgryte
kgryte merged commit eff53c5 into develop Oct 11, 2026
82 checks passed
@kgryte
kgryte deleted the kgryte/ulp-blas-base-wasm-srotm branch October 11, 2026 12:24
@stdlib-bot stdlib-bot removed the Needs Review A pull request which needs code review. label Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BLAS Issue or pull request related to Basic Linear Algebra Subprograms (BLAS). Good First PR A pull request resolving a Good First Issue. Tests Pull requests specifically adding tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants