From e22cb5941cf037269007f6d8ac8a3c62f65203eb Mon Sep 17 00:00:00 2001 From: HEnquist Date: Sat, 30 Aug 2025 17:51:01 +0200 Subject: [PATCH 1/6] Use u64 in Raders twiddle calculations --- src/algorithm/raders_algorithm.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/algorithm/raders_algorithm.rs b/src/algorithm/raders_algorithm.rs index 76ae34b..89b5a3d 100644 --- a/src/algorithm/raders_algorithm.rs +++ b/src/algorithm/raders_algorithm.rs @@ -91,7 +91,8 @@ impl RadersAlgorithm { let twiddle = twiddles::compute_twiddle(twiddle_input, len, direction); *input_cell = twiddle * inner_fft_scale; - twiddle_input = (twiddle_input * primitive_root_inverse) % reduced_len; + twiddle_input = + ((twiddle_input as u64 * primitive_root_inverse as u64) % len as u64) as usize; } let required_inner_scratch = inner_fft.get_inplace_scratch_len(); @@ -290,7 +291,7 @@ boilerplate_fft!( mod unit_tests { use super::*; use crate::algorithm::Dft; - use crate::test_utils::check_fft_algorithm; + use crate::test_utils::{check_fft_algorithm, BigScratchAlgorithm}; use std::sync::Arc; #[test] @@ -303,6 +304,24 @@ mod unit_tests { } } + #[test] + fn test_construct_big_raders() { + // Construct Raders instances for a few large primes + // that could cause overflow errors on 32-bit builds. + for len in [112501, 216569, 417623] { + let dummy_fft = BigScratchAlgorithm { + len: len - 1, + inplace_scratch: len - 1, + outofplace_scratch: len - 1, + immut_scratch: len - 1, + direction: FftDirection::Forward, + }; + let inner_fft: Arc = Arc::new(dummy_fft); + let fft: RadersAlgorithm = RadersAlgorithm::new(inner_fft); + assert_eq!(fft.len(), len); + } + } + fn test_raders_with_length(len: usize, direction: FftDirection) { let inner_fft = Arc::new(Dft::new(len - 1, direction)); let fft = RadersAlgorithm::new(inner_fft); From aa9e59a3e21c8790b4f5de484a92890afdb0fa59 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Tue, 2 Sep 2025 20:54:38 +0200 Subject: [PATCH 2/6] Perform fft with big Raders --- src/algorithm/raders_algorithm.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/algorithm/raders_algorithm.rs b/src/algorithm/raders_algorithm.rs index 89b5a3d..e2a0ff9 100644 --- a/src/algorithm/raders_algorithm.rs +++ b/src/algorithm/raders_algorithm.rs @@ -291,7 +291,8 @@ boilerplate_fft!( mod unit_tests { use super::*; use crate::algorithm::Dft; - use crate::test_utils::{check_fft_algorithm, BigScratchAlgorithm}; + use crate::test_utils::check_fft_algorithm; + use crate::FftPlanner; use std::sync::Arc; #[test] @@ -305,20 +306,15 @@ mod unit_tests { } #[test] - fn test_construct_big_raders() { - // Construct Raders instances for a few large primes - // that could cause overflow errors on 32-bit builds. + fn test_raders_32bit_overflow() { + // Construct and use Raders instances for a few large primes + // that could panic due to overflow errors on 32-bit builds. + let mut planner = FftPlanner::::new(); for len in [112501, 216569, 417623] { - let dummy_fft = BigScratchAlgorithm { - len: len - 1, - inplace_scratch: len - 1, - outofplace_scratch: len - 1, - immut_scratch: len - 1, - direction: FftDirection::Forward, - }; - let inner_fft: Arc = Arc::new(dummy_fft); + let inner_fft = planner.plan_fft_forward(len - 1); let fft: RadersAlgorithm = RadersAlgorithm::new(inner_fft); - assert_eq!(fft.len(), len); + let mut data = vec![Complex::new(0.0, 0.0); len]; + fft.process(&mut data); } } From 1b9bcadfd6411ca3d6e975553ab848227922e721 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Tue, 2 Sep 2025 21:06:20 +0200 Subject: [PATCH 3/6] Fix overflow on Raders processing --- src/algorithm/raders_algorithm.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/algorithm/raders_algorithm.rs b/src/algorithm/raders_algorithm.rs index e2a0ff9..924ff44 100644 --- a/src/algorithm/raders_algorithm.rs +++ b/src/algorithm/raders_algorithm.rs @@ -4,7 +4,7 @@ use num_complex::Complex; use num_integer::Integer; use num_traits::Zero; use primal_check::miller_rabin; -use strength_reduce::StrengthReducedUsize; +use strength_reduce::StrengthReducedU64; use crate::math_utils; use crate::{common::FftNum, twiddles, FftDirection}; @@ -45,7 +45,7 @@ pub struct RadersAlgorithm { primitive_root: usize, primitive_root_inverse: usize, - len: StrengthReducedUsize, + len: StrengthReducedU64, inplace_scratch_len: usize, outofplace_scratch_len: usize, immut_scratch_len: usize, @@ -68,7 +68,7 @@ impl RadersAlgorithm { assert!(miller_rabin(len as u64), "For raders algorithm, inner_fft.len() + 1 must be prime. Expected prime number, got {} + 1 = {}", inner_fft_len, len); let direction = inner_fft.fft_direction(); - let reduced_len = StrengthReducedUsize::new(len); + let reduced_len = StrengthReducedU64::new(len as u64); // compute the primitive root and its inverse for this size let primitive_root = math_utils::primitive_root(len as u64).unwrap() as usize; @@ -92,7 +92,7 @@ impl RadersAlgorithm { *input_cell = twiddle * inner_fft_scale; twiddle_input = - ((twiddle_input as u64 * primitive_root_inverse as u64) % len as u64) as usize; + ((twiddle_input as u64 * primitive_root_inverse as u64) % reduced_len) as usize; } let required_inner_scratch = inner_fft.get_inplace_scratch_len(); @@ -137,7 +137,7 @@ impl RadersAlgorithm { // copy the input into the scratch space, reordering as we go let mut input_index = 1; for output_element in scratch.iter_mut() { - input_index = (input_index * self.primitive_root) % self.len; + input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; let input_element = input[input_index - 1]; *output_element = input_element; @@ -165,7 +165,8 @@ impl RadersAlgorithm { // copy the final values into the output, reordering as we go let mut output_index = 1; for scratch_element in scratch { - output_index = (output_index * self.primitive_root_inverse) % self.len; + output_index = + ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; output[output_index - 1] = scratch_element.conj(); } } @@ -183,7 +184,7 @@ impl RadersAlgorithm { // copy the input into the output, reordering as we go. also compute a sum of all elements let mut input_index = 1; for output_element in output.iter_mut() { - input_index = (input_index * self.primitive_root) % self.len; + input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; let input_element = input[input_index - 1]; *output_element = input_element; @@ -226,7 +227,8 @@ impl RadersAlgorithm { // copy the final values into the output, reordering as we go let mut output_index = 1; for input_element in input { - output_index = (output_index * self.primitive_root_inverse) % self.len; + output_index = + ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; output[output_index - 1] = input_element.conj(); } } @@ -240,7 +242,7 @@ impl RadersAlgorithm { // copy the buffer into the scratch, reordering as we go. also compute a sum of all elements let mut input_index = 1; for scratch_element in scratch.iter_mut() { - input_index = (input_index * self.primitive_root) % self.len; + input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; let buffer_element = buffer[input_index - 1]; *scratch_element = buffer_element; @@ -274,14 +276,15 @@ impl RadersAlgorithm { // copy the final values into the output, reordering as we go let mut output_index = 1; for scratch_element in scratch { - output_index = (output_index * self.primitive_root_inverse) % self.len; + output_index = + ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; buffer[output_index - 1] = scratch_element.conj(); } } } boilerplate_fft!( RadersAlgorithm, - |this: &RadersAlgorithm<_>| this.len.get(), + |this: &RadersAlgorithm<_>| this.len.get() as usize, |this: &RadersAlgorithm<_>| this.inplace_scratch_len, |this: &RadersAlgorithm<_>| this.outofplace_scratch_len, |this: &RadersAlgorithm<_>| this.immut_scratch_len From 76ce63bb1d0e9646ac963a7035b1ca8f6ef424d0 Mon Sep 17 00:00:00 2001 From: HEnquist Date: Sat, 6 Sep 2025 07:09:06 +0200 Subject: [PATCH 4/6] Reduce number of casts --- src/algorithm/raders_algorithm.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/algorithm/raders_algorithm.rs b/src/algorithm/raders_algorithm.rs index 924ff44..5bc45e1 100644 --- a/src/algorithm/raders_algorithm.rs +++ b/src/algorithm/raders_algorithm.rs @@ -42,8 +42,8 @@ pub struct RadersAlgorithm { inner_fft: Arc>, inner_fft_data: Box<[Complex]>, - primitive_root: usize, - primitive_root_inverse: usize, + primitive_root: u64, + primitive_root_inverse: u64, len: StrengthReducedU64, inplace_scratch_len: usize, @@ -71,7 +71,7 @@ impl RadersAlgorithm { let reduced_len = StrengthReducedU64::new(len as u64); // compute the primitive root and its inverse for this size - let primitive_root = math_utils::primitive_root(len as u64).unwrap() as usize; + let primitive_root = math_utils::primitive_root(len as u64).unwrap(); // compute the multiplicative inverse of primative_root mod len and vice versa. // i64::extended_gcd will compute both the inverse of left mod right, and the inverse of right mod left, but we're only goingto use one of them @@ -81,7 +81,7 @@ impl RadersAlgorithm { gcd_data.x } else { gcd_data.x + len as i64 - } as usize; + } as u64; // precompute the coefficients to use inside the process method let inner_fft_scale = T::one() / T::from_usize(inner_fft_len).unwrap(); @@ -92,7 +92,7 @@ impl RadersAlgorithm { *input_cell = twiddle * inner_fft_scale; twiddle_input = - ((twiddle_input as u64 * primitive_root_inverse as u64) % reduced_len) as usize; + ((twiddle_input as u64 * primitive_root_inverse) % reduced_len) as usize; } let required_inner_scratch = inner_fft.get_inplace_scratch_len(); @@ -137,7 +137,7 @@ impl RadersAlgorithm { // copy the input into the scratch space, reordering as we go let mut input_index = 1; for output_element in scratch.iter_mut() { - input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; + input_index = ((input_index as u64 * self.primitive_root) % self.len) as usize; let input_element = input[input_index - 1]; *output_element = input_element; @@ -166,7 +166,7 @@ impl RadersAlgorithm { let mut output_index = 1; for scratch_element in scratch { output_index = - ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; + ((output_index as u64 * self.primitive_root_inverse) % self.len) as usize; output[output_index - 1] = scratch_element.conj(); } } @@ -184,7 +184,7 @@ impl RadersAlgorithm { // copy the input into the output, reordering as we go. also compute a sum of all elements let mut input_index = 1; for output_element in output.iter_mut() { - input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; + input_index = ((input_index as u64 * self.primitive_root) % self.len) as usize; let input_element = input[input_index - 1]; *output_element = input_element; @@ -228,7 +228,7 @@ impl RadersAlgorithm { let mut output_index = 1; for input_element in input { output_index = - ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; + ((output_index as u64 * self.primitive_root_inverse) % self.len) as usize; output[output_index - 1] = input_element.conj(); } } @@ -242,7 +242,7 @@ impl RadersAlgorithm { // copy the buffer into the scratch, reordering as we go. also compute a sum of all elements let mut input_index = 1; for scratch_element in scratch.iter_mut() { - input_index = ((input_index as u64 * self.primitive_root as u64) % self.len) as usize; + input_index = ((input_index as u64 * self.primitive_root) % self.len) as usize; let buffer_element = buffer[input_index - 1]; *scratch_element = buffer_element; @@ -277,7 +277,7 @@ impl RadersAlgorithm { let mut output_index = 1; for scratch_element in scratch { output_index = - ((output_index as u64 * self.primitive_root_inverse as u64) % self.len) as usize; + ((output_index as u64 * self.primitive_root_inverse) % self.len) as usize; buffer[output_index - 1] = scratch_element.conj(); } } From 6790fadbabcb2b1ea28689d86e44900a9a23203e Mon Sep 17 00:00:00 2001 From: Elliott Mahler Date: Wed, 17 Sep 2025 20:35:44 -0700 Subject: [PATCH 5/6] Attempt to fix wasm simd test --- .github/workflows/run_test.yml | 2 +- src/wasm_simd/wasm_simd_common.rs | 7 +-- src/wasm_simd/wasm_simd_vector.rs | 71 +++++++++++++++---------------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/run_test.yml b/.github/workflows/run_test.yml index ce0dc09..17fc955 100644 --- a/.github/workflows/run_test.yml +++ b/.github/workflows/run_test.yml @@ -161,4 +161,4 @@ jobs: with: version: "latest" - name: Run test suites with wasm-pack - run: wasm-pack test --node --lib --features wasm_simd + run: wasm-pack test --node --features wasm_simd diff --git a/src/wasm_simd/wasm_simd_common.rs b/src/wasm_simd/wasm_simd_common.rs index 609f20e..9669309 100644 --- a/src/wasm_simd/wasm_simd_common.rs +++ b/src/wasm_simd/wasm_simd_common.rs @@ -33,11 +33,11 @@ macro_rules! interleave_complex_f32 { /// Shuffle elements to interleave two contiguous sets of f32, from an array of simd vectors to a new array of simd vectors /// This statement: -/// ``` +/// /// let values = separate_interleaved_complex_f32!(input, {0, 2, 4}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// extract_lo_lo_f32(input[0], input[1]), /// extract_lo_lo_f32(input[2], input[3]), @@ -46,6 +46,7 @@ macro_rules! interleave_complex_f32 { /// extract_hi_hi_f32(input[2], input[3]), /// extract_hi_hi_f32(input[4], input[5]), /// ]; +/// macro_rules! separate_interleaved_complex_f32 { ($input:ident, { $($idx:literal),* }) => { [ diff --git a/src/wasm_simd/wasm_simd_vector.rs b/src/wasm_simd/wasm_simd_vector.rs index 2d3d26b..551f166 100644 --- a/src/wasm_simd/wasm_simd_vector.rs +++ b/src/wasm_simd/wasm_simd_vector.rs @@ -11,18 +11,17 @@ use super::WasmNum; /// Read these indexes from an WasmSimdArray and build an array of simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// ``` +/// /// let values = read_complex_to_array!(input, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// input.load_complex(0), /// input.load_complex(1), /// input.load_complex(2), /// input.load_complex(3), /// ]; -/// ``` macro_rules! read_complex_to_array { ($input:ident, { $($idx:literal),* }) => { [ @@ -36,18 +35,18 @@ macro_rules! read_complex_to_array { /// Read these indexes from an WasmSimdArray and build an array or partially filled simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// ``` +/// /// let values = read_partial1_complex_to_array!(input, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// input.load1_complex(0), /// input.load1_complex(1), /// input.load1_complex(2), /// input.load1_complex(3), /// ]; -/// ``` +/// macro_rules! read_partial1_complex_to_array { ($input:ident, { $($idx:literal),* }) => { [ @@ -61,18 +60,18 @@ macro_rules! read_partial1_complex_to_array { /// Write these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// ``` +/// /// let values = write_complex_to_array!(input, output, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// output.store_complex(input[0], 0), /// output.store_complex(input[1], 1), /// output.store_complex(input[2], 2), /// output.store_complex(input[3], 3), /// ]; -/// ``` +/// macro_rules! write_complex_to_array { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -84,18 +83,18 @@ macro_rules! write_complex_to_array { /// Write the low half of these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// ``` +/// /// let values = write_partial_lo_complex_to_array!(input, output, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// output.store_partial_lo_complex(input[0], 0), /// output.store_partial_lo_complex(input[1], 1), /// output.store_partial_lo_complex(input[2], 2), /// output.store_partial_lo_complex(input[3], 3), /// ]; -/// ``` +/// macro_rules! write_partial_lo_complex_to_array { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -107,18 +106,18 @@ macro_rules! write_partial_lo_complex_to_array { /// Write these indexes of an array of simd vectors to the same indexes, multiplied by a stride, of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, an integer stride, and a list of indexes. /// This statement: -/// ``` +/// /// let values = write_complex_to_array_strided!(input, output, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// output.store_complex(input[0], 0), /// output.store_complex(input[1], 2), /// output.store_complex(input[2], 4), /// output.store_complex(input[3], 6), /// ]; -/// ``` +/// macro_rules! write_complex_to_array_strided { ($input:ident, $output:ident, $stride:literal, { $($idx:literal),* }) => { $( @@ -130,18 +129,18 @@ macro_rules! write_complex_to_array_strided { /// Read these indexes from an WasmSimdArray and build an array of simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// ``` +/// /// let values = read_complex_to_array_v128!(input, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// input.load_complex_v128(0), /// input.load_complex_v128(1), /// input.load_complex_v128(2), /// input.load_complex_v128(3), /// ]; -/// ``` +/// macro_rules! read_complex_to_array_v128 { ($input:ident, { $($idx:literal),* }) => { [ @@ -155,18 +154,18 @@ macro_rules! read_complex_to_array_v128 { /// Read these indexes from an WasmSimdArray and build an array or partially filled simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// ``` +/// /// let values = read_partial1_complex_to_array_v128!(input, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// input.load1_complex_v128(0), /// input.load1_complex_v128(1), /// input.load1_complex_v128(2), /// input.load1_complex_v128(3), /// ]; -/// ``` +/// macro_rules! read_partial1_complex_to_array_v128 { ($input:ident, { $($idx:literal),* }) => { [ @@ -180,18 +179,18 @@ macro_rules! read_partial1_complex_to_array_v128 { /// Write these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// ``` +/// /// let values = write_complex_to_array_v128!(input, output, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// output.store_complex_v128(input[0], 0), /// output.store_complex_v128(input[1], 1), /// output.store_complex_v128(input[2], 2), /// output.store_complex_v128(input[3], 3), /// ]; -/// ``` +/// macro_rules! write_complex_to_array_v128 { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -203,18 +202,18 @@ macro_rules! write_complex_to_array_v128 { /// Write these indexes of an array of simd vectors to the same indexes, multiplied by a stride, of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, an integer stride, and a list of indexes. /// This statement: -/// ``` +/// /// let values = write_complex_to_array_strided_v128!(input, output, {0, 1, 2, 3}); -/// ``` +/// /// is equivalent to: -/// ``` +/// /// let values = [ /// output.store_complex_v128(input[0], 0), /// output.store_complex_v128(input[1], 2), /// output.store_complex_v128(input[2], 4), /// output.store_complex_v128(input[3], 6), /// ]; -/// ``` +/// macro_rules! write_complex_to_array_strided_v128 { ($input:ident, $output:ident, $stride:literal, { $($idx:literal),* }) => { $( From 7dd5aa6252e441a62f0b1c80d25aaa29aee9f57a Mon Sep 17 00:00:00 2001 From: Elliott Mahler Date: Wed, 17 Sep 2025 20:36:51 -0700 Subject: [PATCH 6/6] cargo fmt --- src/wasm_simd/wasm_simd_common.rs | 8 ++-- src/wasm_simd/wasm_simd_vector.rs | 70 +++++++++++++++---------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/wasm_simd/wasm_simd_common.rs b/src/wasm_simd/wasm_simd_common.rs index 9669309..af32692 100644 --- a/src/wasm_simd/wasm_simd_common.rs +++ b/src/wasm_simd/wasm_simd_common.rs @@ -33,11 +33,11 @@ macro_rules! interleave_complex_f32 { /// Shuffle elements to interleave two contiguous sets of f32, from an array of simd vectors to a new array of simd vectors /// This statement: -/// +/// /// let values = separate_interleaved_complex_f32!(input, {0, 2, 4}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// extract_lo_lo_f32(input[0], input[1]), /// extract_lo_lo_f32(input[2], input[3]), @@ -46,7 +46,7 @@ macro_rules! interleave_complex_f32 { /// extract_hi_hi_f32(input[2], input[3]), /// extract_hi_hi_f32(input[4], input[5]), /// ]; -/// +/// macro_rules! separate_interleaved_complex_f32 { ($input:ident, { $($idx:literal),* }) => { [ diff --git a/src/wasm_simd/wasm_simd_vector.rs b/src/wasm_simd/wasm_simd_vector.rs index 551f166..11e6e41 100644 --- a/src/wasm_simd/wasm_simd_vector.rs +++ b/src/wasm_simd/wasm_simd_vector.rs @@ -11,11 +11,11 @@ use super::WasmNum; /// Read these indexes from an WasmSimdArray and build an array of simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// +/// /// let values = read_complex_to_array!(input, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// input.load_complex(0), /// input.load_complex(1), @@ -35,18 +35,18 @@ macro_rules! read_complex_to_array { /// Read these indexes from an WasmSimdArray and build an array or partially filled simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// +/// /// let values = read_partial1_complex_to_array!(input, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// input.load1_complex(0), /// input.load1_complex(1), /// input.load1_complex(2), /// input.load1_complex(3), /// ]; -/// +/// macro_rules! read_partial1_complex_to_array { ($input:ident, { $($idx:literal),* }) => { [ @@ -60,18 +60,18 @@ macro_rules! read_partial1_complex_to_array { /// Write these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// +/// /// let values = write_complex_to_array!(input, output, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// output.store_complex(input[0], 0), /// output.store_complex(input[1], 1), /// output.store_complex(input[2], 2), /// output.store_complex(input[3], 3), /// ]; -/// +/// macro_rules! write_complex_to_array { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -83,18 +83,18 @@ macro_rules! write_complex_to_array { /// Write the low half of these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// +/// /// let values = write_partial_lo_complex_to_array!(input, output, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// output.store_partial_lo_complex(input[0], 0), /// output.store_partial_lo_complex(input[1], 1), /// output.store_partial_lo_complex(input[2], 2), /// output.store_partial_lo_complex(input[3], 3), /// ]; -/// +/// macro_rules! write_partial_lo_complex_to_array { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -106,18 +106,18 @@ macro_rules! write_partial_lo_complex_to_array { /// Write these indexes of an array of simd vectors to the same indexes, multiplied by a stride, of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, an integer stride, and a list of indexes. /// This statement: -/// +/// /// let values = write_complex_to_array_strided!(input, output, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// output.store_complex(input[0], 0), /// output.store_complex(input[1], 2), /// output.store_complex(input[2], 4), /// output.store_complex(input[3], 6), /// ]; -/// +/// macro_rules! write_complex_to_array_strided { ($input:ident, $output:ident, $stride:literal, { $($idx:literal),* }) => { $( @@ -129,18 +129,18 @@ macro_rules! write_complex_to_array_strided { /// Read these indexes from an WasmSimdArray and build an array of simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// +/// /// let values = read_complex_to_array_v128!(input, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// input.load_complex_v128(0), /// input.load_complex_v128(1), /// input.load_complex_v128(2), /// input.load_complex_v128(3), /// ]; -/// +/// macro_rules! read_complex_to_array_v128 { ($input:ident, { $($idx:literal),* }) => { [ @@ -154,18 +154,18 @@ macro_rules! read_complex_to_array_v128 { /// Read these indexes from an WasmSimdArray and build an array or partially filled simd vectors. /// Takes a name of a vector to read from, and a list of indexes to read. /// This statement: -/// +/// /// let values = read_partial1_complex_to_array_v128!(input, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// input.load1_complex_v128(0), /// input.load1_complex_v128(1), /// input.load1_complex_v128(2), /// input.load1_complex_v128(3), /// ]; -/// +/// macro_rules! read_partial1_complex_to_array_v128 { ($input:ident, { $($idx:literal),* }) => { [ @@ -179,18 +179,18 @@ macro_rules! read_partial1_complex_to_array_v128 { /// Write these indexes of an array of simd vectors to the same indexes of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, and a list of indexes. /// This statement: -/// +/// /// let values = write_complex_to_array_v128!(input, output, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// output.store_complex_v128(input[0], 0), /// output.store_complex_v128(input[1], 1), /// output.store_complex_v128(input[2], 2), /// output.store_complex_v128(input[3], 3), /// ]; -/// +/// macro_rules! write_complex_to_array_v128 { ($input:ident, $output:ident, { $($idx:literal),* }) => { $( @@ -202,18 +202,18 @@ macro_rules! write_complex_to_array_v128 { /// Write these indexes of an array of simd vectors to the same indexes, multiplied by a stride, of an WasmSimdArray. /// Takes a name of a vector to read from, one to write to, an integer stride, and a list of indexes. /// This statement: -/// +/// /// let values = write_complex_to_array_strided_v128!(input, output, {0, 1, 2, 3}); -/// +/// /// is equivalent to: -/// +/// /// let values = [ /// output.store_complex_v128(input[0], 0), /// output.store_complex_v128(input[1], 2), /// output.store_complex_v128(input[2], 4), /// output.store_complex_v128(input[3], 6), /// ]; -/// +/// macro_rules! write_complex_to_array_strided_v128 { ($input:ident, $output:ident, $stride:literal, { $($idx:literal),* }) => { $(