Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/8.0] Vectorize TensorPrimitives APIs #93746

Merged
merged 30 commits into from
Oct 20, 2023

Conversation

michaelgsharp
Copy link
Member

@michaelgsharp michaelgsharp commented Oct 19, 2023

Backporting updates to the System.Numerics.Tensors packages. This change adds in missing vectorization.

Customer Impact

The Tensors code adds in some missing math features that will be able to be hardware accelerated increasing the performance.

Testing

All new API's have automated testing.

Risk

Risk is very low. The Tensors package hasn't been shipped for many releases, so these changes shouldn't affect anyone. And since we aren't changing existing API's, new automated testing should be enough to mitigated any risks, and since this is basically just adding in vectorization, no functionality is changing.

@ghost
Copy link

ghost commented Oct 19, 2023

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

Issue Details

Backporting updates to the System.Numerics.Tensors packages. This change adds in missing vectorization.

Customer Impact
The Tensors code adds in some missing math features that will be able to be hardware accelerated increasing the performance.

Testing
All new API's have automated testing.

Risk
Risk should be minimal to none. The Tensors package hasn't been shipped for many releases, so these changes shouldn't affect anyone. And since we aren't changing existing API's, new automated testing should be enough to mitigated any risks, and since this is basically just adding in vectorization, no functionality is changing.

Author: michaelgsharp
Assignees: michaelgsharp
Labels:

area-System.Numerics

Milestone: -

@michaelgsharp
Copy link
Member Author

@ericstj @jeffhandley here is the backport PR for Tensors minus the commit from my current PR that will be added as soon as its merged. Can you please approve it.

@artl93 please give it your ack.

@artl93
Copy link
Contributor

artl93 commented Oct 19, 2023

@michaelgsharp - ack.

@carlossanlop
Copy link
Member

When ready, please send an email to Tactics requesting approval. Friendly reminder that we need this merged before 4pm tomorrow Friday 20th to ensure it goes into GA.

stephentoub and others added 20 commits October 20, 2023 01:07
Vector{128/256/512} all provide Abs; no need to do this manually.
…92576)

Change a few of the static abstract interface methods to be virtual, as most implementations throw from these methods; we can consolidate that throwing to the base.
* Normalize some test naming

* Alphabetize tests

* Improve mistmatched length tests with all positions of the shorter tensor

* Alphabetize methods in TensorPrimitives.cs
* Vectorize TensorPrimitives.Min/Max{Magnitude}

* Use AdvSimd.Max/Min

* Rename some parameters/locals for consistency

* Improve HorizontalAggregate

* Move a few helpers

* Avoid scalar path for returning found NaN
…ng elements (dotnet#92672)

* Update TensorPrimitives.CosineSimilarity to vectorize handling of remaining elements

* Vectorize remainder handling for Aggregate helpers
* Flesh out TensorPrimitives XML docs

* Address PR feedback

- Remove use of FusedMultiplyAdd from all but CosineSimilarity
- Remove comments about platform/OS-specific behavior from Add/AddMultiply/Subtract/Multiply/MultiplyAdd/Divide/Negate
- Loosen comments about NaN and which exact one is returned

* Address PR feedback
Some operations would produce incorrect results if the same span was passed as both an input and an output.  When vectorization was employed but the span's length wasn't a perfect multiple of a vector, we'd do the standard trick of performing one last operation on the last vector's worth of data; however, that relies on the operation being idempotent, and if a previous operation has overwritten input with a new value due to the same memory being used for input and output, some operations won't be idempotent.  This fixes that by masking off the already processed elements.  It adds tests to validate in-place use works, and it updates the docs to carve out this valid overlapping.
* Vectorize TensorPrimitives.ConvertToSingle

* Address PR feedback
* Add a way to support operations that can't be vectorized on netstandard

* Updating TensorPrimitives.Log2 to be vectorized on .NET Core

* Update src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Ensure we do an arithmetic right shift in the Log2 vectorization

* Ensure the code can compile on .NET 7

* Ensure that edge cases are properly handled and don't resolve to `x`

* Ensure that Log2 special results are explicitly handled.

---------

Co-authored-by: Stephen Toub <stoub@microsoft.com>
…otnet#92953)

Failing test: `System.Numerics.Tensors.Tests.TensorPrimitivesTests.ConvertToHalf_SpecialValues`

Issue: dotnet#92885
)

* Adding a vectorized implementation of TensorPrimitives.Log

* Make sure to hit Ctrl+S
* Vectorize TensorPrimitives.Exp

* Update src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.netstandard.cs
…et#93029)

* Vectorize TensorPrimitives.Sigmoid and TensorPrimitives.SoftMax

- Adds a SigmoidOperator that just wraps the ExpOperator
- Vectorizes both passes of SoftMax, on top of ExpOperator. Simplest way to do this was to augment the existing InvokeSpanScalarIntoSpan to take a transform operator.
- In doing so, found some naming inconsistencies I'd previously introduced, so I did some automatic renaming to make things more consistent.
- Added XML comments to all the internal/private surface area.
- Fleshes out some tests (and test values).

* Disable tests on mono

* Address PR feedback
* Vectorize TensorPrimitives.Tanh/Cosh/Sinh

Tanh and Cosh are based on AOCL-LibM.

AOCL-LibM doesn't appear to have a sinh implementation, so this Sinh is just based on the sinh formula based on exp(x).

I also augmented the tests further, including:
- Added more tests for sinh/cosh/tanh
- Add an equality routine that supports comparing larger values with a tolerance
- Tightened the tolerance for most functions
- Changed some tests to be theories to be consistent with style elsewhere in the tests
- Fixed some use of Math to be MathF

* Remove unnecessary special-handling path from cosh

* Remove unnecessary special-handling path from tanh

* Redo sinh based on cosh

* Address PR feedback
stephentoub and others added 9 commits October 20, 2023 01:07
… value (dotnet#93169)

* Fix TensorPrimitives.IndexOfXx corner-case when first element is seed value

Found as part of adding more tests for Min/Max{Magnitude} to validate they match their IndexOfXx variants.

* Address PR feedback
… tores (dotnet#93296)

* Improve a vector implementation to support alignment and non-temporal stores

* Fix a build error and mark a couple methods as AggressiveInlining

* Fix the remaining block count computation

* Ensure overlapping for small data on the V256/512 is handled

* Ensure we only go down the vectorized path when supported for netstandard
…rPrimitives operations (dotnet#93409)

* Update InvokeSpanSpanIntoSpan<TBinaryOperator> for TensorPrimitives to use the better SIMD algorithm

* Update InvokeSpanScalarIntoSpan<TTransformOperator, TBinaryOperator> for TensorPrimitives to use the better SIMD algorithm

* Update InvokeSpanSpanSpanIntoSpan<TTernaryOperator> for TensorPrimitives to use the better SIMD algorithm

* Update InvokeSpanSpanScalarIntoSpan<TTernaryOperator> for TensorPrimitives to use the better SIMD algorithm

* Update InvokeSpanScalarSpanIntoSpan<TTernaryOperator> for TensorPrimitives to use the better SIMD algorithm

* Improve codegen slightly by using case 0, rather than default

* Adjust the canAlign check to be latter, to reduce branch count for data under the threshold

* Add a comment explaining the NonTemporalByteThreshold

* Make sure xTransformOp.CanVectorize is checked on .NET Standard
…es operations (dotnet#93695)

* Improve the handling of the IAggregationOperator implementations

* Update Aggregate<TTransformOperator, TAggregationOperator> for TensorPrimitives to use the better SIMD algorithm

* Update Aggregate<TBinaryOperator, TAggregationOperator> for TensorPrimitives to use the better SIMD algorithm

* Respond to PR feedback
* resolved merge conflicts

* net core full done

* minor code cleanup

* NetStandard and PR fixes.

* minor pr changes

* Fix IndexOfMaxMagnitudeOperator

* Fix IndexOfMaxMagnitudeOperator on netcore

* updates from PR comments

* netcore fixed

* net standard updated

* add reference assembly exclusions

* made naive approach better

* resolved PR comments

* minor comment changes

* minor formatting fixes

* added inlining

* fixes from PR comments

* comments from pr

* fixed spacing

---------

Co-authored-by: Eric StJohn <ericstj@microsoft.com>
@ericstj ericstj changed the title Tensors backport [release/8.0] Vectorize TensorPrimitives APIs Oct 20, 2023
@jeffhandley jeffhandley added the Servicing-consider Issue for next servicing release review label Oct 20, 2023
@carlossanlop carlossanlop added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Oct 20, 2023
@carlossanlop
Copy link
Member

Approved by Tactics via email.
CI is green. :shipit:

@carlossanlop carlossanlop merged commit 8262af2 into dotnet:release/8.0 Oct 20, 2023
174 of 179 checks passed
@ghost ghost locked as resolved and limited conversation to collaborators Nov 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Numerics Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants