Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 8 additions & 59 deletions src/csrc/dtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,6 @@
#include "constants.hpp"
#include "utilities.h"

static inline int
quad_load(void *x, char *data_ptr, QuadBackendType backend)
{
if (data_ptr == NULL || x == NULL) {
return -1;
}
if (backend == BACKEND_SLEEF) {
*(Sleef_quad *)x = *(Sleef_quad *)data_ptr;
}
else {
*(long double *)x = *(long double *)data_ptr;
}
return 0;
}

static inline int
quad_store(char *data_ptr, void *x, QuadBackendType backend)
{
if (data_ptr == NULL || x == NULL) {
return -1;
}
if (backend == BACKEND_SLEEF) {
*(Sleef_quad *)data_ptr = *(Sleef_quad *)x;
}
else {
*(long double *)data_ptr = *(long double *)x;
}
return 0;
}

QuadPrecDTypeObject *
new_quaddtype_instance(QuadBackendType backend)
{
Expand Down Expand Up @@ -160,13 +130,7 @@ quadprec_setitem(QuadPrecDTypeObject *descr, PyObject *obj, char *dataptr)
}
}

if (quad_store(dataptr, &value->value, descr->backend) < 0) {
Py_DECREF(value);
char error_msg[100];
snprintf(error_msg, sizeof(error_msg), "Invalid memory location %p", (void *)dataptr);
PyErr_SetString(PyExc_ValueError, error_msg);
return -1;
}
quad_value_store(dataptr, &value->value, descr->backend);

Py_DECREF(value);
return 0;
Expand All @@ -179,13 +143,7 @@ quadprec_getitem(QuadPrecDTypeObject *descr, char *dataptr)
if (!new) {
return NULL;
}
if (quad_load(&new->value, dataptr, descr->backend) < 0) {
Py_DECREF(new);
char error_msg[100];
snprintf(error_msg, sizeof(error_msg), "Invalid memory location %p", (void *)dataptr);
PyErr_SetString(PyExc_ValueError, error_msg);
return NULL;
}
quad_value_load_canonical(&new->value, dataptr, descr->backend);
return (PyObject *)new;
}

Expand Down Expand Up @@ -315,9 +273,10 @@ quadprec_fill(void *buffer, npy_intp length, void *arr_)
long double *buf = (long double *)buffer;
long double start = buf[0];
long double delta = buf[1] - start;

char *bytes = (char *)buffer;

for (i = 2; i < length; ++i) {
buf[i] = start + i * delta;
quad_longdouble_store(bytes + i * descr->base.elsize, start + i * delta);
}
}

Expand Down Expand Up @@ -362,13 +321,8 @@ quadprec_scanfunc(FILE *fp, void *dptr, char *ignore, PyArray_Descr *descr_gener
if (err < 0 || *endptr != '\0') {
return 0; /* Return 0 on parse error (no items read) */
}
if (descr->backend == BACKEND_SLEEF) {
*(Sleef_quad *)dptr = val.sleef_value;
}
else {
*(long double *)dptr = val.longdouble_value;
}

quad_value_store(dptr, &val, descr->backend);

return 1; /* Return 1 on success (1 item read) */
}

Expand All @@ -381,12 +335,7 @@ quadprec_fromstr(char *s, void *dptr, char **endptr, PyArray_Descr *descr_generi
if (err < 0) {
return -1;
}
if(descr->backend == BACKEND_SLEEF) {
*(Sleef_quad *)dptr = val.sleef_value;
}
else {
*(long double *)dptr = val.longdouble_value;
}
quad_value_store(dptr, &val, descr->backend);
return 0;
}

Expand Down
17 changes: 11 additions & 6 deletions src/csrc/scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ QuadPrecision_raw_new(QuadBackendType backend)
}
else {
// An 80-bit long double occupies 16 bytes but writes only 10
memset(&new->value, 0, sizeof(new->value));
new->value.longdouble_value = 0.0L;
quad_value_set_longdouble(&new->value, 0.0L);
}
return new;
}
Expand Down Expand Up @@ -760,10 +759,16 @@ QuadPrecision_from_raw_bytes(PyObject *Py_UNUSED(module), PyObject *args)
PyBuffer_Release(&view);
return NULL;
}
unsigned char *dst = (backend == BACKEND_SLEEF)
? (unsigned char *)&self->value.sleef_value
: (unsigned char *)&self->value.longdouble_value;
quad_copy_canonical(dst, (const unsigned char *)view.buf, expected);
unsigned char raw[sizeof(quad_value)];
quad_copy_canonical(raw, (const unsigned char *)view.buf, expected);
if (backend == BACKEND_SLEEF) {
memcpy(&self->value.sleef_value, raw, expected);
}
else {
long double value;
memcpy(&value, raw, expected);
quad_value_set_longdouble(&self->value, value);
}
PyBuffer_Release(&view);
return (PyObject *)self;
}
Expand Down
35 changes: 16 additions & 19 deletions src/csrc/umath/binary_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,17 @@ quad_generic_binop_strided_loop_unaligned(PyArrayMethod_Context *context, char *

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in1, in2, out;
while (N--) {
memcpy(&in1, in1_ptr, elem_size);
memcpy(&in2, in2_ptr, elem_size);
quad_value_load(&in1, in1_ptr, backend);
quad_value_load(&in2, in2_ptr, backend);
if (backend == BACKEND_SLEEF) {
out.sleef_value = sleef_op(&in1.sleef_value, &in2.sleef_value);
}
else {
out.longdouble_value = longdouble_op(&in1.longdouble_value, &in2.longdouble_value);
}
memcpy(out_ptr, &out, elem_size);
quad_value_store(out_ptr, &out, backend);

in1_ptr += in1_stride;
in2_ptr += in2_stride;
Expand Down Expand Up @@ -134,7 +132,8 @@ quad_generic_binop_strided_loop_aligned(PyArrayMethod_Context *context, char *co
*(Sleef_quad *)out_ptr = sleef_op((Sleef_quad *)in1_ptr, (Sleef_quad *)in2_ptr);
}
else {
*(long double *)out_ptr = longdouble_op((long double *)in1_ptr, (long double *)in2_ptr);
quad_longdouble_store(out_ptr,
longdouble_op((long double *)in1_ptr, (long double *)in2_ptr));
}

in1_ptr += in1_stride;
Expand Down Expand Up @@ -222,21 +221,19 @@ quad_generic_binop_2out_strided_loop_unaligned(PyArrayMethod_Context *context, c

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in1, in2, out1, out2;
while (N--) {
memcpy(&in1, in1_ptr, elem_size);
memcpy(&in2, in2_ptr, elem_size);
quad_value_load(&in1, in1_ptr, backend);
quad_value_load(&in2, in2_ptr, backend);
if (backend == BACKEND_SLEEF) {
sleef_op(&in1.sleef_value, &in2.sleef_value, &out1.sleef_value, &out2.sleef_value);
}
else {
longdouble_op(&in1.longdouble_value, &in2.longdouble_value,
&out1.longdouble_value, &out2.longdouble_value);
}
memcpy(out1_ptr, &out1, elem_size);
memcpy(out2_ptr, &out2, elem_size);
quad_value_store(out1_ptr, &out1, backend);
quad_value_store(out2_ptr, &out2, backend);

in1_ptr += in1_stride;
in2_ptr += in2_stride;
Expand Down Expand Up @@ -270,8 +267,10 @@ quad_generic_binop_2out_strided_loop_aligned(PyArrayMethod_Context *context, cha
(Sleef_quad *)out1_ptr, (Sleef_quad *)out2_ptr);
}
else {
longdouble_op((long double *)in1_ptr, (long double *)in2_ptr,
(long double *)out1_ptr, (long double *)out2_ptr);
long double out1, out2;
longdouble_op((long double *)in1_ptr, (long double *)in2_ptr, &out1, &out2);
quad_longdouble_store(out1_ptr, out1);
quad_longdouble_store(out2_ptr, out2);
}

in1_ptr += in1_stride;
Expand Down Expand Up @@ -338,12 +337,10 @@ quad_ldexp_strided_loop_unaligned(PyArrayMethod_Context *context, char *const da

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in1, out;
npy_intp in2_intp; // Platform-native integer (int64 on 64-bit, int32 on 32-bit)
while (N--) {
memcpy(&in1, in1_ptr, elem_size);
quad_value_load(&in1, in1_ptr, backend);
memcpy(&in2_intp, in2_ptr, sizeof(npy_intp));

int exp_value = (int)in2_intp;
Expand All @@ -353,7 +350,7 @@ quad_ldexp_strided_loop_unaligned(PyArrayMethod_Context *context, char *const da
} else {
out.longdouble_value = longdouble_op(&in1.longdouble_value, &exp_value);
}
memcpy(out_ptr, &out, elem_size);
quad_value_store(out_ptr, &out, backend);

in1_ptr += in1_stride;
in2_ptr += in2_stride;
Expand Down Expand Up @@ -387,7 +384,7 @@ quad_ldexp_strided_loop_aligned(PyArrayMethod_Context *context, char *const data
if (backend == BACKEND_SLEEF) {
*(Sleef_quad *)out_ptr = sleef_op((Sleef_quad *)in1_ptr, &exp_value);
} else {
*(long double *)out_ptr = longdouble_op((long double *)in1_ptr, &exp_value);
quad_longdouble_store(out_ptr, longdouble_op((long double *)in1_ptr, &exp_value));
}

in1_ptr += in1_stride;
Expand Down
2 changes: 1 addition & 1 deletion src/csrc/umath/matmul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ naive_matmul_strided_loop(PyArrayMethod_Context *context, char *const data[],
sum += a_val * b_val;
}

memcpy(C_ij, &sum, sizeof(long double));
quad_longdouble_store(C_ij, sum);
}
}
}
Expand Down
29 changes: 13 additions & 16 deletions src/csrc/umath/unary_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,16 @@ quad_generic_unary_op_strided_loop_unaligned(PyArrayMethod_Context *context, cha

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in, out;
while (N--) {
memcpy(&in, in_ptr, elem_size);
quad_value_load(&in, in_ptr, backend);
if (backend == BACKEND_SLEEF) {
out.sleef_value = sleef_op(&in.sleef_value);
}
else {
out.longdouble_value = longdouble_op(&in.longdouble_value);
}
memcpy(out_ptr, &out, elem_size);
quad_value_store(out_ptr, &out, backend);

in_ptr += in_stride;
out_ptr += out_stride;
Expand Down Expand Up @@ -100,7 +98,7 @@ quad_generic_unary_op_strided_loop_aligned(PyArrayMethod_Context *context, char
*(Sleef_quad *)out_ptr = sleef_op((Sleef_quad *)in_ptr);
}
else {
*(long double *)out_ptr = longdouble_op((long double *)in_ptr);
quad_longdouble_store(out_ptr, longdouble_op((long double *)in_ptr));
}
in_ptr += in_stride;
out_ptr += out_stride;
Expand Down Expand Up @@ -321,19 +319,17 @@ quad_generic_unary_op_2out_strided_loop_unaligned(PyArrayMethod_Context *context

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in, out1, out2;
while (N--) {
memcpy(&in, in_ptr, elem_size);
quad_value_load(&in, in_ptr, backend);
if (backend == BACKEND_SLEEF) {
sleef_op(&in.sleef_value, &out1.sleef_value, &out2.sleef_value);
}
else {
longdouble_op(&in.longdouble_value, &out1.longdouble_value, &out2.longdouble_value);
}
memcpy(out1_ptr, &out1, elem_size);
memcpy(out2_ptr, &out2, elem_size);
quad_value_store(out1_ptr, &out1, backend);
quad_value_store(out2_ptr, &out2, backend);

in_ptr += in_stride;
out1_ptr += out1_stride;
Expand Down Expand Up @@ -365,7 +361,10 @@ quad_generic_unary_op_2out_strided_loop_aligned(PyArrayMethod_Context *context,
sleef_op((Sleef_quad *)in_ptr, (Sleef_quad *)out1_ptr, (Sleef_quad *)out2_ptr);
}
else {
longdouble_op((long double *)in_ptr, (long double *)out1_ptr, (long double *)out2_ptr);
long double out1, out2;
longdouble_op((long double *)in_ptr, &out1, &out2);
quad_longdouble_store(out1_ptr, out1);
quad_longdouble_store(out2_ptr, out2);
}
in_ptr += in_stride;
out1_ptr += out1_stride;
Expand Down Expand Up @@ -470,20 +469,18 @@ quad_frexp_strided_loop_unaligned(PyArrayMethod_Context *context, char *const da

QuadPrecDTypeObject *descr = (QuadPrecDTypeObject *)context->descriptors[0];
QuadBackendType backend = descr->backend;
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof(Sleef_quad) : sizeof(long double);

quad_value in, out_mantissa;
int out_exp;

while (N--) {
memcpy(&in, in_ptr, elem_size);
quad_value_load(&in, in_ptr, backend);
if (backend == BACKEND_SLEEF) {
out_mantissa.sleef_value = sleef_op(&in.sleef_value, &out_exp);
}
else {
out_mantissa.longdouble_value = longdouble_op(&in.longdouble_value, &out_exp);
}
memcpy(out_mantissa_ptr, &out_mantissa, elem_size);
quad_value_store(out_mantissa_ptr, &out_mantissa, backend);
memcpy(out_exp_ptr, &out_exp, sizeof(int));

in_ptr += in_stride;
Expand Down Expand Up @@ -520,7 +517,7 @@ quad_frexp_strided_loop_aligned(PyArrayMethod_Context *context, char *const data
}
else {
long double mantissa = longdouble_op((long double *)in_ptr, &out_exp);
memcpy(out_mantissa_ptr, &mantissa, sizeof(long double));
quad_longdouble_store(out_mantissa_ptr, mantissa);
}
memcpy(out_exp_ptr, &out_exp, sizeof(int));

Expand Down
7 changes: 4 additions & 3 deletions src/csrc/utilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ cstring_to_quad_internal(const char *str, const char *start, QuadBackendType bac
}

} else {
out_value->longdouble_value = strtold(str, endptr);
quad_value_set_longdouble(out_value, strtold(str, endptr));
}

if (endptr && *endptr == str) {
Expand Down Expand Up @@ -218,7 +218,8 @@ NumPyOS_ascii_strtoq(const char *s, QuadBackendType backend, quad_value *out_val
out_value->sleef_value = sign > 0 ? QUAD_PRECISION_INF : QUAD_PRECISION_NINF;
}
else {
out_value->longdouble_value = sign > 0 ? strtold("inf", NULL) : strtold("-inf", NULL);
quad_value_set_longdouble(out_value,
sign > 0 ? strtold("inf", NULL) : strtold("-inf", NULL));
}

if (endptr) {
Expand Down Expand Up @@ -252,7 +253,7 @@ NumPyOS_ascii_strtoq(const char *s, QuadBackendType backend, quad_value *out_val
out_value->sleef_value = nan_val;
}
else {
out_value->longdouble_value = sign < 0 ? -nanl("") : nanl("");
quad_value_set_longdouble(out_value, sign < 0 ? -nanl("") : nanl(""));
}

if (endptr) {
Expand Down
Loading
Loading