Clarify story on libm bindings
Currently the f32 and f64 types provide a number of functions that are just bindings to libm (e.g. trigonometric functions). There are many unbound functions, however (see https://github.com/rust-lang/rust/pull/25780 for some), which can in theory be added over time. It's unclear, however, whether we want to continue this trend and bind all functions or instead try to move away from libm (one possibility being deprecating existing functionality in favor of an external crate).
It would be nice to have a comprehensive understanding on the functions libm provides (beyond those we bind today) and what our story here should be!
While I’d like to see us move away from libm very much, glibc’s libm has been tuned so much over time it would be very hard to provide comparably accurate, compliant and performant implementations.
On the other hand, there’s also a bunch of functions that could easily be implemented in libcore but are currently bound in libstd. A few examples would be
abs,signum,min,maxand all the rounding functions.I’m also really glad we do not bind more obscure functions as tgamma. I believe that they belong in a crate and not stdlib.
Simonas Kazlauskas at 2015-06-17 08:59:10
Ah yes to be clear I don't think we should reimplement trigonometric functions for example, just perhaps deprecate the in-tree versions for an external set of bindings to libm. The stable usage of the standard library in theory does not need to depend on libm.
Alex Crichton at 2015-06-17 17:53:34
Would it be beneficial to put a trait behind some of these? For example,
abs,min, andmax.Abscould be instd::opsand defined asfn abs<T>(&self) -> T, right? I had trouble with this trying to implement something. I wanted the function to work over all integral types, but there was no way to do this and useabsat the same time.Paul Daniel Faria at 2015-12-09 04:03:44
Triage: I know @japaric has been messing with various aspects of libm, but I don't think it's directly relevant to this issue.
Steve Klabnik at 2018-10-31 15:00:21
For this matter, I do not believe that the GNU math.h is quite as overwhelmingly tuned for all our supported platforms as suggested, and we also have to consider e.g. inconsistency over musl, msvc, darwin, etc. Being able to have these methods be part of our own libm story is very useful, because it allows consistency across Rust and thus coherently const-evaluating these methods.
In addition, having to depend on an external libm at runtime for these means that we run into issues where e.g. we have a SIMD vector type and are forced to scalarize everything, breaking apart the vector into its components, calling the math.h on each component, and reassembling the vector. For those, we can gain significantly by providing not only libm, but equivalents to the much more niche and underdeveloped "libmvec". These are nuances of how Rust code interacts with floating point that runtimes written for C don't try to handle.
This was discussed last week by T-libs, and one of the concerns that was brought up that it is a lot of code to maintain, and it might be a bad idea to just wholesale add every single method from libm, especially for smaller platforms which might get punished by e.g. code size, and duplicate lookup tables for CORDIC or similar. So adopting any of these would only be a clear win if the overhead of calling a library function itself would be higher than the statically inlined code size. We don't necessarily want this, as a result, for big methods which might use huge tables like cos, sin, atan, etc.
Nonetheless, it might be that for certain comparatively "well-behaved" and easy to implement functions that this is acceptable, and T-libs expressed openness to seeing something happen. This is useful for both the aforementioned functions (abs, min, max) and also e.g. ceil, floor, and trunc, where the answer should be fairly obvious and relatively easy to implement.
It is quite probable we don't want to further expand our bindings to libm within std, however, not even for replacing it. As noted,
tgammais... rather "specialty", even in terms of numeric code.In other words, the context for this issue includes issues like
- https://github.com/rust-lang/rust/issues/10087
- https://github.com/rust-lang/rust/issues/50145
- https://github.com/rust-lang/rust/issues/55107
- https://github.com/rust-lang/rust/issues/73920
- https://github.com/rust-lang/portable-simd/issues/76
- https://github.com/rust-lang/portable-simd/issues/109
Jubilee at 2022-03-09 21:03:45