Skip to content

Commit

Permalink
Support SIMD on Rust stable (#520)
Browse files Browse the repository at this point in the history
* Remove dependency on `packed_simd`

* Support SIMD on stable Rust

* Move `packed_simd.rs` to `vector` module

* Add comment header to `packed_simd.rs`

* Initialize SIMD registers using intrinsics instead of `transmute`

* Use a splat inside of `unpack_pair`

* Update README: the AVX2 backend now works on stable Rust

* Add a CI job to also build the AVX2 SIMD backend on Rust stable

* Added SIMD MSRV test
  • Loading branch information
koute authored Mar 30, 2023
1 parent f460ae1 commit 4583c47
Show file tree
Hide file tree
Showing 11 changed files with 1,194 additions and 862 deletions.
16 changes: 15 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- run: cargo build --target thumbv7em-none-eabi --release
- run: cargo build --target thumbv7em-none-eabi --release --features serde

build-simd:
build-simd-nightly:
name: Build simd backend (nightly)
runs-on: ubuntu-latest
steps:
Expand All @@ -69,6 +69,16 @@ jobs:
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx512ifma'
run: cargo build --target x86_64-unknown-linux-gnu

test-simd-avx2:
name: Test simd backend (avx2)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- env:
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo test --target x86_64-unknown-linux-gnu

build-docs:
name: Build docs
runs-on: ubuntu-latest
Expand Down Expand Up @@ -151,6 +161,10 @@ jobs:
# deps and the stated MSRV
- uses: dtolnay/[email protected]
- run: cargo build --no-default-features --features serde
# Also make sure the AVX2 build works
- env:
RUSTFLAGS: '--cfg curve25519_dalek_backend="simd" -C target_feature=+avx2'
run: cargo build --target x86_64-unknown-linux-gnu

bench:
name: Check that benchmarks compile
Expand Down
6 changes: 1 addition & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ rand_core = { version = "0.6", default-features = false, features = ["getrandom"

[build-dependencies]
platforms = "3.0.2"
rustc_version = "0.4.0"

[[bench]]
name = "dalek_benchmarks"
Expand All @@ -57,11 +58,6 @@ zeroize = { version = "1", default-features = false, optional = true }
[target.'cfg(curve25519_dalek_backend = "fiat")'.dependencies]
fiat-crypto = "0.1.19"

# The original packed_simd package was orphaned, see
# https://github.com/rust-lang/packed_simd/issues/303#issuecomment-701361161
[target.'cfg(curve25519_dalek_backend = "simd")'.dependencies]
packed_simd = { version = "0.3.8", package = "packed_simd_2", features = ["into_bits"] }

[features]
default = ["alloc", "precomputed-tables", "zeroize"]
alloc = ["zeroize?/alloc"]
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ $ cargo build --target i686-unknown-linux-gnu
Target backend selection within `simd` must be done manually by setting the
`RUSTFLAGS` environment variable to one of the below options:

| CPU feature | `RUSTFLAGS` |
| :--- | :--- |
| avx2 | `-C target_feature=+avx2` |
| avx512ifma | `-C target_feature=+avx512ifma` |
| CPU feature | `RUSTFLAGS` | Requires nightly? |
| :--- | :--- | :--- |
| avx2 | `-C target_feature=+avx2` | no |
| avx512ifma | `-C target_feature=+avx512ifma` | yes |

Or you can use `-C target_cpu=native` if you don't know what to set.

The `simd` backend also requires using nightly, e.g. by running `cargo
+nightly build`, to build.
The AVX512 backend requires Rust nightly. If enabled and when compiled on a non-nightly
compiler it will fall back to using the AVX2 backend.

# Documentation

Expand Down
8 changes: 8 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ fn main() {
DalekBits::Dalek64 => println!("cargo:rustc-cfg=curve25519_dalek_bits=\"64\""),
DalekBits::Dalek32 => println!("cargo:rustc-cfg=curve25519_dalek_bits=\"32\""),
}

if rustc_version::version_meta()
.expect("failed to detect rustc version")
.channel
== rustc_version::Channel::Nightly
{
println!("cargo:rustc-cfg=nightly");
}
}

// Deterministic cfg(curve25519_dalek_bits) when this is not explicitly set.
Expand Down
Loading

0 comments on commit 4583c47

Please sign in to comment.