From 6140c3bb14c5f47de944c0e3727a73da7466224a Mon Sep 17 00:00:00 2001 From: nemo Date: Wed, 7 Apr 2021 16:05:50 -0400 Subject: [PATCH 1/8] feat: allow M1 building by removing asm sha on aarch64 --- sha2raw/Cargo.toml | 6 +++++- sha2raw/src/platform.rs | 4 +++- storage-proofs-core/src/lib.rs | 1 + storage-proofs-porep/Cargo.toml | 7 ++++--- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sha2raw/Cargo.toml b/sha2raw/Cargo.toml index 366bbaab8..82ceb4ff0 100644 --- a/sha2raw/Cargo.toml +++ b/sha2raw/Cargo.toml @@ -30,8 +30,12 @@ sha2 = "0.9.1" rand = "0.7.3" rand_xorshift = "0.2.0" -[features] +[target."cfg(target_arch = \"aarch64\")".features] +default = [] +[target."cfg(not(target_arch = \"aarch64\"))".features] default = ["asm"] + +[features] asm = ["sha2-asm"] diff --git a/sha2raw/src/platform.rs b/sha2raw/src/platform.rs index 759e2a0d2..45d0a0bf5 100644 --- a/sha2raw/src/platform.rs +++ b/sha2raw/src/platform.rs @@ -1,4 +1,6 @@ -use crate::{sha256_intrinsics, sha256_utils}; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +use crate::sha256_intrinsics; +use crate::sha256_utils; #[allow(dead_code)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] diff --git a/storage-proofs-core/src/lib.rs b/storage-proofs-core/src/lib.rs index fc55097bc..9cd421739 100644 --- a/storage-proofs-core/src/lib.rs +++ b/storage-proofs-core/src/lib.rs @@ -8,6 +8,7 @@ #![warn(clippy::ptr_arg)] #![warn(clippy::unnecessary_lazy_evaluations)] #![warn(clippy::redundant_slicing)] +#![allow(bare_trait_objects)] use std::convert::TryInto; diff --git a/storage-proofs-porep/Cargo.toml b/storage-proofs-porep/Cargo.toml index 8c1ff57f6..4912d67f8 100644 --- a/storage-proofs-porep/Cargo.toml +++ b/storage-proofs-porep/Cargo.toml @@ -40,9 +40,10 @@ libc = "0.2" fdlimit = "0.2.0" fr32 = { path = "../fr32", version = "^0.2.0", default-features = false } -[target."cfg(target_arch = \"aarch64\")".dependencies] -sha2 = { version = "0.9.3", features = ["compress", "asm"] } -[target."cfg(not(target_arch = \"aarch64\"))".dependencies] +#[target."cfg(target_arch = \"aarch64\")".dependencies] +#sha2 = { version = "0.9.3", features = ["compress", "asm"] } +#[target."cfg(not(target_arch = \"aarch64\"))".dependencies] +#sha2 = { version = "0.9.3", features = ["compress"] } sha2 = { version = "0.9.3", features = ["compress"] } [dev-dependencies] From 5aa36ccf776bec01c566153c98c0f15c2c5dc791 Mon Sep 17 00:00:00 2001 From: nemo Date: Tue, 13 Apr 2021 15:54:33 -0400 Subject: [PATCH 2/8] fix: align struct and unsafely cast buffer when using on aarch64 --- fr32/src/reader.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fr32/src/reader.rs b/fr32/src/reader.rs index 51edd954d..59d46bea1 100644 --- a/fr32/src/reader.rs +++ b/fr32/src/reader.rs @@ -19,6 +19,7 @@ const NUM_U128S_PER_BLOCK: usize = NUM_BYTES_OUT_BLOCK / size_of::(); const MASK_SKIP_HIGH_2: u128 = 0b0011_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111; /// An `io::Reader` that converts unpadded input into valid `Fr32` padded output. +#[repr(align(16))] pub struct Fr32Reader { /// The source being padded. source: R, @@ -65,7 +66,14 @@ impl Fr32Reader { /// Processes a single block in in_buffer, writing the result to out_buffer. fn process_block(&mut self) { - let in_buffer: &[u128] = self.in_buffer.as_slice_of::().unwrap(); + let in_buffer: &[u128] = { + #[cfg(target_arch = "aarch64")] + unsafe { + &mut (*(&self.in_buffer as *const [u8] as *mut [u128])) + } + #[cfg(not(target_arch = "aarch64"))] + self.in_buffer.as_slice_of::().unwrap() + }; let out = &mut self.out_buffer; // 0..254 From c5033bc72bf0bcb48f0184ecc00cc806d560da20 Mon Sep 17 00:00:00 2001 From: nemo Date: Wed, 14 Apr 2021 15:38:00 -0400 Subject: [PATCH 3/8] feat: add arm builds as CI targets fix: upgrade arm to large build instance and split up blst/pairing fix: make sure we're building & running in release mode fix: replace arm.large with arm.medium to conserve CI resources --- .circleci/config.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ffeb87844..47e3188d3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,6 +16,10 @@ executors: image: ubuntu-1604-cuda-10.1:201909-23 working_directory: ~/gpuci resource_class: gpu.nvidia.medium + arm: + machine: + image: ubuntu-2004:202101-01 + resource_class: arm.large setup-env: &setup-env FIL_PROOFS_PARAMETER_CACHE: "/tmp/filecoin-proof-parameters/" @@ -207,6 +211,35 @@ jobs: cargo +<< pipeline.parameters.nightly-toolchain >> -Zpackage-features test --all --verbose --no-default-features --features << parameters.features >> no_output_timeout: 30m + test_arm_no_gpu: + executor: arm + environment: *setup-env + steps: + - checkout + - attach_workspace: + at: "." + - restore_rustup_cache + - restore_parameter_cache + - run: + name: Install Rust + command: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + - run: rustup install $(cat rust-toolchain) + - run: rustup default $(cat rust-toolchain) + - run: rustup install << pipeline.parameters.nightly-toolchain >> + - run: cargo update + - run: cargo fetch + - run: + name: Install required libraries + command: | + sudo apt-get update -y + sudo apt install -y libhwloc-dev + - run: + name: Test arm with no gpu (<< parameters.features >>) + command: | + cargo +<< pipeline.parameters.nightly-toolchain >> -Zpackage-features test --release --all --verbose --no-default-features --features << parameters.features >> + no_output_timeout: 90m + test_blst: executor: default environment: *setup-env @@ -584,6 +617,19 @@ workflows: - cargo_fetch - ensure_groth_parameters_and_keys_linux + - test_arm_no_gpu: + name: test_no_gpu_pairing + features: 'pairing' + requires: + - cargo_fetch + - ensure_groth_parameters_and_keys_linux + + - test_arm_no_gpu: + name: test_no_gpu_blst + features: 'blst' + requires: + - cargo_fetch + - ensure_groth_parameters_and_keys_linux - bench: requires: From 623394e9cb87c331db1295b1895a0d61424968af Mon Sep 17 00:00:00 2001 From: nemo Date: Wed, 21 Apr 2021 07:54:31 -0400 Subject: [PATCH 4/8] fix: add CI features for arm tests --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 47e3188d3..363098287 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -214,6 +214,9 @@ jobs: test_arm_no_gpu: executor: arm environment: *setup-env + parameters: + features: + type: string steps: - checkout - attach_workspace: From b3717844ead0245962ea608cdcf07fd262e599ab Mon Sep 17 00:00:00 2001 From: nemo Date: Fri, 23 Apr 2021 10:58:18 -0400 Subject: [PATCH 5/8] fix: assign proper names to arm tests --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 363098287..f01e8acb3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -621,14 +621,14 @@ workflows: - ensure_groth_parameters_and_keys_linux - test_arm_no_gpu: - name: test_no_gpu_pairing + name: test_arm_no_gpu_pairing features: 'pairing' requires: - cargo_fetch - ensure_groth_parameters_and_keys_linux - test_arm_no_gpu: - name: test_no_gpu_blst + name: test_arm_no_gpu_blst features: 'blst' requires: - cargo_fetch From f43895f2d00369326f9c2442adff205574e3d4c1 Mon Sep 17 00:00:00 2001 From: nemo Date: Mon, 26 Apr 2021 09:49:00 -0400 Subject: [PATCH 6/8] fix: use asm feature on aarch64 unless also on macos --- sha2raw/Cargo.toml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sha2raw/Cargo.toml b/sha2raw/Cargo.toml index 82ceb4ff0..b9d958ce6 100644 --- a/sha2raw/Cargo.toml +++ b/sha2raw/Cargo.toml @@ -30,12 +30,11 @@ sha2 = "0.9.1" rand = "0.7.3" rand_xorshift = "0.2.0" -[target."cfg(target_arch = \"aarch64\")".features] +[features] +[target."cfg(all(target_os = \"macos\", target_arch = \"aarch64\"))".features] default = [] -[target."cfg(not(target_arch = \"aarch64\"))".features] +[target."cfg(not(all(target_os = \"macos\", target_arch = \"aarch64\")))".features] default = ["asm"] - -[features] -asm = ["sha2-asm"] +asm = ["sha2-asm", "asm"] From 11f3fa606632679126c00b2ce90c139b43ddee99 Mon Sep 17 00:00:00 2001 From: nemo Date: Tue, 27 Apr 2021 11:53:33 -0400 Subject: [PATCH 7/8] fix: add AlignedBuffer type to ensure alignment correctness --- fr32/src/reader.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/fr32/src/reader.rs b/fr32/src/reader.rs index 59d46bea1..601a4c259 100644 --- a/fr32/src/reader.rs +++ b/fr32/src/reader.rs @@ -18,15 +18,17 @@ const NUM_U128S_PER_BLOCK: usize = NUM_BYTES_OUT_BLOCK / size_of::(); const MASK_SKIP_HIGH_2: u128 = 0b0011_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111; -/// An `io::Reader` that converts unpadded input into valid `Fr32` padded output. #[repr(align(16))] +struct AlignedBuffer([u8; NUM_BYTES_IN_BLOCK + 1]); + +/// An `io::Reader` that converts unpadded input into valid `Fr32` padded output. pub struct Fr32Reader { /// The source being padded. source: R, /// Currently read block. /// This is padded to 128 bytes to allow reading all values as `u128`s, but only the first /// 127 bytes are ever valid. - in_buffer: [u8; NUM_BYTES_IN_BLOCK + 1], + in_buffer: AlignedBuffer, /// Currently writing out block. out_buffer: [u128; NUM_U128S_PER_BLOCK], /// The current offset into the `out_buffer` in bytes. @@ -56,7 +58,7 @@ impl Fr32Reader { pub fn new(source: R) -> Self { Fr32Reader { source, - in_buffer: [0; NUM_BYTES_IN_BLOCK + 1], + in_buffer: AlignedBuffer([0; NUM_BYTES_IN_BLOCK + 1]), out_buffer: [0; NUM_U128S_PER_BLOCK], out_offset: 0, available_frs: 0, @@ -68,11 +70,14 @@ impl Fr32Reader { fn process_block(&mut self) { let in_buffer: &[u128] = { #[cfg(target_arch = "aarch64")] + // Safety: This is safe because the struct/data is aligned on + // a 16 byte boundary and can therefore be casted from u128 + // to u8 without alignment safety issues. unsafe { - &mut (*(&self.in_buffer as *const [u8] as *mut [u128])) + &mut (*(&self.in_buffer.0 as *const [u8] as *mut [u128])) } #[cfg(not(target_arch = "aarch64"))] - self.in_buffer.as_slice_of::().unwrap() + self.in_buffer.0.as_slice_of::().unwrap() }; let out = &mut self.out_buffer; @@ -94,7 +99,7 @@ impl Fr32Reader { fn fill_in_buffer(&mut self) -> io::Result { let mut bytes_read = 0; - let mut buf = &mut self.in_buffer[..NUM_BYTES_IN_BLOCK]; + let mut buf = &mut self.in_buffer.0[..NUM_BYTES_IN_BLOCK]; while !buf.is_empty() { match self.source.read(buf) { @@ -111,7 +116,7 @@ impl Fr32Reader { } // Clear unfilled memory. - for val in &mut self.in_buffer[bytes_read..NUM_BYTES_IN_BLOCK] { + for val in &mut self.in_buffer.0[bytes_read..NUM_BYTES_IN_BLOCK] { *val = 0; } From 983e8a230b1d98bfcd88d92c80e287bcaeed4524 Mon Sep 17 00:00:00 2001 From: nemo Date: Tue, 27 Apr 2021 14:54:04 -0400 Subject: [PATCH 8/8] fix: use asm on aarch64 if not macos/m1 --- sha2raw/Cargo.toml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sha2raw/Cargo.toml b/sha2raw/Cargo.toml index b9d958ce6..22808a213 100644 --- a/sha2raw/Cargo.toml +++ b/sha2raw/Cargo.toml @@ -31,10 +31,14 @@ rand = "0.7.3" rand_xorshift = "0.2.0" [features] -[target."cfg(all(target_os = \"macos\", target_arch = \"aarch64\"))".features] -default = [] -[target."cfg(not(all(target_os = \"macos\", target_arch = \"aarch64\")))".features] + +[target.'cfg(all(target_arch = "aarch64", not(target_os = "macos")))'.features] +default = ["asm"] +[target.'cfg(not(target_arch = "aarch64"))'.features] default = ["asm"] +[target.'cfg(all(target_arch = "aarch64", target_os = "macos"))'.features] +default = [] + asm = ["sha2-asm", "asm"]