Open benaadams opened 1 year ago
Tagging subscribers to this area: @dotnet/area-system-numerics See info in area-owners.md if you want to be subscribed.
Author: | benaadams |
---|---|
Assignees: | - |
Labels: | `api-suggestion`, `area-System.Numerics` |
Milestone: | - |
This is one where I'm not convinced providing it as part of the BCL is good or necessary.
In the case of Int128/UInt128, there is a reasonable expectation that the runtime provide the types because Int128/UInt128
are often defined as "ABI primitives" with specialized rules for layout and calling convention. This means, simply put, they are not something that can be provided by an external library. This coupled with there being many cases where hardware acceleration can light up and where specialized APIs might be considered for exposure means that it was a good fit for the BCL, particularly in the context of the new generic math features that allowed it to be exposed without dedicated language support and the sheer number of requests we had gotten over the years.
However, in the case of Int256/UInt256, we really have none of those considerations. They are not ABI primitives and don't really get any "specialized APIs or optimizations" that cannot be filled by some external library. This coupled with the new language features that support generic math and the various hardware intrinsics that allow users to perform manual optimization of their types reduces this further. It's also worth noting that while ~3200 questions related to the type isn't "small", per say, it isn't necessarily representative of the feature being hugely necessary or impactful either and is nowhere near the volume of requests and asks that exist for 128-bit integers.
Because of this, I don't expect we'd be willing to expose these types as part of the BCL, and certainly not part of the System
namespace, at this point in time. I'm certainly open to revisiting this in the future, seeing more data as to the usage of these types, etc. I'd also like for us to potentially explore if there are optimizations or modifications we can make to BigInteger
to improve its performance and reduce the gap that exists between it and some Int256
/UInt256
.
I'd also welcome someone providing their own external implementation and providing it via a NuGet package.
And I'd like to call out, as an idea, that there are a few types people have suggested over the years, like these ones, that I can't see us providing within the BCL, but where they might benefit from having some "unofficially official" 3rd party source. If enough people are interested, I'd be willing to coordinate on creating a repository and going through the necessary steps of getting it into the .NET Foundation, etc. Such an endeavor would be "unofficial", it would be out of box, not part of dotnet/runtime
, and entirely "3rd party". It would ultimately just be a centralized location for such types, extensions, or other optimized numeric algorithms and utilities. There would be a slight bonus that one of the current numerics/intrinsics area owners would be willing to help with API design considerations and code review in their spare time.
This issue has been marked needs-author-action
and may be missing some important information.
@tannergooding As an option if this is something that can't go into the runtime, the .NET Community Toolkit could also be used. It's sort of "in between" in that it's not part of the runtime but it's still first party and officially supported (ie. it's published and maintained by Microsoft). It's also already part of the .NET Foundation. For instance, we could potentially experiment with adding a new "CommunityToolkit.Numerics" package (or adding APIs to an existing one), and use that as the home for APIs such as this one, Complex<T>
in case it didn't get past API review, etc. 🙂
@Sergio0694, I appreciate the offer and it's something that might be worth exploring.
However, I'm also not convinced that's a good idea. One general issue that is worth addressing is the perception that things must be published and maintained by Microsoft. Saying it's not a right fit for the BCL and then turning around and throwing it in some other officially maintained thing doesn't make any progress towards fixing the underlying perception issues that things must be provided by Microsoft. There is also the factor that it being maintained by Microsoft implies a level of support and given many of these types may require deep domain expertise/knowledge that may not exist or be available on the team maintaining the community toolkit.
I think it would be altogether better and healthier for the .NET ecosystem for us to make progress towards something that is truly 3rd party. There would be benefit for some minimal effort around getting such projects started, and ensuring project maintainers understand the general API design rules/considerations we strive to follow in the BCL. Such projects having a relationship, of any kind, with the maintainers of the official APIs likewise benefits both sides of the board.
-- I'm thinking about this from multiple perspectives. One is from the perspective of being an official maintainer for various APIs that ship in box with .NET and understanding what likely will or will not pass API review as well as the general direction that I think would best benefit the "areas" I help maintain.
However, there is another equally important perspective from being an independent .NET OSS maintainer as well as being part of the .NET Foundation project/maintainers committees (all of which are not related to the work I do on dotnet as part of my employment).
When taking all of this into account, I don't think this is something that would pass API review at this time. However, I also see the benefit of having such an API and ensuring there is some common location people might be able to go and find this type or related types. Then accounting for the known perception issues that many people want to work towards resolving and the domain expertise required to maintain such APIs, I come to the conclusion that something completely 3rd party that is started and maintained by people passionate about this space is the right direction. Getting things setup, ensuring it still has that .NET BCL look and feel, and similar is something that I can then offer assistance on from all my perspectives.
However, in the case of Int256/UInt256, we really have none of those considerations. They are not ABI primitives and don't really get any "specialized APIs or optimizations" that cannot be filled by some external library.
Except to be implemented well they need ADC
, ADCX
and ADOX
which have previously been rejected as too complicated to surface and optimize https://github.com/dotnet/runtime/issues/72423
ADCX
and ADOX
have been introduced in combination with MULX
to maintain independent carry chains so large integer multiplication can be parrallelised: Intel: New Instructions Supporting Large Integer Arithmetic and Intel: Large Integer Squaring so they cannot be easily written in C# directly (third column):
Those are cases where the JIT needs to start with recognizing the relevant non-intrinsic pattern and where we may want to revisit such a intrinsic APIs in the future, particularly with the improvements the JIT has received since the last time we looked.
Noting that for https://github.com/dotnet/runtime/issues/72423 in particular, we didn't reject the proposal. It was closed because there wasn't an API proposal there.
If someone opened a new proposal following the appropriate template, we could bring it to API review.
The difficult part is really in doing the JIT work and that the API shape may change slightly depending on what is "optimal" for the JIT.
Noting that for #72423 in particular, we didn't reject the proposal. It was closed because there wasn't an API proposal there.
If someone opened a new proposal following the appropriate template, we could bring it to API review.
The difficult part is really in doing the JIT work and that the API shape may change slightly depending on what is "optimal" for the JIT.
Added proposal https://github.com/dotnet/runtime/issues/80674
Also related to #12221 because both issues involve scenarios that require large data types (for e.g. machine learning, big data / HPC, blockchains, etc.)
We are happy to make https://github.com/NethermindEth/int256 the high performance Int256/UInt256 .net library, we plan keep working at it and happy to accept external contributions, like great work of @benaadams .
I agree that having https://github.com/dotnet/runtime/issues/80674 would be great for optimizing multiplication.
Background and motivation
256 bit integers are becoming more commonly used with 3,189 questions on StackOverflow and use in .NET for example in the application NethermindEth and library Nethereum.
While BigInteger can be used a dedicated type can provide x14 gains and much lower memory usage than BigInteger through not needing to use an arrays to represent data. The implementation can also achieve x2.5 gains using Avx2 vs a software implementation although the approach starts to become exotic https://github.com/NethermindEth/int256/pull/24
API Proposal
API Usage
Alternative Designs
No response
Risks
No response