Open nerodesu017 opened 3 months ago
Including libm
as a dependency is not an option IIRC. Although not mentioned in the requirements, we want to minimize the use of external dependencies. The closest matching requirement would be: https://github.com/DLR-FT/wasm-interpreter/blob/256e3cd31c7f52033373a5aec69fd8dc5de86fa2/requirements/requirements.sdoc#L18-L26
@wucke13
So what solution would you guys propose?
I' immediately aware of https://docs.rs/libm/latest/libm/ and https://crates.io/crates/num-traits . Num internally relies on libm, but it uses the same names like std::f64, thus it is more familiar. Both have a minimal dependency tree, i.e. libm depends on nothing, and num-traits depends only on libm. Other than that, we could implement these by hand. here would be the most basic example for abs
:
pub fn abs64(x: f64) -> f64 {
f64::from_bits(x.to_bits() & (i64::MAX as u64))
}
pub fn abs32(x: f32) -> f32 {
f32::from_bits(x.to_bits() & (i32::MAX as u32))
}
ceil
and floor
require some comparison with the exponent and the mantissa, should be easy enough. Really the only non-trivial issue is sqrt
. We could write a newton iteration for that, but it is not guaranteed to complete in a fixed time, i.e. it would be a loop with an unstable termination condition. Here I'd much prefer to use the respective hardware instruction.
In short, I think it is mostly feasible to implement this by hand, but I believe it would be wise to tap into num-traits and be done with it.
We agreed to use libm, but not num-crates
As requested by @wucke13 here is the link that talks about some architectures silently altering floats:
https://github.com/bytecodealliance/wasmtime/pull/2251#discussion_r498508646
That is an interesting read. IIUC, the TL;DR of it is: bit representation (and especially the case distinctions) for NaN are not handled identical on all architectures. Hence wasmtime chose to implement these themselves. I'm still in favor of just using libm
for now, and revisit this issue some-time later, as I do not expect immediate issue with this in-determinism w/r/t NaN representations. However, I do not have a strong opinion on this.
Specifically talking about NaNs, I think it is not a critical problem, but I would keep in mind to fix it later in a similar manner to wasmtime.
As the title says, there are a few methods for f32 (and I assume for f64, as well), that are only in the std library:
abs
,ceil
,floor
,trunc
,round
,sqrt
andcopysign
.The only alternative I could find, until now, was the libm library. Sadly, it has a major number of 0, which means breaking changes might appear on any new update. We could lock it at a version or maybe just use from its source what's needed, since licenses are Apache 2 and MIT