NSIMD documentation
Index | Tutorial | FAQ | Contribute | API overview | API reference | Wrapped intrinsics | Modules

IEEE float16 related functions

NSIMD natively supports IEEE float16's. This means that NSIMD provides types and functions to deal with them. When the targeted architecture supports them then NSIMD will use approriate intrinsics otherwise emulation with float32's will be used.

Float16's related functions and types

NSIMD provide the f16 type which represents a IEEE float16. Note that depending on the targeted architecture and the presence of -DFP16 the float16 type can typedefs many different types. Therefore the two following functions are provided and can be used to convert a float16 from/to a float32. These functions preserve NaN's and infinities. When converting from a float32 to a float16 saturation to infinities is performed when the float32 cannot be represented as a float16.

Function signature Availability
f16 nsimd_f32_to_f16(f32 a); C and C++
f32 nsimd_f16_to_f32(f16 a); C and C++
f16 nsimd::f32_to_f16(f32 a); C++ only
f32 nsimd::f16_to_f32(f16 a); C++ only

For loading/storing float16's NSIMD provides other conversion function to/from 16-bits unsigned integers. The integers will hold the IEEE binary representation of the float16's.

Function signature Availability
u16 nsimd_f32_to_u16(f32 a); C and C++
f32 nsimd_u16_to_f32(u16 a); C and C++
u16 nsimd::f32_to_u16(f32 a); C++ only
f32 nsimd::u16_to_f32(u16 a); C++ only

The nsimd_* functions listed above do not use the same linkage type depending on the targeted architecture. When compiling for GPUs the corresponding symbols names are mangled. They use C++ ABI because the float16 type is defined as a C++ class and not as a C struct. We therefore inherit from the implementation of CUDA and HIP/ROCm. Linkage types are listed below.

Function signature CUDA/ROCm Other architectures
f16 nsimd_f32_to_f16(f32 a); C++ linkage C linkage
f32 nsimd_f16_to_f32(f16 a); C++ linkage C linkage
f16 nsimd::f32_to_f16(f32 a); C++ linkage C++ linkage
f32 nsimd::f16_to_f32(f16 a); C++ linkage C++ linkage
u16 nsimd_f32_to_u16(f32 a); C++ linkage C linkage
f32 nsimd_u16_to_f32(u16 a); C++ linkage C linkage
u16 nsimd::f32_to_u16(f32 a); C++ linkage C++ linkage
f32 nsimd::u16_to_f32(u16 a); C++ linkage C++ linkage

It is possible to know at compile time in which situation we are. The NSIMD_C_LINKAGE_FOR_F16 macro if defined means that C linkage is used for nsimd_* functions.