-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ohadn/qm31 arithmetics in math utils #1944
Conversation
3237909
to
d6d9a96
Compare
|
Benchmark Results for unmodified programs 🚀
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1944 +/- ##
==========================================
+ Coverage 96.39% 96.41% +0.02%
==========================================
Files 102 102
Lines 41566 41861 +295
==========================================
+ Hits 40068 40362 +294
- Misses 1498 1499 +1 ☔ View full report in Codecov by Sentry. |
d6d9a96
to
d1f230b
Compare
1bec5ba
to
afcbcea
Compare
d1f230b
to
4bca3db
Compare
6f060e8
to
ee6ba48
Compare
ef1aa46
to
cbd7519
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 12 files reviewed, 1 unresolved discussion (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, and @YairVaknin-starkware)
cbd7519
to
ee011aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 12 files reviewed, 1 unresolved discussion (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, and @YairVaknin-starkware)
84ec321
to
9cdce6f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 8 of 12 files reviewed, 6 unresolved discussions (waiting on @dancarmoz, @DavidLevitGurevich, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 195 at r4 (raw file):
Previously, ohad-nir-starkware (Ohad Nir) wrote…
not sure I understand what is you recommendation, use u64 or u128?
For the sake of VM efficiency, I have changed it to u64.
let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 4 of 4 files at r5, 1 of 1 files at r6, all commit messages.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @dancarmoz, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 195 at r4 (raw file):
Previously, ohad-nir-starkware (Ohad Nir) wrote…
For the sake of VM efficiency, I have changed it to u64.
let me know what you think.
@dancarmoz are you sure it is more efficient? or is it not what you meant? because it seems that the code now does % stwo_prime_u128
more time than before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 6 unresolved discussions (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 194 at r4 (raw file):
Previously, ohad-nir-starkware (Ohad Nir) wrote…
Done.
Should still be upper case C (Computes
)
vm/src/math_utils/mod.rs
line 195 at r4 (raw file):
Previously, DavidLevitGurevich wrote…
@dancarmoz are you sure it is more efficient? or is it not what you meant? because it seems that the code now does
% stwo_prime_u128
more time than before
Certainly it does % stwo_prime_u128
fewer times than before, now it only does it inside the mul, and before it did in every function and every packing (it's just that STWO_PRIME
used to be the name of stwo_prime_u128
rather than of the u64 version, which didn't exist...).
As to whether I'm sure it's more efficient - it is mostly intuition that u64 operations should be faster than u128 operations by a factor that justifies these few conversions. IMO the only way to be sure which is faster is to test and benchmark.
vm/src/math_utils/mod.rs
line 178 at r6 (raw file):
coordinates2_u64[2] as u128, coordinates2_u64[3] as u128, ];
You can also apply the map directly on qm31_packed_reduced_read_coordinates(felt[12])?
without defining coordinates[12]_u64
.
Suggestion:
let coordinates1 = coordinates1_u64.map(u128::from);
let coordinates2 = coordinates2_u64.map(u128::from);
vm/src/math_utils/mod.rs
line 179 at r6 (raw file):
coordinates2_u64[3] as u128, ]; let stwo_prime_u128 = STWO_PRIME as u128;
It would be better (and possibly more efficient) to have STWO_PRIME_U128
be a const as well.
vm/src/math_utils/mod.rs
line 180 at r6 (raw file):
]; let stwo_prime_u128 = STWO_PRIME as u128; let result_unreduced_coordinates = [
Actually already reduced in this version :)
Suggestion:
let result_coordinates = [
vm/src/math_utils/mod.rs
line 213 at r6 (raw file):
/// M31 utility function, used specifically for Stwo. /// computes inverse in the M31 field using Fermat's little theorem i.e. returns /// `v^(STWO_PRIME-2) modulo STWO_PRIME` which is the inverse of v unless v % STWO_PRIME == 0
Suggestion:
/// Computes the inverse in the M31 field using Fermat's little theorem, i.e., returns
/// `v^(STWO_PRIME-2) modulo STWO_PRIME`, which is the inverse of v unless v % STWO_PRIME == 0.
9cdce6f
to
57521d5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @dancarmoz, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 194 at r4 (raw file):
Previously, dancarmoz (Dan Carmon) wrote…
Should still be upper case C (
Computes
)
Done.
vm/src/math_utils/mod.rs
line 178 at r6 (raw file):
Previously, dancarmoz (Dan Carmon) wrote…
You can also apply the map directly on
qm31_packed_reduced_read_coordinates(felt[12])?
without definingcoordinates[12]_u64
.
Done.
vm/src/math_utils/mod.rs
line 179 at r6 (raw file):
Previously, dancarmoz (Dan Carmon) wrote…
It would be better (and possibly more efficient) to have
STWO_PRIME_U128
be a const as well.
Done.
vm/src/math_utils/mod.rs
line 180 at r6 (raw file):
Previously, dancarmoz (Dan Carmon) wrote…
Actually already reduced in this version :)
Done.
vm/src/math_utils/mod.rs
line 213 at r6 (raw file):
/// M31 utility function, used specifically for Stwo. /// computes inverse in the M31 field using Fermat's little theorem i.e. returns /// `v^(STWO_PRIME-2) modulo STWO_PRIME` which is the inverse of v unless v % STWO_PRIME == 0
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 11 of 12 files reviewed, 5 unresolved discussions (waiting on @dancarmoz, @DavidLevitGurevich, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 195 at r4 (raw file):
Previously, dancarmoz (Dan Carmon) wrote…
Certainly it does
% stwo_prime_u128
fewer times than before, now it only does it inside the mul, and before it did in every function and every packing (it's just thatSTWO_PRIME
used to be the name ofstwo_prime_u128
rather than of the u64 version, which didn't exist...).As to whether I'm sure it's more efficient - it is mostly intuition that u64 operations should be faster than u128 operations by a factor that justifies these few conversions. IMO the only way to be sure which is faster is to test and benchmark.
Tested the time it takes to compute qm31_packed_reduced_mul
10^6 times in both versions (u128 and u64):
the u64 version took about 109 ms and the u128 version took about 160 seconds, so even with the extra %
calculations the u64 is much faster.
I could also implement another packing function that assumes that the coordinates are already reduced or add a flag to qm31_coordinates_to_packed_reduced
that indicates whether to assume that or not.
WDYT?
57521d5
to
29ce31e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r8, all commit messages.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @dancarmoz, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
line 195 at r4 (raw file):
Previously, ohad-nir-starkware (Ohad Nir) wrote…
Tested the time it takes to compute
qm31_packed_reduced_mul
10^6 times in both versions (u128 and u64):
the u64 version took about 109 ms and the u128 version took about 160 seconds, so even with the extra%
calculations the u64 is much faster.
I could also implement another packing function that assumes that the coordinates are already reduced or add a flag toqm31_coordinates_to_packed_reduced
that indicates whether to assume that or not.
WDYT?
I think the current version is good as is 👍
/// M31 utility function, used specifically for Stwo. | ||
/// Computes the inverse in the M31 field using Fermat's little theorem, i.e., returns | ||
/// `v^(STWO_PRIME-2) modulo STWO_PRIME`, which is the inverse of v unless v % STWO_PRIME == 0. | ||
pub fn pow2147483645(v: u64) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function computes the inverse of the M31 field, I suggest to rename it to something like:
pub fn pow2147483645(v: u64) -> u64 { | |
pub fn m31_inv(v: u64) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it doesn't invert zero, but you have a point.
however this function and sqn
are adaptations from
https://github.com/starkware-libs/stwo/blob/dev/crates/prover/src/core/fields/m31.rs
do you still think they should be renamed?
I initially thought of adding starkware-libs/stwo
as a dependency and taking all the QM31 arithmetics from there, but I was told that is not option.
Let me know whether that is true or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave it like this for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
/// M31 utility function, used specifically for Stwo. | ||
/// Computes `v^(2^n) modulo STWO_PRIME`. | ||
fn sqn(v: u64, n: usize) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this function to something more descriptive:
fn sqn(v: u64, n: usize) -> u64 { | |
fn square_n(v: u64, n: usize) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in the discussion about pow2147483645
. let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can leave it like this for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_add_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the ´test´ word as a prefix for test case names, following the convention for other cases.
fn qm31_packed_reduced_add_test() { | |
fn test_qm31_packed_reduced_add() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_neg_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_neg_test() { | |
fn test_qm31_packed_reduced_neg() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_sub_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_sub_test() { | |
fn test_qm31_packed_reduced_sub() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_mul_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_mul_test() { | |
fn test_qm31_packed_reduced_mul() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_inv_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_inv_test() { | |
fn test_qm31_packed_reduced_inv() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_div_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_div_test() { | |
fn test_qm31_packed_reduced_div() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_inv_extensive_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn qm31_packed_reduced_inv_extensive_test() { | |
fn test_qm31_packed_reduced_inv_extensive() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
let mut rng = SmallRng::seed_from_u64(11480028852697973135); | ||
let configurations = vec!["zero", "one", "minus_one", "random"]; | ||
let mut cartesian_product: Vec<[&str; 4]> = vec![]; | ||
for &a in &configurations { | ||
for &b in &configurations { | ||
for &c in &configurations { | ||
for &d in &configurations { | ||
cartesian_product.push([a, b, c, d]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
for test_case in cartesian_product { | ||
let x_coordinates: [u64; 4] = test_case | ||
.iter() | ||
.map(|&x| match x { | ||
"zero" => 0, | ||
"one" => 1, | ||
"minus_one" => STWO_PRIME - 1, | ||
"random" => rng.gen_range(0..STWO_PRIME), | ||
_ => unreachable!(), | ||
}) | ||
.collect::<Vec<u64>>() | ||
.try_into() | ||
.unwrap(); | ||
if x_coordinates == [0, 0, 0, 0] { | ||
continue; | ||
} | ||
let x = qm31_coordinates_to_packed_reduced(x_coordinates); | ||
let res = qm31_packed_reduced_inv(x).unwrap(); | ||
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case I suggest to use proptest
. If you want to force testing 0
, 1
and -1
you can also add separate test cases for those.
Here's an example of how the proptest could look like:
proptest! {
#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn test_qm31_packed_reduced_inv(x_coordinates in uniform4(0..STWO_PRIME).prop_filter("felt is zero", |x| *x != [0, 0, 0, 0])) {
let x = qm31_coordinates_to_packed_reduced(x_coordinates);
let res = qm31_packed_reduced_inv(x).unwrap();
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1)));
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrote a test inside the existing proptest!
, it's called qm31_packed_reduced_inv_x_by_x_is_1
, let me know what you think.
@DavidLevitGurevich can this new test replace qm31_packed_reduced_inv_extensive_test
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know this tool, if it goes over all options then it's good, otherwise I feel it's a degradation of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the idea is to make sure that we include 0
, 1
or -1
in the test cases then you need to specify it in the test case function and not in the proptest
argument. The proptest
argument is useful for the random values.
We can leave this like this by deleting the qm31_packed_reduced_inv_x_by_x_is_1
test. Then we can create a PR for refactoring.
A minor change I think it can be done here is to replace the string cases with an enum (e.g.: replace "zero"
with Coordinate::Zero
or something like that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
29ce31e
to
d733ade
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 12 unresolved discussions (waiting on @DavidLevitGurevich, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
/// M31 utility function, used specifically for Stwo. | ||
/// Computes the inverse in the M31 field using Fermat's little theorem, i.e., returns | ||
/// `v^(STWO_PRIME-2) modulo STWO_PRIME`, which is the inverse of v unless v % STWO_PRIME == 0. | ||
pub fn pow2147483645(v: u64) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, it doesn't invert zero, but you have a point.
however this function and sqn
are adaptations from
https://github.com/starkware-libs/stwo/blob/dev/crates/prover/src/core/fields/m31.rs
do you still think they should be renamed?
I initially thought of adding starkware-libs/stwo
as a dependency and taking all the QM31 arithmetics from there, but I was told that is not option.
Let me know whether that is true or not.
|
||
/// M31 utility function, used specifically for Stwo. | ||
/// Computes `v^(2^n) modulo STWO_PRIME`. | ||
fn sqn(v: u64, n: usize) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in the discussion about pow2147483645
. let me know what you think.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_add_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_neg_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_sub_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_mul_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_inv_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_inv_extensive_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
vm/src/math_utils/mod.rs
Outdated
let mut rng = SmallRng::seed_from_u64(11480028852697973135); | ||
let configurations = vec!["zero", "one", "minus_one", "random"]; | ||
let mut cartesian_product: Vec<[&str; 4]> = vec![]; | ||
for &a in &configurations { | ||
for &b in &configurations { | ||
for &c in &configurations { | ||
for &d in &configurations { | ||
cartesian_product.push([a, b, c, d]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
for test_case in cartesian_product { | ||
let x_coordinates: [u64; 4] = test_case | ||
.iter() | ||
.map(|&x| match x { | ||
"zero" => 0, | ||
"one" => 1, | ||
"minus_one" => STWO_PRIME - 1, | ||
"random" => rng.gen_range(0..STWO_PRIME), | ||
_ => unreachable!(), | ||
}) | ||
.collect::<Vec<u64>>() | ||
.try_into() | ||
.unwrap(); | ||
if x_coordinates == [0, 0, 0, 0] { | ||
continue; | ||
} | ||
let x = qm31_coordinates_to_packed_reduced(x_coordinates); | ||
let res = qm31_packed_reduced_inv(x).unwrap(); | ||
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrote a test inside the existing proptest!
, it's called qm31_packed_reduced_inv_x_by_x_is_1
, let me know what you think.
@DavidLevitGurevich can this new test replace qm31_packed_reduced_inv_extensive_test
?
vm/src/math_utils/mod.rs
Outdated
|
||
#[test] | ||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] | ||
fn qm31_packed_reduced_div_test() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r9.
Reviewable status: all files reviewed (commit messages unreviewed), 12 unresolved discussions (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
Outdated
let mut rng = SmallRng::seed_from_u64(11480028852697973135); | ||
let configurations = vec!["zero", "one", "minus_one", "random"]; | ||
let mut cartesian_product: Vec<[&str; 4]> = vec![]; | ||
for &a in &configurations { | ||
for &b in &configurations { | ||
for &c in &configurations { | ||
for &d in &configurations { | ||
cartesian_product.push([a, b, c, d]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
for test_case in cartesian_product { | ||
let x_coordinates: [u64; 4] = test_case | ||
.iter() | ||
.map(|&x| match x { | ||
"zero" => 0, | ||
"one" => 1, | ||
"minus_one" => STWO_PRIME - 1, | ||
"random" => rng.gen_range(0..STWO_PRIME), | ||
_ => unreachable!(), | ||
}) | ||
.collect::<Vec<u64>>() | ||
.try_into() | ||
.unwrap(); | ||
if x_coordinates == [0, 0, 0, 0] { | ||
continue; | ||
} | ||
let x = qm31_coordinates_to_packed_reduced(x_coordinates); | ||
let res = qm31_packed_reduced_inv(x).unwrap(); | ||
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know this tool, if it goes over all options then it's good, otherwise I feel it's a degradation of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed all commit messages.
Reviewable status: all files reviewed, 12 unresolved discussions (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
@ohad-nir-starkware the QM31 operations should be defined in the future in Lambdaworks along with the |
d733ade
to
9b6fbea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gabrielbosio added a line in the documentation of each QM31 / M31 function regarding it's future relocation to Lambdaworks.
let me know if any other changes are needed.
Reviewable status: all files reviewed, 12 unresolved discussions (waiting on @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
vm/src/math_utils/mod.rs
Outdated
let mut rng = SmallRng::seed_from_u64(11480028852697973135); | ||
let configurations = vec!["zero", "one", "minus_one", "random"]; | ||
let mut cartesian_product: Vec<[&str; 4]> = vec![]; | ||
for &a in &configurations { | ||
for &b in &configurations { | ||
for &c in &configurations { | ||
for &d in &configurations { | ||
cartesian_product.push([a, b, c, d]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
for test_case in cartesian_product { | ||
let x_coordinates: [u64; 4] = test_case | ||
.iter() | ||
.map(|&x| match x { | ||
"zero" => 0, | ||
"one" => 1, | ||
"minus_one" => STWO_PRIME - 1, | ||
"random" => rng.gen_range(0..STWO_PRIME), | ||
_ => unreachable!(), | ||
}) | ||
.collect::<Vec<u64>>() | ||
.try_into() | ||
.unwrap(); | ||
if x_coordinates == [0, 0, 0, 0] { | ||
continue; | ||
} | ||
let x = qm31_coordinates_to_packed_reduced(x_coordinates); | ||
let res = qm31_packed_reduced_inv(x).unwrap(); | ||
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} | ||
|
||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot something, because we decided to keep this test case as it is for now, I suggest to add this:
#[test] | |
// TODO: Refactor using proptest and separating particular cases | |
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
9b6fbea
to
38adbe6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 11 of 12 files reviewed, 13 unresolved discussions (waiting on @DavidLevitGurevich, @fmoletta, @gabrielbosio, @igaray, @juanbono, @JulianGCalderon, @Oppen, @pefontana, @YairVaknin-starkware, and @yuvalsw)
/// M31 utility function, used specifically for Stwo. | ||
/// Computes the inverse in the M31 field using Fermat's little theorem, i.e., returns | ||
/// `v^(STWO_PRIME-2) modulo STWO_PRIME`, which is the inverse of v unless v % STWO_PRIME == 0. | ||
pub fn pow2147483645(v: u64) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
/// M31 utility function, used specifically for Stwo. | ||
/// Computes `v^(2^n) modulo STWO_PRIME`. | ||
fn sqn(v: u64, n: usize) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
assert_eq!(qm31_packed_reduced_mul(x, res), Ok(Felt252::from(1))); | ||
} | ||
|
||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
qm31 arithmetics in math utils
Description
add functions that compute packed reduced qm31 arithmetics to math_utils
Checklist
This change is