1//! A crate that provides support for half-precision 16-bit floating point types.
2//!
3//! This crate provides the [`f16`] type, which is an implementation of the IEEE 754-2008 standard
4//! [`binary16`] a.k.a `half` floating point type. This 16-bit floating point type is intended for
5//! efficient storage where the full range and precision of a larger floating point value is not
6//! required. This is especially useful for image storage formats.
7//!
8//! This crate also provides a [`bf16`] type, an alternative 16-bit floating point format. The
9//! [`bfloat16`] format is a truncated IEEE 754 standard `binary32` float that preserves the
10//! exponent to allow the same range as [`f32`] but with only 8 bits of precision (instead of 11
11//! bits for [`f16`]). See the [`bf16`] type for details.
12//!
13//! Because [`f16`] and [`bf16`] are primarily for efficient storage, floating point operations such
14//! as addition, multiplication, etc. are not implemented by hardware. While this crate does provide
15//! the appropriate trait implementations for basic operations, they each convert the value to
16//! [`f32`] before performing the operation and then back afterward. When performing complex
17//! arithmetic, manually convert to and from [`f32`] before and after to reduce repeated conversions
18//! for each operation.
19//!
20//! This crate also provides a [`slice`][mod@slice] module for zero-copy in-place conversions of
21//! [`u16`] slices to both [`f16`] and [`bf16`], as well as efficient vectorized conversions of
22//! larger buffers of floating point values to and from these half formats.
23//!
24//! The crate uses `#[no_std]` by default, so can be used in embedded environments without using the
25//! Rust [`std`] library. A `std` feature to enable support for the standard library is available,
26//! see the [Cargo Features](#cargo-features) section below.
27//!
28//! A [`prelude`] module is provided for easy importing of available utility traits.
29//!
30//! # Cargo Features
31//!
32//! This crate supports a number of optional cargo features. None of these features are enabled by
33//! default, even `std`.
34//!
35//! - **`use-intrinsics`** -- Use [`core::arch`] hardware intrinsics for `f16` and `bf16` conversions
36//! if available on the compiler target. This feature currently only works on nightly Rust
37//! until the corresponding intrinsics are stabilized.
38//!
39//! When this feature is enabled and the hardware supports it, the functions and traits in the
40//! [`slice`][mod@slice] module will use vectorized SIMD intructions for increased efficiency.
41//!
42//! By default, without this feature, conversions are done only in software, which will also be
43//! the fallback if the target does not have hardware support. Note that without the `std`
44//! feature enabled, no runtime CPU feature detection is used, so the hardware support is only
45//! compiled if the compiler target supports the CPU feature.
46//!
47//! - **`alloc`** -- Enable use of the [`alloc`] crate when not using the `std` library.
48//!
49//! Among other functions, this enables the [`vec`] module, which contains zero-copy
50//! conversions for the [`Vec`] type. This allows fast conversion between raw `Vec<u16>` bits and
51//! `Vec<f16>` or `Vec<bf16>` arrays, and vice versa.
52//!
53//! - **`std`** -- Enable features that depend on the Rust [`std`] library. This also enables the
54//! `alloc` feature automatically.
55//!
56//! Enabling the `std` feature also enables runtime CPU feature detection when the
57//! `use-intrsincis` feature is also enabled. Without this feature detection, intrinsics are only
58//! used when compiler target supports the target feature.
59//!
60//! - **`serde`** -- Adds support for the [`serde`] crate by implementing [`Serialize`] and
61//! [`Deserialize`] traits for both [`f16`] and [`bf16`].
62//!
63//! - **`num-traits`** -- Adds support for the [`num-traits`] crate by implementing [`ToPrimitive`],
64//! [`FromPrimitive`], [`AsPrimitive`], [`Num`], [`Float`], [`FloatCore`], and [`Bounded`] traits
65//! for both [`f16`] and [`bf16`].
66//!
67//! - **`bytemuck`** -- Adds support for the [`bytemuck`] crate by implementing [`Zeroable`] and
68//! [`Pod`] traits for both [`f16`] and [`bf16`].
69//!
70//! - **`zerocopy`** -- Adds support for the [`zerocopy`] crate by implementing [`AsBytes`] and
71//! [`FromBytes`] traits for both [`f16`] and [`bf16`].
72//!
73//! [`alloc`]: https://doc.rust-lang.org/alloc/
74//! [`std`]: https://doc.rust-lang.org/std/
75//! [`binary16`]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
76//! [`bfloat16`]: https://en.wikipedia.org/wiki/Bfloat16_floating-point_format
77//! [`serde`]: https://crates.io/crates/serde
78//! [`bytemuck`]: https://crates.io/crates/bytemuck
79//! [`num-traits`]: https://crates.io/crates/num-traits
80//! [`zerocopy`]: https://crates.io/crates/zerocopy
81#![cfg_attr(
82 feature = "alloc",
83 doc = "
84[`vec`]: mod@vec"
85)]
86#![cfg_attr(
87 not(feature = "alloc"),
88 doc = "
89[`vec`]: #
90[`Vec`]: https://docs.rust-lang.org/stable/alloc/vec/struct.Vec.html"
91)]
92#![cfg_attr(
93 feature = "serde",
94 doc = "
95[`Serialize`]: serde::Serialize
96[`Deserialize`]: serde::Deserialize"
97)]
98#![cfg_attr(
99 not(feature = "serde"),
100 doc = "
101[`Serialize`]: https://docs.rs/serde/*/serde/trait.Serialize.html
102[`Deserialize`]: https://docs.rs/serde/*/serde/trait.Deserialize.html"
103)]
104#![cfg_attr(
105 feature = "num-traits",
106 doc = "
107[`ToPrimitive`]: ::num_traits::ToPrimitive
108[`FromPrimitive`]: ::num_traits::FromPrimitive
109[`AsPrimitive`]: ::num_traits::AsPrimitive
110[`Num`]: ::num_traits::Num
111[`Float`]: ::num_traits::Float
112[`FloatCore`]: ::num_traits::float::FloatCore
113[`Bounded`]: ::num_traits::Bounded"
114)]
115#![cfg_attr(
116 not(feature = "num-traits"),
117 doc = "
118[`ToPrimitive`]: https://docs.rs/num-traits/*/num_traits/cast/trait.ToPrimitive.html
119[`FromPrimitive`]: https://docs.rs/num-traits/*/num_traits/cast/trait.FromPrimitive.html
120[`AsPrimitive`]: https://docs.rs/num-traits/*/num_traits/cast/trait.AsPrimitive.html
121[`Num`]: https://docs.rs/num-traits/*/num_traits/trait.Num.html
122[`Float`]: https://docs.rs/num-traits/*/num_traits/float/trait.Float.html
123[`FloatCore`]: https://docs.rs/num-traits/*/num_traits/float/trait.FloatCore.html
124[`Bounded`]: https://docs.rs/num-traits/*/num_traits/bounds/trait.Bounded.html"
125)]
126#![cfg_attr(
127 feature = "bytemuck",
128 doc = "
129[`Zeroable`]: bytemuck::Zeroable
130[`Pod`]: bytemuck::Pod"
131)]
132#![cfg_attr(
133 not(feature = "bytemuck"),
134 doc = "
135[`Zeroable`]: https://docs.rs/bytemuck/*/bytemuck/trait.Zeroable.html
136[`Pod`]: https://docs.rs/bytemuck/*bytemuck/trait.Pod.html"
137)]
138#![cfg_attr(
139 feature = "zerocopy",
140 doc = "
141[`AsBytes`]: zerocopy::AsBytes
142[`FromBytes`]: zerocopy::FromBytes"
143)]
144#![cfg_attr(
145 not(feature = "zerocopy"),
146 doc = "
147[`AsBytes`]: https://docs.rs/zerocopy/*/zerocopy/trait.AsBytes.html
148[`FromBytes`]: https://docs.rs/zerocopy/*/zerocopy/trait.FromBytes.html"
149)]
150#![warn(
151 missing_docs,
152 missing_copy_implementations,
153 missing_debug_implementations,
154 trivial_numeric_casts,
155 future_incompatible
156)]
157#![allow(clippy::verbose_bit_mask, clippy::cast_lossless)]
158#![cfg_attr(not(feature = "std"), no_std)]
159#![cfg_attr(
160 all(
161 feature = "use-intrinsics",
162 any(target_arch = "x86", target_arch = "x86_64")
163 ),
164 feature(stdsimd, f16c_target_feature)
165)]
166#![doc(html_root_url = "https://docs.rs/half/1.8.2")]
167#![doc(test(attr(deny(warnings), allow(unused))))]
168#![cfg_attr(docsrs, feature(doc_cfg))]
169
170#[cfg(feature = "alloc")]
171extern crate alloc;
172
173mod bfloat;
174mod binary16;
175#[cfg(feature = "num-traits")]
176mod num_traits;
177
178pub mod slice;
179#[cfg(feature = "alloc")]
180#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
181pub mod vec;
182
183pub use bfloat::bf16;
184#[doc(hidden)]
185#[allow(deprecated)]
186pub use binary16::consts;
187pub use binary16::f16;
188
189/// A collection of the most used items and traits in this crate for easy importing.
190///
191/// # Examples
192///
193/// ```rust
194/// use half::prelude::*;
195/// ```
196pub mod prelude {
197 #[doc(no_inline)]
198 pub use crate::{
199 bf16, f16,
200 slice::{HalfBitsSliceExt, HalfFloatSliceExt},
201 };
202
203 #[cfg(feature = "alloc")]
204 #[doc(no_inline)]
205 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
206 pub use crate::vec::{HalfBitsVecExt, HalfFloatVecExt};
207}
208
209// Keep this module private to crate
210mod private {
211 use crate::{bf16, f16};
212
213 pub trait SealedHalf {}
214
215 impl SealedHalf for f16 {}
216 impl SealedHalf for bf16 {}
217}
218