@@ -9,6 +9,7 @@ extern "C" {
99#include  < Python.h> 
1010
1111#include  " numpy/arrayobject.h" 
12+ #include  " numpy/halffloat.h" 
1213#include  " numpy/ndarraytypes.h" 
1314#include  " numpy/dtype_api.h" 
1415}
@@ -20,7 +21,7 @@ extern "C" {
2021#include  " casts.h" 
2122#include  " dtype.h" 
2223
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
2425
2526static  NPY_CASTING
2627quad_to_quad_resolve_descriptors (PyObject *NPY_UNUSED (self),
@@ -150,19 +151,21 @@ quad_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const da
150151    return  0 ;
151152}
152153
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
154155struct  my_npy_bool  {}
156+ struct  my_npy_half  {}
155157
156158template <typename  T>
157159struct  NpyType  { typedef  T TYPE; };
158160template <>
159161struct  NpyType <my_npy_bool>{ typedef  npy_bool TYPE; };
162+ struct  NpyType <my_npy_half>{ typedef  npy_half TYPE; };
160163
161164//  Casting from other types to QuadDType
162165
163166template  <typename  T>
164167static  inline  quad_value
165- to_quad (NpyType<T>::TYPE x, QuadBackendType backend);
168+ to_quad (typename   NpyType<T>::TYPE x, QuadBackendType backend);
166169
167170template  <>
168171inline  quad_value
@@ -317,6 +320,21 @@ to_quad<npy_ulonglong>(npy_ulonglong x, QuadBackendType backend)
317320    }
318321    return  result;
319322}
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+ 
320338template  <>
321339inline  quad_value
322340to_quad<float >(float  x, QuadBackendType backend)
@@ -396,10 +414,10 @@ numpy_to_quad_strided_loop_unaligned(PyArrayMethod_Context *context, char *const
396414    size_t  elem_size = (backend == BACKEND_SLEEF) ? sizeof (Sleef_quad) : sizeof (long  double );
397415
398416    while  (N--) {
399-         NpyType<T>::TYPE in_val;
417+         typename   NpyType<T>::TYPE in_val;
400418        quad_value out_val;
401419
402-         memcpy (&in_val, in_ptr, sizeof (NpyType<T>::TYPE));
420+         memcpy (&in_val, in_ptr, sizeof (typename   NpyType<T>::TYPE));
403421        out_val = to_quad<T>(in_val, backend);
404422        memcpy (out_ptr, &out_val, elem_size);
405423
@@ -423,7 +441,7 @@ numpy_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
423441    QuadBackendType backend = descr_out->backend ;
424442
425443    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;
427445        quad_value out_val = to_quad<T>(in_val, backend);
428446
429447        if  (backend == BACKEND_SLEEF) {
@@ -442,7 +460,7 @@ numpy_to_quad_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
442460//  Casting from QuadDType to other types
443461
444462template  <typename  T>
445- static  inline  NpyType<T>::TYPE
463+ static  inline  typename   NpyType<T>::TYPE
446464from_quad (quad_value x, QuadBackendType backend);
447465
448466template  <>
@@ -577,6 +595,18 @@ from_quad<npy_ulonglong>(quad_value x, QuadBackendType backend)
577595    }
578596}
579597
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+ 
580610template  <>
581611inline  float 
582612from_quad<float >(quad_value x, QuadBackendType backend)
@@ -645,8 +675,8 @@ quad_to_numpy_strided_loop_unaligned(PyArrayMethod_Context *context, char *const
645675        quad_value in_val;
646676        memcpy (&in_val, in_ptr, elem_size);
647677
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));
650680
651681        in_ptr += strides[0 ];
652682        out_ptr += strides[1 ];
@@ -676,8 +706,8 @@ quad_to_numpy_strided_loop_aligned(PyArrayMethod_Context *context, char *const d
676706            in_val.longdouble_value  = *(long  double  *)in_ptr;
677707        }
678708
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;
681711
682712        in_ptr += strides[0 ];
683713        out_ptr += strides[1 ];
@@ -784,6 +814,7 @@ init_casts_internal(void)
784814    add_cast_to<npy_ulong>(&PyArray_ULongDType);
785815    add_cast_to<npy_longlong>(&PyArray_LongLongDType);
786816    add_cast_to<npy_ulonglong>(&PyArray_ULongLongDType);
817+     add_cast_to<my_npy_half>(&PyArray_HalfDType);
787818    add_cast_to<float >(&PyArray_FloatDType);
788819    add_cast_to<double >(&PyArray_DoubleDType);
789820    add_cast_to<long  double >(&PyArray_LongDoubleDType);
@@ -799,6 +830,7 @@ init_casts_internal(void)
799830    add_cast_from<npy_ulong>(&PyArray_ULongDType);
800831    add_cast_from<npy_longlong>(&PyArray_LongLongDType);
801832    add_cast_from<npy_ulonglong>(&PyArray_ULongLongDType);
833+     add_cast_from<my_npy_half>(&PyArray_HalfDType);
802834    add_cast_from<float >(&PyArray_FloatDType);
803835    add_cast_from<double >(&PyArray_DoubleDType);
804836    add_cast_from<long  double >(&PyArray_LongDoubleDType);
0 commit comments