@@ -14,12 +14,13 @@ extern "C" {
14
14
}
15
15
#include " sleef.h"
16
16
#include " sleefquad.h"
17
- #include < vector>
18
17
19
18
#include " scalar.h"
20
19
#include " casts.h"
21
20
#include " dtype.h"
22
21
22
+ #define NUM_CASTS 29 // 14 to_casts + 14 from_casts + 1 quad_to_quad
23
+
23
24
static NPY_CASTING
24
25
quad_to_quad_resolve_descriptors (PyObject *NPY_UNUSED (self),
25
26
PyArray_DTypeMeta *NPY_UNUSED(dtypes[2 ]),
@@ -51,14 +52,13 @@ quad_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
51
52
char *in_ptr = data[0 ];
52
53
char *out_ptr = data[1 ];
53
54
54
- while (N--) {
55
- Sleef_quad *in = (Sleef_quad *)in_ptr;
56
- Sleef_quad *out = (Sleef_quad *)out_ptr;
57
-
58
- *out = *in;
55
+ npy_intp in_stride = strides[0 ];
56
+ npy_intp out_stride = strides[1 ];
59
57
60
- in_ptr += strides[0 ];
61
- out_ptr += strides[1 ];
58
+ while (N--) {
59
+ memcpy (out_ptr, in_ptr, sizeof (Sleef_quad));
60
+ in_ptr += in_stride;
61
+ out_ptr += out_stride;
62
62
}
63
63
return 0 ;
64
64
}
@@ -172,7 +172,7 @@ numpy_to_quad_resolve_descriptors(PyObject *NPY_UNUSED(self), PyArray_DTypeMeta
172
172
}
173
173
174
174
loop_descrs[0 ] = PyArray_GetDefaultDescr (dtypes[0 ]);
175
- *view_offset = 0 ;
175
+ // *view_offset = 0;
176
176
return NPY_SAFE_CASTING;
177
177
}
178
178
@@ -187,9 +187,12 @@ numpy_to_quad_strided_loop(PyArrayMethod_Context *context, char *const data[],
187
187
char *out_ptr = data[1 ];
188
188
189
189
while (N--) {
190
- T in_val = *(T *)in_ptr;
191
- Sleef_quad *out_val = (Sleef_quad *)out_ptr;
192
- *out_val = to_quad<T>(in_val);
190
+ T in_val;
191
+ Sleef_quad out_val;
192
+
193
+ memcpy (&in_val, in_ptr, sizeof (T));
194
+ out_val = to_quad<T>(in_val);
195
+ memcpy (out_ptr, &out_val, sizeof (Sleef_quad));
193
196
194
197
in_ptr += strides[0 ];
195
198
out_ptr += strides[1 ];
@@ -298,8 +301,8 @@ quad_to_numpy_resolve_descriptors(PyObject *NPY_UNUSED(self), PyArray_DTypeMeta
298
301
loop_descrs[0 ] = given_descrs[0 ];
299
302
300
303
loop_descrs[1 ] = PyArray_GetDefaultDescr (dtypes[1 ]);
301
- *view_offset = 0 ;
302
- return NPY_SAME_KIND_CASTING ;
304
+ // *view_offset = 0;
305
+ return NPY_UNSAFE_CASTING ;
303
306
}
304
307
305
308
template <typename T>
@@ -323,7 +326,16 @@ quad_to_numpy_strided_loop(PyArrayMethod_Context *context, char *const data[],
323
326
return 0 ;
324
327
}
325
328
326
- static std::vector<PyArrayMethod_Spec *> specs;
329
+ static PyArrayMethod_Spec *specs[NUM_CASTS + 1 ]; // +1 for NULL terminator
330
+ static size_t spec_count = 0 ;
331
+
332
+ void
333
+ add_spec (PyArrayMethod_Spec *spec)
334
+ {
335
+ if (spec_count < NUM_CASTS) {
336
+ specs[spec_count++] = spec;
337
+ }
338
+ }
327
339
328
340
// functions to add casts
329
341
template <typename T>
@@ -337,15 +349,16 @@ add_cast_from(PyArray_DTypeMeta *to)
337
349
{NPY_METH_strided_loop, (void *)&quad_to_numpy_strided_loop<T>},
338
350
{0 , nullptr }};
339
351
340
- specs. push_back ( new PyArrayMethod_Spec{
352
+ PyArrayMethod_Spec *spec = new PyArrayMethod_Spec{
341
353
.name = " cast_QuadPrec_to_NumPy" ,
342
354
.nin = 1 ,
343
355
.nout = 1 ,
344
- .casting = NPY_SAME_KIND_CASTING ,
356
+ .casting = NPY_UNSAFE_CASTING ,
345
357
.flags = (NPY_ARRAYMETHOD_FLAGS)0 ,
346
358
.dtypes = dtypes,
347
359
.slots = slots,
348
- });
360
+ };
361
+ add_spec (spec);
349
362
}
350
363
351
364
template <typename T>
@@ -359,34 +372,40 @@ add_cast_to(PyArray_DTypeMeta *from)
359
372
{NPY_METH_strided_loop, (void *)&numpy_to_quad_strided_loop<T>},
360
373
{0 , nullptr }};
361
374
362
- specs. push_back ( new PyArrayMethod_Spec{
375
+ PyArrayMethod_Spec *spec = new PyArrayMethod_Spec{
363
376
.name = " cast_NumPy_to_QuadPrec" ,
364
377
.nin = 1 ,
365
378
.nout = 1 ,
366
379
.casting = NPY_SAFE_CASTING,
367
380
.flags = (NPY_ARRAYMETHOD_FLAGS)0 ,
368
381
.dtypes = dtypes,
369
382
.slots = slots,
370
- });
383
+ };
384
+
385
+ add_spec (spec);
371
386
}
372
387
373
388
PyArrayMethod_Spec **
374
389
init_casts_internal (void )
375
390
{
376
391
PyArray_DTypeMeta **quad2quad_dtypes = new PyArray_DTypeMeta *[2 ]{nullptr , nullptr };
392
+ PyType_Slot *quad2quad_slots = new PyType_Slot[4 ]{
393
+ {NPY_METH_resolve_descriptors, (void *)&quad_to_quad_resolve_descriptors},
394
+ {NPY_METH_strided_loop, (void *)&quad_to_quad_strided_loop},
395
+ {NPY_METH_unaligned_strided_loop, (void *)&quad_to_quad_strided_loop},
396
+ {0 , nullptr }};
377
397
378
- specs. push_back ( new PyArrayMethod_Spec{
398
+ PyArrayMethod_Spec *quad2quad_spec = new PyArrayMethod_Spec{
379
399
.name = " cast_QuadPrec_to_QuadPrec" ,
380
400
.nin = 1 ,
381
401
.nout = 1 ,
382
402
.casting = NPY_SAME_KIND_CASTING,
383
403
.flags = NPY_METH_SUPPORTS_UNALIGNED,
384
404
.dtypes = quad2quad_dtypes,
385
- .slots = new PyType_Slot[4 ]{
386
- {NPY_METH_resolve_descriptors, (void *)&quad_to_quad_resolve_descriptors},
387
- {NPY_METH_strided_loop, (void *)&quad_to_quad_strided_loop},
388
- {NPY_METH_unaligned_strided_loop, (void *)&quad_to_quad_strided_loop},
389
- {0 , NULL }}});
405
+ .slots = quad2quad_slots,
406
+ };
407
+
408
+ add_spec (quad2quad_spec);
390
409
391
410
add_cast_to<npy_bool>(&PyArray_BoolDType);
392
411
add_cast_to<npy_byte>(&PyArray_ByteDType);
@@ -418,8 +437,8 @@ init_casts_internal(void)
418
437
add_cast_from<double >(&PyArray_DoubleDType);
419
438
add_cast_from<long double >(&PyArray_LongDoubleDType);
420
439
421
- specs. push_back ( nullptr ) ;
422
- return specs. data () ;
440
+ specs[spec_count] = nullptr ;
441
+ return specs;
423
442
}
424
443
425
444
PyArrayMethod_Spec **
@@ -428,7 +447,7 @@ init_casts(void)
428
447
try {
429
448
return init_casts_internal ();
430
449
}
431
- catch (const std::exception & e) {
450
+ catch (int e) {
432
451
PyErr_NoMemory ();
433
452
return nullptr ;
434
453
}
@@ -445,5 +464,5 @@ free_casts(void)
445
464
delete cast->slots ;
446
465
delete cast;
447
466
}
448
- specs. clear () ;
467
+ spec_count = 0 ;
449
468
}
0 commit comments