-
-
Notifications
You must be signed in to change notification settings - Fork 9
Implement sign, sigbit, and copysign ufuncs and extend unary op tests #118
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
base: main
Are you sure you want to change the base?
Conversation
Ideally, I'd also like to add signbit, but I'm unsure about how to implement it for sleef |
So there is a way to extract sign bit from sleef_quad value, I used that in static inline int32_t
quad_signbit(Sleef_quad *op)
{
union
{
Sleef_quad q;
struct
{
uint64_t lo;
uint64_t hi;
} i;
} u;
u.q = *op;
// Sign bit is the MSB of the high 64 bits
return (u.i.hi >> 63) != 0;
} |
Is the ordering of hi and lo guaranteed independent of endianness? |
Good question, so typically Little-Endian (x86, x86_64, ARM64 in little-endian mode) are widely used and supported and compatible (I think GitHub CI uses these only). For Big-Endian (PowerPC, SPARC, some ARM) the current will fail One way is to use compile-time directives to pick endianness but they are not standardised across compilers and build systems although C++20 has static inline int32_t
quad_signbit(Sleef_quad *op)
{
union {
Sleef_quad q;
unsigned char bytes[16];
} u;
u.q = *op;
if constexpr (std::endian::native == std::endian::big) {
return (u.bytes[0] & 0x80) != 0; // Sign bit in first byte
} else if constexpr (std::endian::native == std::endian::little) {
return (u.bytes[15] & 0x80) != 0; // Sign bit in last byte
}
} More simpler and directIf you want then one other simpler and portable method could be using sleef's static inline int32_t
quad_signbit(Sleef_quad *op)
{
Sleef_quad one = Sleef_strtoq("1.0", NULL);
Sleef_quad result = Sleef_copysignq1(one, *op);
Sleef_quad zero = Sleef_strtoq("0.0", NULL);
return Sleef_icmpltq1(result, zero);
} |
With that I'll also suggest when writing pytest tests, use string based inputs (casting from double sometimes give precision issues) |
We test little endian architectures in the numpy CI using PPC64le QEMU emulation. It's slow but it at least lets you do a real end-to-end test. |
I'll start with the copysign-based implementation that @SwayamInSync suggested - once we have endianness testing in CI I'd be happy to replace it with the binary one |
6ffcdca adds dispatch support for (quad) -> bool ufunc "properties" like signbit, which should open the way to support |
Progress on #111
sign
,signbit
, andcopysign
ufuncsconst
annotations to the ops implementations