diff --git a/.cargo/config.toml b/.cargo/config.toml index b7efcef..f6cdd9a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,17 @@ [build] -rustflags = ["-Clinker-plugin-lto", "-Clinker=clang-13", "-Clink-arg=-fuse-ld=lld-13", "-Ctarget-cpu=native"] -rustdocflags = ["-Clinker-plugin-lto", "-Clinker=clang-13", "-Clink-arg=-fuse-ld=lld-13", "--cfg", "docsrs"] +rustflags = [ + "-Clinker-plugin-lto", + "-Clinker=clang-19", + "-Clink-arg=-fuse-ld=lld-19", + "-Ctarget-cpu=native", +] +rustdocflags = [ + "-Clinker-plugin-lto", + "-Clinker=clang-19", + "-Clink-arg=-fuse-ld=lld-19", + "--cfg", + "docsrs", +] [env] -CC = "clang-13" +CC = "clang-19" diff --git a/.devcontainer/Dockerfile.devcontainer b/.devcontainer/Dockerfile.devcontainer new file mode 100644 index 0000000..7ff6f12 --- /dev/null +++ b/.devcontainer/Dockerfile.devcontainer @@ -0,0 +1,44 @@ +FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye + +# Include lld linker to improve build times either by using environment variable +# RUSTFLAGS="-C link-arg=-fuse-ld=lld" or with Cargo's configuration file (i.e see .cargo/config.toml). +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install clang lld \ + && apt-get autoremove -y && apt-get clean -y + +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install --no-install-recommends \ + linux-perf \ + valgrind \ + && apt-get clean -y && rm -rf /var/lib/apt/lists/* + +RUN cp /usr/bin/perf_5.10 /usr/bin/perf + +RUN cd /tmp && \ + wget -qO- https://sourceware.org/pub/valgrind/valgrind-3.24.0.tar.bz2 | tar xj && \ + cd valgrind-3.24.0 && \ + ./configure && \ + make -j && \ + make install && \ + cd .. && \ + rm -rf valgrind-3.24.0 + +# Add llvm 19 apt sources +RUN echo "deb http://apt.llvm.org/bullseye/ llvm-toolchain-bullseye-19 main" >> /etc/apt/sources.list.d/llvm.list && \ + echo "deb-src http://apt.llvm.org/bullseye/ llvm-toolchain-bullseye-19 main" >> /etc/apt/sources.list.d/llvm.list && \ + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ + apt-get update && \ + apt-get install -y --no-install-recommends clang-19 lld-19 + + +# Install & configure delta diff tool +RUN wget -O- https://github.com/dandavison/delta/releases/download/0.18.2/git-delta_0.18.2_amd64.deb > /tmp/git-delta.deb && \ +sudo dpkg -i /tmp/git-delta.deb && \ +rm /tmp/git-delta.deb + +RUN git config --system core.pager "delta" && \ + git config --system interactive.diffFilter "delta --color-only" && \ + git config --system delta.navigate true && \ + git config --system delta.dark true && \ + git config --system delta.side-by-side true && \ + git config --system merge.conflictstyle "zdiff3" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..6848846 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,37 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/rust +{ + "name": "Rust", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "build": { + "dockerfile": "Dockerfile.devcontainer" + }, + "features": { + "ghcr.io/meaningful-ooo/devcontainer-features/fish:1": {}, + "ghcr.io/nikobockerman/devcontainer-features/fish-persistent-data:2": {} + } + + // Use 'mounts' to make the cargo cache persistent in a Docker Volume. + // "mounts": [ + // { + // "source": "devcontainer-cargo-cache-${devcontainerId}", + // "target": "/usr/local/cargo", + // "type": "volume" + // } + // ] + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "rustc --version", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f33a02c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for more information: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +# https://containers.dev/guide/dependabot + +version: 2 +updates: + - package-ecosystem: "devcontainers" + directory: "/" + schedule: + interval: weekly diff --git a/Cargo.toml b/Cargo.toml index b115b65..a3d2404 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,16 +24,18 @@ harness = false required-features = ["nalgebra-v029"] [features] -default = ["num-traits"] +default = ["num-traits", "wide"] # optional trait implementations nalgebra-v021 = ["num-traits", "nalgebra_v021", "simba_v01", "approx_v03"] nalgebra-v029 = ["num-traits", "nalgebra_v029", "simba_v06", "approx_v05"] +wide = ["wide-v07"] [dependencies] paste = "1" num-traits = { version = "0.2", optional = true } +wide-v07 = { package = "wide", version = "0.7", optional = true } approx_v03 = { package = "approx", version = "0.3", optional = true } nalgebra_v021 = { package = "nalgebra", version = "0.21", optional = true } @@ -42,6 +44,8 @@ simba_v01 = { package = "simba", version = "0.1", optional = true } approx_v05 = { package = "approx", version = "0.5", optional = true } nalgebra_v029 = { package = "nalgebra", version = "0.29", optional = true } simba_v06 = { package = "simba", version = "0.6", optional = true } +rand = "0.8" + [build-dependencies] cc = "1" @@ -51,8 +55,8 @@ criterion = { version = "0.3", features = ["html_reports"] } rand = "0.8" [profile.release] -lto="thin" -codegen-units=1 +lto = "thin" +codegen-units = 1 [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 43c989b..0000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.56.1 diff --git a/src/lib.rs b/src/lib.rs index c08a582..216d3a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ #![doc = include_str!("../README.md")] -#![cfg_attr(docsrs, feature(doc_cfg))] use core::{ cmp, fmt, @@ -7,6 +6,7 @@ use core::{ num::FpCategory, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}, }; +use std::borrow::Borrow; macro_rules! forward_freeze_self { ($fast_ty:ident, $base_ty:ident @@ -41,9 +41,14 @@ macro_rules! forward_freeze_self { mod math; mod nalgebra; mod num_traits; +mod wide; mod poison; use poison::MaybePoison; +use rand::{ + distributions::uniform::{SampleBorrow, SampleUniform, UniformFloat, UniformSampler}, + Rng, +}; // The big challenge with fast-math in general is avoiding UB, and to a lesser extent unspecified // values. LLVM's fast operations document "poison" behavior when given invalid inputs; poison @@ -469,3 +474,73 @@ macro_rules! impls { impls! { FF32, f32 } impls! { FF64, f64 } + +pub struct UniformFF32(UniformFloat); +pub struct UniformFF64(UniformFloat); + +impl UniformSampler for UniformFF32 { + type X = FF32; + + fn new(low: B1, high: B2) -> Self + where + B1: SampleBorrow + Sized, + B2: SampleBorrow + Sized, + { + UniformFF32(UniformFloat::::new( + low.borrow().freeze_raw(), + high.borrow().freeze_raw(), + )) + } + + fn new_inclusive(low: B1, high: B2) -> Self + where + B1: SampleBorrow + Sized, + B2: SampleBorrow + Sized, + { + UniformFF32(UniformFloat::::new_inclusive( + low.borrow().freeze_raw(), + high.borrow().freeze_raw(), + )) + } + + fn sample(&self, rng: &mut R) -> FF32 { + FF32::new(self.0.sample(rng)) + } +} +impl SampleUniform for FF32 { + type Sampler = UniformFF32; +} + +impl UniformSampler for UniformFF64 { + type X = FF64; + + fn new(low: B1, high: B2) -> Self + where + B1: SampleBorrow + Sized, + B2: SampleBorrow + Sized, + { + UniformFF64(UniformFloat::::new( + low.borrow().freeze_raw(), + high.borrow().freeze_raw(), + )) + } + + fn new_inclusive(low: B1, high: B2) -> Self + where + B1: SampleBorrow + Sized, + B2: SampleBorrow + Sized, + { + UniformFF64(UniformFloat::::new_inclusive( + low.borrow().freeze_raw(), + high.borrow().freeze_raw(), + )) + } + + fn sample(&self, rng: &mut R) -> FF64 { + FF64::new(self.0.sample(rng)) + } +} + +impl SampleUniform for FF64 { + type Sampler = UniformFF64; +} diff --git a/src/num_traits.rs b/src/num_traits.rs index 2c0081e..4156e02 100644 --- a/src/num_traits.rs +++ b/src/num_traits.rs @@ -1,5 +1,4 @@ #![cfg(feature = "num-traits")] -#![cfg_attr(docsrs, doc(cfg(feature = "num-traits")))] use crate::{FF32, FF64}; diff --git a/src/wide.rs b/src/wide.rs new file mode 100644 index 0000000..0a967c6 --- /dev/null +++ b/src/wide.rs @@ -0,0 +1,10 @@ +#![cfg(feature = "wide")] + +use crate::FF32; +use wide_v07::f32x8; + +// impl Into for &[FF32] { +// fn into(self) -> f32x8 { +// f32x8::new(self.try_into().unwrap()) +// } +// }