@@ -9,6 +9,7 @@ extern "C" {
9
9
#include < Python.h>
10
10
11
11
#include " numpy/arrayobject.h"
12
+ #include " numpy/halffloat.h"
12
13
#include " numpy/ndarraytypes.h"
13
14
#include " numpy/dtype_api.h"
14
15
}
@@ -20,7 +21,7 @@ extern "C" {
20
21
#include " casts.h"
21
22
#include " dtype.h"
22
23
23
- #define NUM_CASTS 31 // 15 to_casts + 15 from_casts + 1 quad_to_quad
24
+ #define NUM_CASTS 33 // 16 to_casts + 16 from_casts + 1 quad_to_quad
24
25
25
26
static NPY_CASTING
26
27
quad_to_quad_resolve_descriptors (PyObject *NPY_UNUSED (self),
@@ -150,19 +151,21 @@ quad_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const da
150
151
return 0 ;
151
152
}
152
153
153
- // Template magic to ensure npy_bool and npy_ubyte do not alias in templates
154
+ // Template magic to ensure npy_bool/npy_ubyte and npy_half/npy_ushort do not alias in templates
154
155
struct my_npy_bool {}
156
+ struct my_npy_half {}
155
157
156
158
template <typename T>
157
159
struct NpyType { typedef T TYPE; };
158
160
template <>
159
161
struct NpyType <my_npy_bool>{ typedef npy_bool TYPE; };
162
+ struct NpyType <my_npy_half>{ typedef npy_half TYPE; };
160
163
161
164
// Casting from other types to QuadDType
162
165
163
166
template <typename T>
164
167
static inline quad_value
165
- to_quad (NpyType<T>::TYPE x, QuadBackendType backend);
168
+ to_quad (typename NpyType<T>::TYPE x, QuadBackendType backend);
166
169
167
170
template <>
168
171
inline quad_value
@@ -317,6 +320,21 @@ to_quad<npy_ulonglong>(npy_ulonglong x, QuadBackendType backend)
317
320
}
318
321
return result;
319
322
}
323
+
324
+ template <>
325
+ inline quad_value
326
+ to_quad<my_npy_half>(npy_half x, QuadBackendType backend)
327
+ {
328
+ quad_value result;
329
+ if (backend == BACKEND_SLEEF) {
330
+ result.sleef_value = Sleef_cast_from_doubleq1 (npy_half_to_double (x));
331
+ }
332
+ else {
333
+ result.longdouble_value = (long double )npy_half_to_double (x);
334
+ }
335
+ return result;
336
+ }
337
+
320
338
template <>
321
339
inline quad_value
322
340
to_quad<float >(float x, QuadBackendType backend)
@@ -396,10 +414,10 @@ numpy_to_quad_strided_loop_unaligned(PyArrayMethod_Context *context, char *const
396
414
size_t elem_size = (backend == BACKEND_SLEEF) ? sizeof (Sleef_quad) : sizeof (long double );
397
415
398
416
while (N--) {
399
- NpyType<T>::TYPE in_val;
417
+ typename NpyType<T>::TYPE in_val;
400
418
quad_value out_val;
401
419
402
- memcpy (&in_val, in_ptr, sizeof (NpyType<T>::TYPE));
420
+ memcpy (&in_val, in_ptr, sizeof (typename NpyType<T>::TYPE));
403
421
out_val = to_quad<T>(in_val, backend);
404
422
memcpy (out_ptr, &out_val, elem_size);
405
423
@@ -423,7 +441,7 @@ numpy_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
423
441
QuadBackendType backend = descr_out->backend ;
424
442
425
443
while (N--) {
426
- NpyType<T>::TYPE in_val = *(NpyType<T>::TYPE *)in_ptr;
444
+ typename NpyType<T>::TYPE in_val = *(typename NpyType<T>::TYPE *)in_ptr;
427
445
quad_value out_val = to_quad<T>(in_val, backend);
428
446
429
447
if (backend == BACKEND_SLEEF) {
@@ -442,7 +460,7 @@ numpy_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
442
460
// Casting from QuadDType to other types
443
461
444
462
template <typename T>
445
- static inline NpyType<T>::TYPE
463
+ static inline typename NpyType<T>::TYPE
446
464
from_quad (quad_value x, QuadBackendType backend);
447
465
448
466
template <>
@@ -577,6 +595,18 @@ from_quad<npy_ulonglong>(quad_value x, QuadBackendType backend)
577
595
}
578
596
}
579
597
598
+ template <>
599
+ inline npy_half
600
+ from_quad<my_npy_half>(quad_value x, QuadBackendType backend)
601
+ {
602
+ if (backend == BACKEND_SLEEF) {
603
+ return npy_double_to_half (Sleef_cast_to_doubleq1 (x.sleef_value ));
604
+ }
605
+ else {
606
+ return npy_double_to_half ((double )x.longdouble_value );
607
+ }
608
+ }
609
+
580
610
template <>
581
611
inline float
582
612
from_quad<float >(quad_value x, QuadBackendType backend)
@@ -645,8 +675,8 @@ quad_to_numpy_strided_loop_unaligned(PyArrayMethod_Context *context, char *const
645
675
quad_value in_val;
646
676
memcpy (&in_val, in_ptr, elem_size);
647
677
648
- NpyType<T>::TYPE out_val = from_quad<T>(in_val, backend);
649
- memcpy (out_ptr, &out_val, sizeof (NpyType<T>::TYPE));
678
+ typename NpyType<T>::TYPE out_val = from_quad<T>(in_val, backend);
679
+ memcpy (out_ptr, &out_val, sizeof (typename NpyType<T>::TYPE));
650
680
651
681
in_ptr += strides[0 ];
652
682
out_ptr += strides[1 ];
@@ -676,8 +706,8 @@ quad_to_numpy_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
676
706
in_val.longdouble_value = *(long double *)in_ptr;
677
707
}
678
708
679
- NpyType<T>::TYPE out_val = from_quad<T>(in_val, backend);
680
- *(NpyType<T>::TYPE *)(out_ptr) = out_val;
709
+ typename NpyType<T>::TYPE out_val = from_quad<T>(in_val, backend);
710
+ *(typename NpyType<T>::TYPE *)(out_ptr) = out_val;
681
711
682
712
in_ptr += strides[0 ];
683
713
out_ptr += strides[1 ];
@@ -784,6 +814,7 @@ init_casts_internal(void)
784
814
add_cast_to<npy_ulong>(&PyArray_ULongDType);
785
815
add_cast_to<npy_longlong>(&PyArray_LongLongDType);
786
816
add_cast_to<npy_ulonglong>(&PyArray_ULongLongDType);
817
+ add_cast_to<my_npy_half>(&PyArray_HalfDType);
787
818
add_cast_to<float >(&PyArray_FloatDType);
788
819
add_cast_to<double >(&PyArray_DoubleDType);
789
820
add_cast_to<long double >(&PyArray_LongDoubleDType);
@@ -799,6 +830,7 @@ init_casts_internal(void)
799
830
add_cast_from<npy_ulong>(&PyArray_ULongDType);
800
831
add_cast_from<npy_longlong>(&PyArray_LongLongDType);
801
832
add_cast_from<npy_ulonglong>(&PyArray_ULongLongDType);
833
+ add_cast_from<my_npy_half>(&PyArray_HalfDType);
802
834
add_cast_from<float >(&PyArray_FloatDType);
803
835
add_cast_from<double >(&PyArray_DoubleDType);
804
836
add_cast_from<long double >(&PyArray_LongDoubleDType);
0 commit comments