Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: VoidStarKat/half-rs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.4.0
Choose a base ref
...
head repository: VoidStarKat/half-rs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.4.1
Choose a head ref
  • 4 commits
  • 11 files changed
  • 1 contributor

Commits on Apr 6, 2024

  1. properly import alloc::vec in no-std+alloc. Fixes #107

    VoidStarKat committed Apr 6, 2024
    Copy the full SHA
    2841ec4 View commit details
  2. add annotations to transmutes to satify nightly clippy

    VoidStarKat committed Apr 6, 2024
    Copy the full SHA
    88d4213 View commit details
  3. bump version to 2.4.1

    VoidStarKat committed Apr 6, 2024
    Copy the full SHA
    e133f19 View commit details
  4. fix build status badge

    VoidStarKat committed Apr 6, 2024
    Copy the full SHA
    b2c5209 View commit details
Showing with 67 additions and 29 deletions.
  1. +3 −0 .circleci/config.yml
  2. +8 −1 CHANGELOG.md
  3. +1 −1 Cargo.lock
  4. +1 −1 Cargo.toml
  5. +21 −1 Makefile.toml
  6. +1 −1 README.md
  7. +13 −9 src/bfloat/convert.rs
  8. +16 −12 src/binary16/arch.rs
  9. +1 −1 src/lib.rs
  10. +1 −1 src/slice.rs
  11. +1 −1 src/vec.rs
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -39,6 +39,9 @@ jobs:
- run:
name: cargo test no_std
command: cargo -v test --no-default-features -- --nocapture
- run:
name: cargo test no_std+alloc
command: cargo -v test --no-default-features --features alloc -- --nocapture

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [2.4.1] - 2024-04-06 <a name="2.4.1"></a>
### Fixed
- Missing macro import causing build failure on `no_std` + `alloc` feature set. Fixes [#107].
- Clippy warning on nightly rust.

## [2.4.0] - 2024-02-25 <a name="2.4.0"></a>
### Added
- Optional `rkyv` support. Fixes [#100], by [@comath].
@@ -324,6 +329,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
[#93]: https://github.com/starkat99/half-rs/issues/54
[#100]: https://github.com/starkat99/half-rs/issues/100
[#103]: https://github.com/starkat99/half-rs/issues/103
[#107]: https://github.com/starkat99/half-rs/issues/107

[@tspiteri]: https://github.com/tspiteri
[@PSeitz]: https://github.com/PSeitz
@@ -347,7 +353,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
[@comath]: https://github.com/comath


[Unreleased]: https://github.com/starkat99/half-rs/compare/v2.4.0...HEAD
[Unreleased]: https://github.com/starkat99/half-rs/compare/v2.4.1...HEAD
[2.4.1]: https://github.com/starkat99/half-rs/compare/v2.4.0...v2.4.1
[2.4.0]: https://github.com/starkat99/half-rs/compare/v2.3.1...v2.4.0
[2.3.1]: https://github.com/starkat99/half-rs/compare/v2.3.0...v2.3.1
[2.3.0]: https://github.com/starkat99/half-rs/compare/v2.2.1...v2.3.0
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "half"
# Remember to keep in sync with html_root_url crate attribute
version = "2.4.0"
version = "2.4.1"
authors = ["Kathryn Long <squeeself@gmail.com>"]
description = "Half-precision floating point f16 and bf16 types for Rust implementing the IEEE 754-2008 standard binary16 and bfloat16 types."
repository = "https://github.com/starkat99/half-rs"
22 changes: 21 additions & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
@@ -43,7 +43,15 @@ args = [

# Build & Test with no features enabled
[tasks.post-ci-flow]
run_task = [{ name = ["check-docs", "build-no-std", "test-no-std"] }]
run_task = [
{ name = [
"check-docs",
"build-no-std",
"test-no-std",
"build-no-std-alloc",
"test-no-std-alloc",
] },
]

[tasks.build-no-std]
description = "Build without any features"
@@ -56,3 +64,15 @@ description = "Run tests without any features"
category = "Test"
env = { CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "--no-default-features" }
run_task = "test"

[tasks.build-no-std-alloc]
description = "Build without any features except alloc"
category = "Build"
env = { CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "--no-default-features --features alloc" }
run_task = "build"

[tasks.test-no-std-alloc]
description = "Run tests without any features except alloc"
category = "Test"
env = { CARGO_MAKE_CARGO_BUILD_TEST_FLAGS = "--no-default-features --features alloc" }
run_task = "test"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# `f16` and `bf16` floating point types for Rust
[![Crates.io](https://img.shields.io/crates/v/half.svg)](https://crates.io/crates/half/) [![Documentation](https://docs.rs/half/badge.svg)](https://docs.rs/half/) ![Crates.io](https://img.shields.io/crates/l/half) [![Build status](https://github.com/starkat99/half-rs/actions/workflows/rust.yml/badge.svg?branch=master)](https://github.com/starkat99/half-rs/actions/workflows/rust.yml) [![CircleCI](https://dl.circleci.com/status-badge/img/gh/starkat99/half-rs/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/starkat99/half-rs/tree/main)
[![Crates.io](https://img.shields.io/crates/v/half.svg)](https://crates.io/crates/half/) [![Documentation](https://docs.rs/half/badge.svg)](https://docs.rs/half/) ![Crates.io](https://img.shields.io/crates/l/half) [![Build status](https://github.com/starkat99/half-rs/actions/workflows/rust.yml/badge.svg?branch=main&event=push)](https://github.com/starkat99/half-rs/actions/workflows/rust.yml) [![CircleCI](https://dl.circleci.com/status-badge/img/gh/starkat99/half-rs/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/starkat99/half-rs/tree/main)

This crate implements a half-precision floating point `f16` type for Rust implementing the IEEE
754-2008 standard [`binary16`](https://en.wikipedia.org/wiki/Half-precision_floating-point_format)
22 changes: 13 additions & 9 deletions src/bfloat/convert.rs
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ use core::mem;
pub(crate) const fn f32_to_bf16(value: f32) -> u16 {
// TODO: Replace mem::transmute with to_bits() once to_bits is const-stabilized
// Convert to raw bytes
let x: u32 = unsafe { mem::transmute(value) };
let x: u32 = unsafe { mem::transmute::<f32, u32>(value) };

// check for NaN
if x & 0x7FFF_FFFFu32 > 0x7F80_0000u32 {
@@ -27,7 +27,7 @@ pub(crate) const fn f64_to_bf16(value: f64) -> u16 {
// TODO: Replace mem::transmute with to_bits() once to_bits is const-stabilized
// Convert to raw bytes, truncating the last 32-bits of mantissa; that precision will always
// be lost on half-precision.
let val: u64 = unsafe { mem::transmute(value) };
let val: u64 = unsafe { mem::transmute::<f64, u64>(value) };
let x = (val >> 32) as u32;

// Extract IEEE754 components
@@ -95,9 +95,9 @@ pub(crate) const fn bf16_to_f32(i: u16) -> f32 {
// TODO: Replace mem::transmute with from_bits() once from_bits is const-stabilized
// If NaN, keep current mantissa but also set most significiant mantissa bit
if i & 0x7FFFu16 > 0x7F80u16 {
unsafe { mem::transmute((i as u32 | 0x0040u32) << 16) }
unsafe { mem::transmute::<u32, f32>((i as u32 | 0x0040u32) << 16) }
} else {
unsafe { mem::transmute((i as u32) << 16) }
unsafe { mem::transmute::<u32, f32>((i as u32) << 16) }
}
}

@@ -106,7 +106,7 @@ pub(crate) const fn bf16_to_f64(i: u16) -> f64 {
// TODO: Replace mem::transmute with from_bits() once from_bits is const-stabilized
// Check for signed zero
if i & 0x7FFFu16 == 0 {
return unsafe { mem::transmute((i as u64) << 48) };
return unsafe { mem::transmute::<u64, f64>((i as u64) << 48) };
}

let half_sign = (i & 0x8000u16) as u64;
@@ -117,11 +117,15 @@ pub(crate) const fn bf16_to_f64(i: u16) -> f64 {
if half_exp == 0x7F80u64 {
// Check for signed infinity if mantissa is zero
if half_man == 0 {
return unsafe { mem::transmute((half_sign << 48) | 0x7FF0_0000_0000_0000u64) };
return unsafe {
mem::transmute::<u64, f64>((half_sign << 48) | 0x7FF0_0000_0000_0000u64)
};
} else {
// NaN, keep current mantissa but also set most significiant mantissa bit
return unsafe {
mem::transmute((half_sign << 48) | 0x7FF8_0000_0000_0000u64 | (half_man << 45))
mem::transmute::<u64, f64>(
(half_sign << 48) | 0x7FF8_0000_0000_0000u64 | (half_man << 45),
)
};
}
}
@@ -139,10 +143,10 @@ pub(crate) const fn bf16_to_f64(i: u16) -> f64 {
// Rebias and adjust exponent
let exp = ((1023 - 127 - e) as u64) << 52;
let man = (half_man << (46 + e)) & 0xF_FFFF_FFFF_FFFFu64;
return unsafe { mem::transmute(sign | exp | man) };
return unsafe { mem::transmute::<u64, f64>(sign | exp | man) };
}
// Rebias exponent for a normalized normal
let exp = ((unbiased_exp + 1023) as u64) << 52;
let man = (half_man & 0x007Fu64) << 45;
unsafe { mem::transmute(sign | exp | man) }
unsafe { mem::transmute::<u64, f64>(sign | exp | man) }
}
28 changes: 16 additions & 12 deletions src/binary16/arch.rs
Original file line number Diff line number Diff line change
@@ -482,7 +482,7 @@ fn convert_chunked_slice_4<S: Copy + Default, D: Copy>(
pub(crate) const fn f32_to_f16_fallback(value: f32) -> u16 {
// TODO: Replace mem::transmute with to_bits() once to_bits is const-stabilized
// Convert to raw bytes
let x: u32 = unsafe { mem::transmute(value) };
let x: u32 = unsafe { mem::transmute::<f32, u32>(value) };

// Extract IEEE754 components
let sign = x & 0x8000_0000u32;
@@ -544,7 +544,7 @@ pub(crate) const fn f64_to_f16_fallback(value: f64) -> u16 {
// Convert to raw bytes, truncating the last 32-bits of mantissa; that precision will always
// be lost on half-precision.
// TODO: Replace mem::transmute with to_bits() once to_bits is const-stabilized
let val: u64 = unsafe { mem::transmute(value) };
let val: u64 = unsafe { mem::transmute::<f64, u64>(value) };
let x = (val >> 32) as u32;

// Extract IEEE754 components
@@ -612,7 +612,7 @@ pub(crate) const fn f16_to_f32_fallback(i: u16) -> f32 {
// Check for signed zero
// TODO: Replace mem::transmute with from_bits() once from_bits is const-stabilized
if i & 0x7FFFu16 == 0 {
return unsafe { mem::transmute((i as u32) << 16) };
return unsafe { mem::transmute::<u32, f32>((i as u32) << 16) };
}

let half_sign = (i & 0x8000u16) as u32;
@@ -623,11 +623,11 @@ pub(crate) const fn f16_to_f32_fallback(i: u16) -> f32 {
if half_exp == 0x7C00u32 {
// Check for signed infinity if mantissa is zero
if half_man == 0 {
return unsafe { mem::transmute((half_sign << 16) | 0x7F80_0000u32) };
return unsafe { mem::transmute::<u32, f32>((half_sign << 16) | 0x7F80_0000u32) };
} else {
// NaN, keep current mantissa but also set most significiant mantissa bit
return unsafe {
mem::transmute((half_sign << 16) | 0x7FC0_0000u32 | (half_man << 13))
mem::transmute::<u32, f32>((half_sign << 16) | 0x7FC0_0000u32 | (half_man << 13))
};
}
}
@@ -645,21 +645,21 @@ pub(crate) const fn f16_to_f32_fallback(i: u16) -> f32 {
// Rebias and adjust exponent
let exp = (127 - 15 - e) << 23;
let man = (half_man << (14 + e)) & 0x7F_FF_FFu32;
return unsafe { mem::transmute(sign | exp | man) };
return unsafe { mem::transmute::<u32, f32>(sign | exp | man) };
}

// Rebias exponent for a normalized normal
let exp = ((unbiased_exp + 127) as u32) << 23;
let man = (half_man & 0x03FFu32) << 13;
unsafe { mem::transmute(sign | exp | man) }
unsafe { mem::transmute::<u32, f32>(sign | exp | man) }
}

#[inline]
pub(crate) const fn f16_to_f64_fallback(i: u16) -> f64 {
// Check for signed zero
// TODO: Replace mem::transmute with from_bits() once from_bits is const-stabilized
if i & 0x7FFFu16 == 0 {
return unsafe { mem::transmute((i as u64) << 48) };
return unsafe { mem::transmute::<u64, f64>((i as u64) << 48) };
}

let half_sign = (i & 0x8000u16) as u64;
@@ -670,11 +670,15 @@ pub(crate) const fn f16_to_f64_fallback(i: u16) -> f64 {
if half_exp == 0x7C00u64 {
// Check for signed infinity if mantissa is zero
if half_man == 0 {
return unsafe { mem::transmute((half_sign << 48) | 0x7FF0_0000_0000_0000u64) };
return unsafe {
mem::transmute::<u64, f64>((half_sign << 48) | 0x7FF0_0000_0000_0000u64)
};
} else {
// NaN, keep current mantissa but also set most significiant mantissa bit
return unsafe {
mem::transmute((half_sign << 48) | 0x7FF8_0000_0000_0000u64 | (half_man << 42))
mem::transmute::<u64, f64>(
(half_sign << 48) | 0x7FF8_0000_0000_0000u64 | (half_man << 42),
)
};
}
}
@@ -692,13 +696,13 @@ pub(crate) const fn f16_to_f64_fallback(i: u16) -> f64 {
// Rebias and adjust exponent
let exp = ((1023 - 15 - e) as u64) << 52;
let man = (half_man << (43 + e)) & 0xF_FFFF_FFFF_FFFFu64;
return unsafe { mem::transmute(sign | exp | man) };
return unsafe { mem::transmute::<u64, f64>(sign | exp | man) };
}

// Rebias exponent for a normalized normal
let exp = ((unbiased_exp + 1023) as u64) << 52;
let man = (half_man & 0x03FFu64) << 42;
unsafe { mem::transmute(sign | exp | man) }
unsafe { mem::transmute::<u64, f64>(sign | exp | man) }
}

#[inline]
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -200,7 +200,7 @@
#![cfg_attr(not(target_arch = "spirv"), warn(missing_debug_implementations))]
#![allow(clippy::verbose_bit_mask, clippy::cast_lossless)]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(html_root_url = "https://docs.rs/half/2.4.0")]
#![doc(html_root_url = "https://docs.rs/half/2.4.1")]
#![doc(test(attr(deny(warnings), allow(unused))))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

2 changes: 1 addition & 1 deletion src/slice.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
use crate::{bf16, binary16::arch, f16};
#[cfg(feature = "alloc")]
#[allow(unused_imports)]
use alloc::vec::Vec;
use alloc::{vec, vec::Vec};
use core::slice;

/// Extensions to `[f16]` and `[bf16]` slices to support conversion and reinterpret operations.
2 changes: 1 addition & 1 deletion src/vec.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
use super::{bf16, f16, slice::HalfFloatSliceExt};
#[cfg(feature = "alloc")]
#[allow(unused_imports)]
use alloc::vec::Vec;
use alloc::{vec, vec::Vec};
use core::mem;

/// Extensions to [`Vec<f16>`] and [`Vec<bf16>`] to support reinterpret operations.