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

(Pre)Proposal: wasi-math #587

Open
oovm opened this issue Mar 4, 2024 · 6 comments
Open

(Pre)Proposal: wasi-math #587

oovm opened this issue Mar 4, 2024 · 6 comments
Labels
feature-request Requests for new WASI APIs

Comments

@oovm
Copy link

oovm commented Mar 4, 2024

I would like to make some comments here: Is it necessary to develop wasi-math?


Motivation

Many people want to use some slightly complex mathematical functions in wasm, but their high-performance implementation is actually not simple, especially in wasm.

So I'm wondering if it's possible to add math functions to the next stage of wasi (in preview3)?

In this case, the host platform can directly use hardware acceleration on platforms that contain corresponding instructions, and use programming implementation on platforms that do not support it.


Goals(MVP)

The initial goal is to achieve the same computing power as Javascript Math.

Including abilities such as large integers, trigonometric functions, inverse trigonometric functions, exponential logarithms, etc.

Non-Goals

  • Already included in WASM
    • min, max
  • The algorithm is extremely simple
    • Fibonacci Sequence, 3n+1
  • Difficult to implement the optimal algorithm
    • Prime number, determine whether it is a prime number

To be discussed

  • The number theory function is a very commonly used function in cryptography.
    • I don’t know what component it should belong to.
    • Mathematics? Cryptography? Or a dedicated number theory proposal?
  • Vector operations, quaternions
    • is very common in games, and I focused on the needs of platforms such as Unity.
@sunfishcode
Copy link
Member

sunfishcode commented Mar 4, 2024

It is possible to add math functions to WASI. It's even possible to add them to Preview 2. I expect the main challenge is to find a clear scope that can be sufficiently motivated.

General-purpose CPUs today typically don't have hardware acceleration for trig/exp/log/etc. functions. x86 does have sin/cos/tan instructions, however it turns out that they're slower than just computing those functions in software. Consequently, the apparent advantage here is just toolchain convenience.

There are decently high-quality open-source implementations of things like trigonometric and exp/log/pow functions available. It is less convenient for toolchains to integrate them, however many toolchains today are able to do this. And in return, there are significant advantages to having toolchains do this.

Today's JavaScript engines typically don't implement correct rounding (and indeed, are not required by the spec to do so), so results will often differ in the last digit or so. And, the performance can vary significantly between platforms. Having toolchains bundle their own implementations avoids both of these problems.

And, for some applications, today's JavaScript engines' trig functions compute to a level of precision that is greater than needed, and as a result are slower than they'd need to be. Having toolchains provide their own algorithms gives them the ability to make their own speed/precision tradeoffs, and in a way that's deterministic for a compiled Wasm. And it doesn't require Wasm or WASI to include a specification for reduced-precision math, which can be pretty tricky. Naive attempts can break important symmetries like cos(-x) = cos(x) or invariants like sin(x) <= 1, and different use cases need different things (for example, some applications care about sin(x) for really big values of x, while others don't).

In summary, what's needed here is for someone to propose a specific scope for what should be included, what the precision and determinism requirements should look like, and what the performance expectations should be.

@oovm
Copy link
Author

oovm commented Mar 5, 2024

Regarding the balance between accuracy and speed, many languages have a mode called fast-math, which guarantees accuracy by default and speed in fast mode.

The following options are available:

Keep both

Just like wasi:random has both a safe but slower version and a fast but unsafe version, it is possible to have both math and fast-math interfaces at the same time

Shortcoming

There is only one correct answer, but there are many approximate answers, each with different trade-offs and application scenarios. In fact, there may not be a fast-math version that can satisfy all users.

Moreover, fast-math does not have various strict IEEE standards, and there may be differences in various programming languages.

Fallback Mechanism

We don’t know yet how this mechanism will work, and it may add unnecessary complexity.

Only keep high-precision version

Practical factors

Although the accuracy provided by js is already excessive in most cases, when considering applications such as physical simulation (such as three-body motion simulation demo), a high-precision correct version is still needed.

Size factor

Compared with the fast, accuracy-sacrifice version, the correct, high-precision algorithm will require a lot more binary code.

So I think letting the host bear this cost is a better trade-off.

If users need fast-math, they can choose the appropriate version in each language and according to their own ecology.

@sunfishcode sunfishcode added the feature-request Requests for new WASI APIs label Mar 15, 2024
@spotandjake
Copy link

spotandjake commented Dec 21, 2024

I have a few thoughts relating to this:
Component Model Overhead:
Given wasi proposals are going to be using the component model there is overhead from the shared nothing nature this isn't normally an issue when it comes to system operations as the time spent waiting for the operation to take place outweighs any conversions happening between the host and the guest, but in the case of functions where performance really does matter this could be an issue, Now normally only numbers would be being passed back and forth here which are pass by value eliminating the copy overhead but there could still be conversion overhead (still unlikely) but I think it's something that needs to be considered.

What should a math library include:
When I was building grains number library, I certainly would have loved having something like this especially when it came time to implement the trig functions and other advanced functions such as a floating point power function, so I certainly think these need to be included for this interface to be helpful most other functions are rather trivial to implement.

Does it really make sense to have this be a wasi interface:
My final thought is really I don't know if this makes sense as a system interface compared to allowing the developer to just compose together their component with another math library using wac? This doesn't require any system interactions (as noted the hardware instructions are not really faster) so we are not losing any capabilities, letting the developer handle it would let them address their specific needs for their specific use case.

@oovm
Copy link
Author

oovm commented Dec 23, 2024

My consideration is mainly two application scenarios

  1. The first is the case of a host function, in which the function is passed in and called by the host
    The libc or standard library linked by the host already has a basic math library, which does not cause too much extra work
  2. The second is the case of a guest function, where the host may be resource-constrained and unable to provide such an interface, or only provides an old wasm runtime
    Then in the distant future, the optimizer can link to the implementation of a polyfill library and perform cross-component link time optimization to inline them

No matter which solution is adopted, it makes sense to write a set of interfaces with wit first.

I defined some of my own wit libraries here, all functions are divided into f32 and f64 versions.

@oovm
Copy link
Author

oovm commented Dec 23, 2024

A potentially controversial point is whether to include bigint. My main considerations are:

  1. Already included in js, no new implementation required
  2. Cryptography library depends it
  3. Handwritten wasm implementation may be difficult to implement FFT, NTT hardware acceleration

What is less certain is whether there will be a wasm:js-bigint proposal similar to wasm:js-string, in which case there is competition.

From the perspective of polyfill, I suggest adding this interface to make it compatible with old wasm devices.


By the way, I think wasi polyfill will be the norm for quite a long time

It is convenient to use jco map to do this, I now use the following rules:

wasi:*=@bytecodealliance/preview2-shim/*
wasi:math/*=@valkyrie-language/math-shim/*
wasi:webgpu/*=@valkyrie-language/webgpu-shim/*
valkyrie:image/*=@valkyrie-language/image-shim/*
valkyrie:dom/*=@valkyrie-language/dom-shim/*

@programmerjake
Copy link
Contributor

programmerjake commented Dec 23, 2024

A potentially controversial point is whether to include bigint. My main considerations are:

  1. It is dependent on cryptography

assuming you meant that cryptography is dependent on bigint. bigint implementations for cryptography are quite different than bigint implementations for general arithmetic, since they have to use different often-slower algorithms to prevent timing side-channels (leaking the secret information you're processing by being able to observe how long it takes over the network).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Requests for new WASI APIs
Projects
None yet
Development

No branches or pull requests

4 participants