Skip to content

Vectorize Atanh for Vector64/128/256/512 and TensorPrimitives#126420

Open
stephentoub wants to merge 2 commits intomainfrom
copilot/vectorize-atanh
Open

Vectorize Atanh for Vector64/128/256/512 and TensorPrimitives#126420
stephentoub wants to merge 2 commits intomainfrom
copilot/vectorize-atanh

Conversation

@stephentoub
Copy link
Copy Markdown
Member

@stephentoub stephentoub commented Apr 1, 2026

Add vectorized Atanh implementations for float and double across all SIMD vector types.

Description

  • Exposes new Vector64/128/256/512.Atanh APIs and updates the System.Runtime.Intrinsics ref surface.
  • Implements the shared vectorized math kernels in VectorMath for atanh (double core + float via widen/narrow).
  • Enables TensorPrimitives.Atanh vectorization for float/double and adjusts test tolerances accordingly.
  • Fixed Vector256.Atanh(float) to branch on Vector512.IsHardwareAccelerated and fall back to Vector256<double> when Vector512 isn't available, matching the pattern used by Asin, Cos, Exp, and other float implementations.
  • Added unit tests for Vector64/128/256/512.Atanh APIs covering accuracy (with tolerances) and special cases (NaN, ±0, |x|>1 → NaN, x=±1 → ±Infinity) following the existing Asin/Cos test patterns. Test data added to GenericMathTestMemberData with AtanhDouble and AtanhSingle data sources covering standard mathematical constants.

Add vectorized Atanh implementations for float and double across all SIMD vector types.
- AtanhDouble: AMD atanh.c [5,5] rational polynomial + log1p identity for large values
- AtanhSingle: widens to double, uses AMD atanhf.c [2,2] rational polynomial
- Hook up TensorPrimitives.Atanh to use vectorized implementations

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 1, 2026 18:10
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-runtime-intrinsics
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SIMD-optimized Atanh for float/double across Vector64/128/256/512 and enables corresponding vectorization in TensorPrimitives.Atanh.

Changes:

  • Exposes new Vector64/128/256/512.Atanh APIs (and updates the System.Runtime.Intrinsics ref surface).
  • Implements the shared vectorized math kernels in VectorMath for atanh (double core + float via widen/narrow).
  • Enables TensorPrimitives.Atanh vectorization for float/double (and adjusts test tolerances accordingly).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs Adds Atanh to the public ref surface for Vector64/128/256/512.
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/VectorMath.cs Introduces vectorized AtanhDouble and AtanhSingle implementations used by all vector types.
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs Adds Vector64.Atanh (double/float) and scalar fallback helper.
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs Adds Vector128.Atanh (double/float), delegating to VectorMath or splitting to Vector64.
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs Adds Vector256.Atanh (double/float), delegating to VectorMath or splitting to Vector128.
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs Adds Vector512.Atanh (double/float), delegating to VectorMath or splitting to Vector256.
src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs Updates Atanh test tolerance to account for vectorized implementation accuracy.
src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.Atanh.cs Enables vectorization for Atanh when T is float/double (NET11+), using the new vector APIs.

@stephentoub
Copy link
Copy Markdown
Member Author

@copilot please evaluate and address the feedback

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Code Review: Atanh Vectorization

❌ Bug: Vector256.Atanh(Vector256<float>) unconditionally uses Vector512 without availability check

File: src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs (lines 877–890)
Severity: High

Vector256.Atanh(Vector256<float>) unconditionally instantiates VectorMath.AtanhSingle with Vector512<double> type parameters when IsHardwareAccelerated is true, without first checking Vector512.IsHardwareAccelerated. On systems with AVX2 but no AVX-512 (the vast majority of deployed x86-64 CPUs), every Vector512 operation inside the math kernel will be software-emulated as pairs of Vector256 operations, defeating the purpose of vectorization.

Current code:

public static Vector256<float> Atanh(Vector256<float> vector)
{
    if (IsHardwareAccelerated)
    {
        // ⚠️ Always uses Vector512 — no availability check
        return VectorMath.AtanhSingle<Vector256<float>, Vector256<int>, Vector256<uint>,
            Vector512<double>, Vector512<long>, Vector512<ulong>>(vector);
    }
    ...
}

Every other Vector256 single-precision math function in the same file guards on Vector512.IsHardwareAccelerated:

Function Line Has Vector512.IsHardwareAccelerated check?
Asin 840
Cos 915
Exp 1820
Hypot 2072
Sin 3873
SinCos 3917
Atanh 879 ❌ Missing

Note that the PR's own sibling methods Vector64.Atanh(float) (checks Vector128.IsHardwareAccelerated) and Vector128.Atanh(float) (checks Vector256.IsHardwareAccelerated) correctly follow the pattern — only the Vector256 case was missed.

Suggested fix: Add the guard and provide a Vector256<double> fallback, matching the Asin pattern directly above:

if (IsHardwareAccelerated)
{
    if (Vector512.IsHardwareAccelerated)
    {
        return VectorMath.AtanhSingle<Vector256<float>, Vector256<int>, Vector256<uint>,
            Vector512<double>, Vector512<long>, Vector512<ulong>>(vector);
    }
    else
    {
        return VectorMath.AtanhSingle<Vector256<float>, Vector256<int>, Vector256<uint>,
            Vector256<double>, Vector256<long>, Vector256<ulong>>(vector);
    }
}

Everything else reviewed looks correct:

  • AtanhDouble / AtanhSingleCoreDouble numerical formulas, sign/infinity/NaN handling, and ConditionalSelect ordering
  • log(1+ratio) instead of log1p(ratio) is safe since the large path guarantees 1+ratio ≥ 3
  • ✅ Polynomial coefficients sourced from AMD AOCL-libm
  • ✅ Ref assembly, Vector64/128/512 entry points, and test tolerance updates

Generated by Code Review for issue #126420 ·

…unit tests

Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/5d519063-12be-4ef4-b760-f38c1b0e57ef

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

@copilot please evaluate and address the feedback

Addressed both feedback items in 046a5e3:

  1. Vector256.Atanh(float) IsHardwareAccelerated check: Added the Vector512.IsHardwareAccelerated branch (matching the pattern used by Asin/Cos/Exp) so it falls back to Vector256<double> when Vector512 isn't hardware-accelerated.

  2. Unit tests: Added AtanhDoubleTest and AtanhSingleTest to all four test files (Vector64/128/256/512Tests.cs) with test data in GenericMathTestMemberData covering NaN, ±0, ±1 (→ ±Infinity), |x|>1 (→ NaN), and standard mathematical constants. All 13,096 tests pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants