#numeric

no-std common_traits

Traits to write generic functions on different numeric types, with atomic support, and other features

33 releases (9 breaking)

0.10.2 Feb 3, 2024
0.10.0 Oct 11, 2023
0.7.0 Jul 31, 2023
0.2.4 Feb 9, 2023

#54 in Math

Download history 27/week @ 2024-01-01 93/week @ 2024-01-08 118/week @ 2024-01-15 93/week @ 2024-01-22 119/week @ 2024-01-29 84/week @ 2024-02-05 78/week @ 2024-02-12 65/week @ 2024-02-19 217/week @ 2024-02-26 143/week @ 2024-03-04 137/week @ 2024-03-11 238/week @ 2024-03-18 136/week @ 2024-03-25 243/week @ 2024-04-01 178/week @ 2024-04-08 147/week @ 2024-04-15

713 downloads per month
Used in 5 crates (4 directly)

Apache-2.0

210KB
4.5K SLoC

common_traits

A collection of traits and dependencies that can be used to write code that is generic over numerical types. It provides also atomic floats implemented using the integer atomic byte with the same number of bits, and support for half precision floats via the crate half.

Additionally, there are a few traits missing from the standard library, such as Sequence, and variants of existing library traits such as [Rng] and Hash.

Finally, we provide traits for casting between types, such as UpcastableInto, and fast implementation of a few primitives such FastRange and SelectInWord.

Everything is experimental and I'll change them to my needs, respecting semantic versioning. :)

The point of making this crate public is to be able to discuss this as it covers many core missings from Rust.

The traits in this crate are similar to the ones from num-traits but they are more interconnected, which allows to write generic code (e.g., code mixing a type and its associated atomic type) more easily and with less trait bounds.

The numerical traits dependancy chains is this:

This crate adds emulated atomic floats through fetch_update for the following types:

The crate also contains a couple of extra traits:

  • [Rng] for a generic random number generator.
  • Splat to broadcast a smaller type on a larger type, mainly used for SWAR.
  • SelectInWord to find the position of the i-th 1 or 0 in words of memory.
  • FastRange for faster div, mod, and range operations.
  • Sequence, SequenceMut, and SequenceGrowable to abstract over slices and other sequence like types.

Traits for conversion between types are also provided:

The difference between Castable and [To] is that Castable does not allow casting from f32 to u32 for example, because Castable is implemented only between integers and between floats, while [To] is implemented for all primitive types.

Features

This crate has the following features:

  • simd: To enable portable_simd and be able to do generic simd code
  • atomic_from_mut: to add the get_mut_slice and from_mut_slice methods
  • std: to disable for no_std
  • half: to enable support for half::f16 (WORK IN PROGRESS)

Example

Mixed precision generic dot products!

use common_traits::*;

#[inline]
pub fn dot_product<MT: Number, RT: Number, A, B>(a: A, b: B) -> RT
where
    A: Sequence,
    B: Sequence,
    A::Item: To<MT>,
    B::Item: To<MT>,
    MT: To<RT>,
    RT: To<MT>,
{
    // Check compatability of the vectors
    assert_eq!(a.len(), b.len());

    // Compute the dot product
    let mut accum = RT::ZERO;
    for (a, b) in a.iter().zip(b.iter()) {
        accum = (a.to()).mul_add(b.to(), accum.to()).to();
    }

    accum
}

let x: Vec<f32> = vec![1.0, 2.0, 3.0];
let w: Vec<u8> = vec![3, 2, 1];
// compute the dot product between f32 and u8, casting to f64 and
// accumulating as u16
let res: u16 = dot_product::<f64, _, _, _>(&x, &w);
println!("{:?}", res);

Dependencies

~190KB