diff options
Diffstat (limited to 'vendor/half/src/slice.rs')
-rw-r--r-- | vendor/half/src/slice.rs | 854 |
1 files changed, 0 insertions, 854 deletions
diff --git a/vendor/half/src/slice.rs b/vendor/half/src/slice.rs deleted file mode 100644 index f1e9feb..0000000 --- a/vendor/half/src/slice.rs +++ /dev/null @@ -1,854 +0,0 @@ -//! Contains utility functions and traits to convert between slices of [`u16`] bits and [`f16`] or -//! [`bf16`] numbers. -//! -//! The utility [`HalfBitsSliceExt`] sealed extension trait is implemented for `[u16]` slices, -//! while the utility [`HalfFloatSliceExt`] sealed extension trait is implemented for both `[f16]` -//! and `[bf16]` slices. These traits provide efficient conversions and reinterpret casting of -//! larger buffers of floating point values, and are automatically included in the -//! [`prelude`][crate::prelude] module. - -use crate::{bf16, binary16::convert, f16}; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; -use core::slice; - -/// Extensions to `[f16]` and `[bf16]` slices to support conversion and reinterpret operations. -/// -/// This trait is sealed and cannot be implemented outside of this crate. -pub trait HalfFloatSliceExt: private::SealedHalfFloatSlice { - /// Reinterprets a slice of [`f16`] or [`bf16`] numbers as a slice of [`u16`] bits. - /// - /// This is a zero-copy operation. The reinterpreted slice has the same lifetime and memory - /// location as `self`. - /// - /// # Examples - /// - /// ```rust - /// # use half::prelude::*; - /// let float_buffer = [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.)]; - /// let int_buffer = float_buffer.reinterpret_cast(); - /// - /// assert_eq!(int_buffer, [float_buffer[0].to_bits(), float_buffer[1].to_bits(), float_buffer[2].to_bits()]); - /// ``` - #[must_use] - fn reinterpret_cast(&self) -> &[u16]; - - /// Reinterprets a mutable slice of [`f16`] or [`bf16`] numbers as a mutable slice of [`u16`]. - /// bits - /// - /// This is a zero-copy operation. The transmuted slice has the same lifetime as the original, - /// which prevents mutating `self` as long as the returned `&mut [u16]` is borrowed. - /// - /// # Examples - /// - /// ```rust - /// # use half::prelude::*; - /// let mut float_buffer = [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.)]; - /// - /// { - /// let int_buffer = float_buffer.reinterpret_cast_mut(); - /// - /// assert_eq!(int_buffer, [f16::from_f32(1.).to_bits(), f16::from_f32(2.).to_bits(), f16::from_f32(3.).to_bits()]); - /// - /// // Mutating the u16 slice will mutating the original - /// int_buffer[0] = 0; - /// } - /// - /// // Note that we need to drop int_buffer before using float_buffer again or we will get a borrow error. - /// assert_eq!(float_buffer, [f16::from_f32(0.), f16::from_f32(2.), f16::from_f32(3.)]); - /// ``` - #[must_use] - fn reinterpret_cast_mut(&mut self) -> &mut [u16]; - - /// Converts all of the elements of a `[f32]` slice into [`f16`] or [`bf16`] values in `self`. - /// - /// The length of `src` must be the same as `self`. - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// // Initialize an empty buffer - /// let mut buffer = [0u16; 4]; - /// let buffer = buffer.reinterpret_cast_mut::<f16>(); - /// - /// let float_values = [1., 2., 3., 4.]; - /// - /// // Now convert - /// buffer.convert_from_f32_slice(&float_values); - /// - /// assert_eq!(buffer, [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.), f16::from_f32(4.)]); - /// ``` - fn convert_from_f32_slice(&mut self, src: &[f32]); - - /// Converts all of the elements of a `[f64]` slice into [`f16`] or [`bf16`] values in `self`. - /// - /// The length of `src` must be the same as `self`. - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// // Initialize an empty buffer - /// let mut buffer = [0u16; 4]; - /// let buffer = buffer.reinterpret_cast_mut::<f16>(); - /// - /// let float_values = [1., 2., 3., 4.]; - /// - /// // Now convert - /// buffer.convert_from_f64_slice(&float_values); - /// - /// assert_eq!(buffer, [f16::from_f64(1.), f16::from_f64(2.), f16::from_f64(3.), f16::from_f64(4.)]); - /// ``` - fn convert_from_f64_slice(&mut self, src: &[f64]); - - /// Converts all of the [`f16`] or [`bf16`] elements of `self` into [`f32`] values in `dst`. - /// - /// The length of `src` must be the same as `self`. - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// // Initialize an empty buffer - /// let mut buffer = [0f32; 4]; - /// - /// let half_values = [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.), f16::from_f32(4.)]; - /// - /// // Now convert - /// half_values.convert_to_f32_slice(&mut buffer); - /// - /// assert_eq!(buffer, [1., 2., 3., 4.]); - /// ``` - fn convert_to_f32_slice(&self, dst: &mut [f32]); - - /// Converts all of the [`f16`] or [`bf16`] elements of `self` into [`f64`] values in `dst`. - /// - /// The length of `src` must be the same as `self`. - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// # Panics - /// - /// This function will panic if the two slices have different lengths. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// // Initialize an empty buffer - /// let mut buffer = [0f64; 4]; - /// - /// let half_values = [f16::from_f64(1.), f16::from_f64(2.), f16::from_f64(3.), f16::from_f64(4.)]; - /// - /// // Now convert - /// half_values.convert_to_f64_slice(&mut buffer); - /// - /// assert_eq!(buffer, [1., 2., 3., 4.]); - /// ``` - fn convert_to_f64_slice(&self, dst: &mut [f64]); - - // Because trait is sealed, we can get away with different interfaces between features. - - /// Converts all of the [`f16`] or [`bf16`] elements of `self` into [`f32`] values in a new - /// vector - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// This method is only available with the `std` or `alloc` feature. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// let half_values = [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.), f16::from_f32(4.)]; - /// let vec = half_values.to_f32_vec(); - /// - /// assert_eq!(vec, vec![1., 2., 3., 4.]); - /// ``` - #[cfg(any(feature = "alloc", feature = "std"))] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - #[must_use] - fn to_f32_vec(&self) -> Vec<f32>; - - /// Converts all of the [`f16`] or [`bf16`] elements of `self` into [`f64`] values in a new - /// vector. - /// - /// The conversion operation is vectorized over the slice, meaning the conversion may be more - /// efficient than converting individual elements on some hardware that supports SIMD - /// conversions. See [crate documentation](crate) for more information on hardware conversion - /// support. - /// - /// This method is only available with the `std` or `alloc` feature. - /// - /// # Examples - /// ```rust - /// # use half::prelude::*; - /// let half_values = [f16::from_f64(1.), f16::from_f64(2.), f16::from_f64(3.), f16::from_f64(4.)]; - /// let vec = half_values.to_f64_vec(); - /// - /// assert_eq!(vec, vec![1., 2., 3., 4.]); - /// ``` - #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] - #[must_use] - fn to_f64_vec(&self) -> Vec<f64>; -} - -/// Extensions to `[u16]` slices to support reinterpret operations. -/// -/// This trait is sealed and cannot be implemented outside of this crate. -pub trait HalfBitsSliceExt: private::SealedHalfBitsSlice { - /// Reinterprets a slice of [`u16`] bits as a slice of [`f16`] or [`bf16`] numbers. - /// - /// `H` is the type to cast to, and must be either the [`f16`] or [`bf16`] type. - /// - /// This is a zero-copy operation. The reinterpreted slice has the same lifetime and memory - /// location as `self`. - /// - /// # Examples - /// - /// ```rust - /// # use half::prelude::*; - /// let int_buffer = [f16::from_f32(1.).to_bits(), f16::from_f32(2.).to_bits(), f16::from_f32(3.).to_bits()]; - /// let float_buffer: &[f16] = int_buffer.reinterpret_cast(); - /// - /// assert_eq!(float_buffer, [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.)]); - /// - /// // You may have to specify the cast type directly if the compiler can't infer the type. - /// // The following is also valid in Rust. - /// let typed_buffer = int_buffer.reinterpret_cast::<f16>(); - /// ``` - #[must_use] - fn reinterpret_cast<H>(&self) -> &[H] - where - H: crate::private::SealedHalf; - - /// Reinterprets a mutable slice of [`u16`] bits as a mutable slice of [`f16`] or [`bf16`] - /// numbers. - /// - /// `H` is the type to cast to, and must be either the [`f16`] or [`bf16`] type. - /// - /// This is a zero-copy operation. The transmuted slice has the same lifetime as the original, - /// which prevents mutating `self` as long as the returned `&mut [f16]` is borrowed. - /// - /// # Examples - /// - /// ```rust - /// # use half::prelude::*; - /// let mut int_buffer = [f16::from_f32(1.).to_bits(), f16::from_f32(2.).to_bits(), f16::from_f32(3.).to_bits()]; - /// - /// { - /// let float_buffer: &mut [f16] = int_buffer.reinterpret_cast_mut(); - /// - /// assert_eq!(float_buffer, [f16::from_f32(1.), f16::from_f32(2.), f16::from_f32(3.)]); - /// - /// // Mutating the f16 slice will mutating the original - /// float_buffer[0] = f16::from_f32(0.); - /// } - /// - /// // Note that we need to drop float_buffer before using int_buffer again or we will get a borrow error. - /// assert_eq!(int_buffer, [f16::from_f32(0.).to_bits(), f16::from_f32(2.).to_bits(), f16::from_f32(3.).to_bits()]); - /// - /// // You may have to specify the cast type directly if the compiler can't infer the type. - /// // The following is also valid in Rust. - /// let typed_buffer = int_buffer.reinterpret_cast_mut::<f16>(); - /// ``` - #[must_use] - fn reinterpret_cast_mut<H>(&mut self) -> &mut [H] - where - H: crate::private::SealedHalf; -} - -mod private { - use crate::{bf16, f16}; - - pub trait SealedHalfFloatSlice {} - impl SealedHalfFloatSlice for [f16] {} - impl SealedHalfFloatSlice for [bf16] {} - - pub trait SealedHalfBitsSlice {} - impl SealedHalfBitsSlice for [u16] {} -} - -impl HalfFloatSliceExt for [f16] { - #[inline] - fn reinterpret_cast(&self) -> &[u16] { - let pointer = self.as_ptr() as *const u16; - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts(pointer, length) } - } - - #[inline] - fn reinterpret_cast_mut(&mut self) -> &mut [u16] { - let pointer = self.as_mut_ptr().cast::<u16>(); - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts_mut(pointer, length) } - } - - fn convert_from_f32_slice(&mut self, src: &[f32]) { - assert_eq!( - self.len(), - src.len(), - "destination and source slices have different lengths" - ); - - convert::f32_to_f16_slice(src, self.reinterpret_cast_mut()) - } - - fn convert_from_f64_slice(&mut self, src: &[f64]) { - assert_eq!( - self.len(), - src.len(), - "destination and source slices have different lengths" - ); - - convert::f64_to_f16_slice(src, self.reinterpret_cast_mut()) - } - - fn convert_to_f32_slice(&self, dst: &mut [f32]) { - assert_eq!( - self.len(), - dst.len(), - "destination and source slices have different lengths" - ); - - convert::f16_to_f32_slice(self.reinterpret_cast(), dst) - } - - fn convert_to_f64_slice(&self, dst: &mut [f64]) { - assert_eq!( - self.len(), - dst.len(), - "destination and source slices have different lengths" - ); - - convert::f16_to_f64_slice(self.reinterpret_cast(), dst) - } - - #[cfg(any(feature = "alloc", feature = "std"))] - #[inline] - #[allow(clippy::uninit_vec)] - fn to_f32_vec(&self) -> Vec<f32> { - let mut vec = Vec::with_capacity(self.len()); - // SAFETY: convert will initialize every value in the vector without reading them, - // so this is safe to do instead of double initialize from resize, and we're setting it to - // same value as capacity. - unsafe { vec.set_len(self.len()) }; - self.convert_to_f32_slice(&mut vec); - vec - } - - #[cfg(any(feature = "alloc", feature = "std"))] - #[inline] - #[allow(clippy::uninit_vec)] - fn to_f64_vec(&self) -> Vec<f64> { - let mut vec = Vec::with_capacity(self.len()); - // SAFETY: convert will initialize every value in the vector without reading them, - // so this is safe to do instead of double initialize from resize, and we're setting it to - // same value as capacity. - unsafe { vec.set_len(self.len()) }; - self.convert_to_f64_slice(&mut vec); - vec - } -} - -impl HalfFloatSliceExt for [bf16] { - #[inline] - fn reinterpret_cast(&self) -> &[u16] { - let pointer = self.as_ptr() as *const u16; - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts(pointer, length) } - } - - #[inline] - fn reinterpret_cast_mut(&mut self) -> &mut [u16] { - let pointer = self.as_mut_ptr().cast::<u16>(); - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts_mut(pointer, length) } - } - - fn convert_from_f32_slice(&mut self, src: &[f32]) { - assert_eq!( - self.len(), - src.len(), - "destination and source slices have different lengths" - ); - - // Just use regular loop here until there's any bf16 SIMD support. - for (i, f) in src.iter().enumerate() { - self[i] = bf16::from_f32(*f); - } - } - - fn convert_from_f64_slice(&mut self, src: &[f64]) { - assert_eq!( - self.len(), - src.len(), - "destination and source slices have different lengths" - ); - - // Just use regular loop here until there's any bf16 SIMD support. - for (i, f) in src.iter().enumerate() { - self[i] = bf16::from_f64(*f); - } - } - - fn convert_to_f32_slice(&self, dst: &mut [f32]) { - assert_eq!( - self.len(), - dst.len(), - "destination and source slices have different lengths" - ); - - // Just use regular loop here until there's any bf16 SIMD support. - for (i, f) in self.iter().enumerate() { - dst[i] = f.to_f32(); - } - } - - fn convert_to_f64_slice(&self, dst: &mut [f64]) { - assert_eq!( - self.len(), - dst.len(), - "destination and source slices have different lengths" - ); - - // Just use regular loop here until there's any bf16 SIMD support. - for (i, f) in self.iter().enumerate() { - dst[i] = f.to_f64(); - } - } - - #[cfg(any(feature = "alloc", feature = "std"))] - #[inline] - #[allow(clippy::uninit_vec)] - fn to_f32_vec(&self) -> Vec<f32> { - let mut vec = Vec::with_capacity(self.len()); - // SAFETY: convert will initialize every value in the vector without reading them, - // so this is safe to do instead of double initialize from resize, and we're setting it to - // same value as capacity. - unsafe { vec.set_len(self.len()) }; - self.convert_to_f32_slice(&mut vec); - vec - } - - #[cfg(any(feature = "alloc", feature = "std"))] - #[inline] - #[allow(clippy::uninit_vec)] - fn to_f64_vec(&self) -> Vec<f64> { - let mut vec = Vec::with_capacity(self.len()); - // SAFETY: convert will initialize every value in the vector without reading them, - // so this is safe to do instead of double initialize from resize, and we're setting it to - // same value as capacity. - unsafe { vec.set_len(self.len()) }; - self.convert_to_f64_slice(&mut vec); - vec - } -} - -impl HalfBitsSliceExt for [u16] { - // Since we sealed all the traits involved, these are safe. - #[inline] - fn reinterpret_cast<H>(&self) -> &[H] - where - H: crate::private::SealedHalf, - { - let pointer = self.as_ptr() as *const H; - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts(pointer, length) } - } - - #[inline] - fn reinterpret_cast_mut<H>(&mut self) -> &mut [H] - where - H: crate::private::SealedHalf, - { - let pointer = self.as_mut_ptr() as *mut H; - let length = self.len(); - // SAFETY: We are reconstructing full length of original slice, using its same lifetime, - // and the size of elements are identical - unsafe { slice::from_raw_parts_mut(pointer, length) } - } -} - -#[allow(clippy::float_cmp)] -#[cfg(test)] -mod test { - use super::{HalfBitsSliceExt, HalfFloatSliceExt}; - use crate::{bf16, f16}; - - #[test] - fn test_slice_conversions_f16() { - let bits = &[ - f16::E.to_bits(), - f16::PI.to_bits(), - f16::EPSILON.to_bits(), - f16::FRAC_1_SQRT_2.to_bits(), - ]; - let numbers = &[f16::E, f16::PI, f16::EPSILON, f16::FRAC_1_SQRT_2]; - - // Convert from bits to numbers - let from_bits = bits.reinterpret_cast::<f16>(); - assert_eq!(from_bits, numbers); - - // Convert from numbers back to bits - let to_bits = from_bits.reinterpret_cast(); - assert_eq!(to_bits, bits); - } - - #[test] - fn test_mutablility_f16() { - let mut bits_array = [f16::PI.to_bits()]; - let bits = &mut bits_array[..]; - - { - // would not compile without these braces - let numbers = bits.reinterpret_cast_mut(); - numbers[0] = f16::E; - } - - assert_eq!(bits, &[f16::E.to_bits()]); - - bits[0] = f16::LN_2.to_bits(); - assert_eq!(bits, &[f16::LN_2.to_bits()]); - } - - #[test] - fn test_slice_conversions_bf16() { - let bits = &[ - bf16::E.to_bits(), - bf16::PI.to_bits(), - bf16::EPSILON.to_bits(), - bf16::FRAC_1_SQRT_2.to_bits(), - ]; - let numbers = &[bf16::E, bf16::PI, bf16::EPSILON, bf16::FRAC_1_SQRT_2]; - - // Convert from bits to numbers - let from_bits = bits.reinterpret_cast::<bf16>(); - assert_eq!(from_bits, numbers); - - // Convert from numbers back to bits - let to_bits = from_bits.reinterpret_cast(); - assert_eq!(to_bits, bits); - } - - #[test] - fn test_mutablility_bf16() { - let mut bits_array = [bf16::PI.to_bits()]; - let bits = &mut bits_array[..]; - - { - // would not compile without these braces - let numbers = bits.reinterpret_cast_mut(); - numbers[0] = bf16::E; - } - - assert_eq!(bits, &[bf16::E.to_bits()]); - - bits[0] = bf16::LN_2.to_bits(); - assert_eq!(bits, &[bf16::LN_2.to_bits()]); - } - - #[test] - fn slice_convert_f16_f32() { - // Exact chunks - let vf32 = [1., 2., 3., 4., 5., 6., 7., 8.]; - let vf16 = [ - f16::from_f32(1.), - f16::from_f32(2.), - f16::from_f32(3.), - f16::from_f32(4.), - f16::from_f32(5.), - f16::from_f32(6.), - f16::from_f32(7.), - f16::from_f32(8.), - ]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf32 = [1., 2., 3., 4., 5., 6., 7., 8., 9.]; - let vf16 = [ - f16::from_f32(1.), - f16::from_f32(2.), - f16::from_f32(3.), - f16::from_f32(4.), - f16::from_f32(5.), - f16::from_f32(6.), - f16::from_f32(7.), - f16::from_f32(8.), - f16::from_f32(9.), - ]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf32 = [1., 2.]; - let vf16 = [f16::from_f32(1.), f16::from_f32(2.)]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - } - - #[test] - fn slice_convert_bf16_f32() { - // Exact chunks - let vf32 = [1., 2., 3., 4., 5., 6., 7., 8.]; - let vf16 = [ - bf16::from_f32(1.), - bf16::from_f32(2.), - bf16::from_f32(3.), - bf16::from_f32(4.), - bf16::from_f32(5.), - bf16::from_f32(6.), - bf16::from_f32(7.), - bf16::from_f32(8.), - ]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf32 = [1., 2., 3., 4., 5., 6., 7., 8., 9.]; - let vf16 = [ - bf16::from_f32(1.), - bf16::from_f32(2.), - bf16::from_f32(3.), - bf16::from_f32(4.), - bf16::from_f32(5.), - bf16::from_f32(6.), - bf16::from_f32(7.), - bf16::from_f32(8.), - bf16::from_f32(9.), - ]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf32 = [1., 2.]; - let vf16 = [bf16::from_f32(1.), bf16::from_f32(2.)]; - let mut buf32 = vf32; - let mut buf16 = vf16; - - vf16.convert_to_f32_slice(&mut buf32); - assert_eq!(&vf32, &buf32); - - buf16.convert_from_f32_slice(&vf32); - assert_eq!(&vf16, &buf16); - } - - #[test] - fn slice_convert_f16_f64() { - // Exact chunks - let vf64 = [1., 2., 3., 4., 5., 6., 7., 8.]; - let vf16 = [ - f16::from_f64(1.), - f16::from_f64(2.), - f16::from_f64(3.), - f16::from_f64(4.), - f16::from_f64(5.), - f16::from_f64(6.), - f16::from_f64(7.), - f16::from_f64(8.), - ]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf64 = [1., 2., 3., 4., 5., 6., 7., 8., 9.]; - let vf16 = [ - f16::from_f64(1.), - f16::from_f64(2.), - f16::from_f64(3.), - f16::from_f64(4.), - f16::from_f64(5.), - f16::from_f64(6.), - f16::from_f64(7.), - f16::from_f64(8.), - f16::from_f64(9.), - ]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf64 = [1., 2.]; - let vf16 = [f16::from_f64(1.), f16::from_f64(2.)]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - } - - #[test] - fn slice_convert_bf16_f64() { - // Exact chunks - let vf64 = [1., 2., 3., 4., 5., 6., 7., 8.]; - let vf16 = [ - bf16::from_f64(1.), - bf16::from_f64(2.), - bf16::from_f64(3.), - bf16::from_f64(4.), - bf16::from_f64(5.), - bf16::from_f64(6.), - bf16::from_f64(7.), - bf16::from_f64(8.), - ]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf64 = [1., 2., 3., 4., 5., 6., 7., 8., 9.]; - let vf16 = [ - bf16::from_f64(1.), - bf16::from_f64(2.), - bf16::from_f64(3.), - bf16::from_f64(4.), - bf16::from_f64(5.), - bf16::from_f64(6.), - bf16::from_f64(7.), - bf16::from_f64(8.), - bf16::from_f64(9.), - ]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - - // Partial with chunks - let vf64 = [1., 2.]; - let vf16 = [bf16::from_f64(1.), bf16::from_f64(2.)]; - let mut buf64 = vf64; - let mut buf16 = vf16; - - vf16.convert_to_f64_slice(&mut buf64); - assert_eq!(&vf64, &buf64); - - buf16.convert_from_f64_slice(&vf64); - assert_eq!(&vf16, &buf16); - } - - #[test] - #[should_panic] - fn convert_from_f32_slice_len_mismatch_panics() { - let mut slice1 = [f16::ZERO; 3]; - let slice2 = [0f32; 4]; - slice1.convert_from_f32_slice(&slice2); - } - - #[test] - #[should_panic] - fn convert_from_f64_slice_len_mismatch_panics() { - let mut slice1 = [f16::ZERO; 3]; - let slice2 = [0f64; 4]; - slice1.convert_from_f64_slice(&slice2); - } - - #[test] - #[should_panic] - fn convert_to_f32_slice_len_mismatch_panics() { - let slice1 = [f16::ZERO; 3]; - let mut slice2 = [0f32; 4]; - slice1.convert_to_f32_slice(&mut slice2); - } - - #[test] - #[should_panic] - fn convert_to_f64_slice_len_mismatch_panics() { - let slice1 = [f16::ZERO; 3]; - let mut slice2 = [0f64; 4]; - slice1.convert_to_f64_slice(&mut slice2); - } -} |