Skip to content
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

Hadar/reduction from storage #745

Merged
merged 34 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d02cc1e
recover from mont branch
HadarIngonyama Jan 12, 2025
1b58dc4
remove extra math from field
HadarIngonyama Jan 13, 2025
2e34b68
how was this not formatted?
HadarIngonyama Jan 13, 2025
ba51110
Merge remote-tracking branch 'origin/main' into hadar/base-math
HadarIngonyama Jan 13, 2025
5d04ac8
fmt
HadarIngonyama Jan 13, 2025
90d2d7d
fffffmmmmttt
HadarIngonyama Jan 13, 2025
c1d532a
small fix
HadarIngonyama Jan 13, 2025
5d4fc30
small field fix
HadarIngonyama Jan 14, 2025
a42e08e
Merge remote-tracking branch 'origin/main' into hadar/reduce-from-sto…
HadarIngonyama Jan 15, 2025
337390e
first try
HadarIngonyama Jan 16, 2025
4527d93
first try
HadarIngonyama Jan 16, 2025
5a97dc0
first version works
HadarIngonyama Jan 16, 2025
960c6a7
secon version working
HadarIngonyama Jan 16, 2025
c928abb
adding params, from 3 working
HadarIngonyama Jan 17, 2025
4855b7d
bug fix - asymmetric mult 64
HadarIngonyama Jan 20, 2025
ef57d44
add mod sqr subs
HadarIngonyama Jan 22, 2025
67cdc90
add comments
HadarIngonyama Jan 22, 2025
c080d37
Merge remote-tracking branch 'origin/main' into hadar/basic-from-storage
HadarIngonyama Jan 22, 2025
47024ce
Merge remote-tracking branch 'origin/main' into hadar/basic-from-storage
HadarIngonyama Jan 22, 2025
c47a740
fix bugs
HadarIngonyama Jan 22, 2025
e007b43
added test
HadarIngonyama Jan 22, 2025
a406106
temp
HadarIngonyama Jan 23, 2025
12b2aa0
Merge remote-tracking branch 'origin/main' into hadar/reduce-from-sto…
HadarIngonyama Jan 23, 2025
7ad41f1
Merge branch 'hadar/reduce-from-storage' into hadar/basic-from-storage
HadarIngonyama Jan 23, 2025
e861c2e
merge
HadarIngonyama Jan 23, 2025
d7bfa3c
stark 252 works
HadarIngonyama Jan 27, 2025
fab2c90
all the fields work
HadarIngonyama Jan 27, 2025
3d91859
formatting
HadarIngonyama Jan 27, 2025
8efd7a7
small fix
HadarIngonyama Jan 27, 2025
db2a8cc
small fix
HadarIngonyama Jan 28, 2025
2e66dbb
spelling
HadarIngonyama Feb 3, 2025
1db8797
adding a non-template version
HadarIngonyama Feb 3, 2025
c805ca6
Merge remote-tracking branch 'origin/main' into hadar/basic-from-storage
HadarIngonyama Feb 3, 2025
8dee5b6
small change
HadarIngonyama Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion icicle/include/icicle/fields/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class Field
static HOST_DEVICE_INLINE Field inv_log_size(uint32_t logn)
{
if (logn == 0) { return Field{CONFIG::one}; }
base_math::inv_log_size_err(logn, CONFIG::omegas_count);
base_math::index_err(logn, CONFIG::omegas_count); // check if the requested size is within the valid range
HadarIngonyama marked this conversation as resolved.
Show resolved Hide resolved
storage_array<CONFIG::omegas_count, TLC> const inv = CONFIG::inv;
return Field{inv.storages[logn - 1]};
}
Expand Down Expand Up @@ -239,6 +239,13 @@ class Field
}
}

HadarIngonyama marked this conversation as resolved.
Show resolved Hide resolved
static HOST_DEVICE_INLINE Field get_reduced_digit(int i)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should clarify by adding modulus / p to the function name as well to the reduced_digits struct and the mod_sub function + struct

{
base_math::index_err(i, CONFIG::reduced_digits_count); // check if the requested size is within the valid range
storage_array<CONFIG::reduced_digits_count, TLC> const reduced_digits = CONFIG::reduced_digits;
return Field{reduced_digits.storages[i]};
}

template <unsigned NLIMBS, bool CARRY_OUT>
static constexpr HOST_DEVICE_INLINE uint32_t
add_limbs(const storage<NLIMBS>& xs, const storage<NLIMBS>& ys, storage<NLIMBS>& rs)
Expand Down Expand Up @@ -275,6 +282,16 @@ class Field
return rv;
}

template <unsigned NLIMBS>
static HOST_INLINE storage<NLIMBS> rand_storage(unsigned non_zero_limbs = NLIMBS)
{
std::uniform_int_distribution<unsigned> distribution;
storage<NLIMBS> value{};
for (unsigned i = 0; i < non_zero_limbs; i++)
value.limbs[i] = distribution(rand_generator);
return value;
}

// NOTE this function is used for test and examples - it assumed it is executed on a single-thread (no two threads
// accessing rand_generator at the same time)
static HOST_INLINE Field rand_host()
Expand Down Expand Up @@ -369,6 +386,25 @@ class Field
xs.limbs_storage, get_m(), get_modulus(), get_modulus<2>(), get_neg_modulus())};
}

// this function receives a storage object (currently supports up to 544 bits) and reduces it to a field element
// between 0 and p.
template <unsigned NLIMBS>
static constexpr HOST_DEVICE_INLINE Field from(const storage<NLIMBS>& xs)
{
Wide rs = {};
int constexpr size = (NLIMBS + TLC - 1) / TLC;
for (int i = 0; i < size; i++) {
Field xi = {}; // split into field size digits
for (int j = 0; j < std::min(TLC, NLIMBS - i * TLC); j++) {
xi.limbs_storage.limbs[j] = xs.limbs[i * TLC + j];
}
Field pi = get_reduced_digit(i); // use precomputed values - pi = 2^(TLC*32*i) % p
Wide temp = mul_wide(xi, pi);
rs = rs + temp; // wide addition keeps the result under p^2, subtracting p^2 after every addition if needed
}
return reduce(rs); // finally, use barret reduction
}

HOST_DEVICE Field& operator=(Field const& other)
{
#pragma unroll
Expand Down
15 changes: 8 additions & 7 deletions icicle/include/icicle/fields/host_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ namespace host_math {
static HOST_INLINE void multiply_raw_64(const uint64_t* a, const uint64_t* b, uint64_t* r)
{
#pragma unroll
for (unsigned j = 0; j < NLIMBS_A / 2; j++) {
for (unsigned i = 0; i < NLIMBS_B / 2; i++) {
uint64_t carry = 0;
#pragma unroll
for (unsigned i = 0; i < NLIMBS_B / 2; i++) {
for (unsigned j = 0; j < NLIMBS_A / 2; j++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you swap the loops?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to fix a bug that was inserted in an earlier PR..

r[j + i] = host_math::madc_cc_64(a[j], b[i], r[j + i], carry);
}
r[NLIMBS_A / 2 + j] = carry;
r[NLIMBS_A / 2 + i] = carry;
}
}

Expand Down Expand Up @@ -363,12 +363,13 @@ namespace host_math {
{
return std::memcmp(xs.limbs, ys.limbs, NLIMBS * sizeof(xs.limbs[0])) == 0;
}
static constexpr void inv_log_size_err(uint32_t logn, uint32_t omegas_count)
// this function checks if the given index is within the array range
static constexpr void index_err(uint32_t index, uint32_t max_index)
HadarIngonyama marked this conversation as resolved.
Show resolved Hide resolved
{
if (logn > omegas_count)
if (index > max_index)
THROW_ICICLE_ERR(
icicle::eIcicleError::INVALID_ARGUMENT,
"Field: Invalid inv index" + std::to_string(logn) + ">" + std::to_string(omegas_count));
icicle::eIcicleError::INVALID_ARGUMENT, "Field: index out of range: given index -" + std::to_string(index) +
"> max index - " + std::to_string(max_index));
}

template <unsigned NLIMBS>
Expand Down
1 change: 1 addition & 0 deletions icicle/include/icicle/fields/params_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ namespace params_gen {
}
return invs;
}

} // namespace params_gen

#define PARAMS(modulus) \
Expand Down
6 changes: 6 additions & 0 deletions icicle/include/icicle/fields/snark_fields/bls12_377_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ namespace bls12_377 {
struct fq_config {
static constexpr storage<12> modulus = {0x00000001, 0x8508c000, 0x30000000, 0x170b5d44, 0xba094800, 0x1ef3622f,
0x00f5138f, 0x1a22d9f3, 0x6ca1493b, 0xc63b05c0, 0x17c510ea, 0x01ae3a46};
static constexpr storage_array<2, 12> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
mickeyasa marked this conversation as resolved.
Show resolved Hide resolved
0x00000000, 0x00000000, 0x00000000},
{0xffffff68, 0x02cdffff, 0x7fffffb1, 0x51409f83, 0x8a7d3ff2, 0x9f7db3a9, 0x6e7c6305, 0x7b4e97b7, 0x803c84e8,
0x4cf495bf, 0xe2fdf49a, 0x008d6661}}};
static constexpr unsigned reduced_digits_count = 2;
PARAMS(modulus)

static constexpr storage<12> rou = {0xc563b9a1, 0x7eca603c, 0x06fe0bc3, 0x06df0a43, 0x0ddff8c6, 0xb44d994a,
Expand Down
6 changes: 5 additions & 1 deletion icicle/include/icicle/fields/snark_fields/bls12_377_scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ namespace bls12_377 {
struct fp_config {
static constexpr storage<8> modulus = {0x00000001, 0x0a118000, 0xd0000001, 0x59aa76fe,
0x5c37b001, 0x60b44d1e, 0x9a2ca556, 0x12ab655e};
static constexpr storage_array<3, 8> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0xfffffff3, 0x7d1c7fff, 0x6ffffff2, 0x7257f50f, 0x512c0fee, 0x16d81575, 0x2bbb9a9d, 0x0d4bda32},
{0xb861857b, 0x25d577ba, 0x8860591f, 0xcc2c27b5, 0xe5dc8593, 0xa7cc008f, 0xeff1c939, 0x011fdae7}}};
static constexpr unsigned reduced_digits_count = 3;
PARAMS(modulus)

static constexpr storage<8> rou = {0xec2a895e, 0x476ef4a4, 0x63e3f04a, 0x9b506ee3,
0xd1a8a12f, 0x60c69477, 0x0cb92cc1, 0x11d4b7f6};
TWIDDLES(modulus, rou)
Expand Down
5 changes: 5 additions & 0 deletions icicle/include/icicle/fields/snark_fields/bls12_381_scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ namespace bls12_381 {
struct fp_config {
static constexpr storage<8> modulus = {0x00000001, 0xffffffff, 0xfffe5bfe, 0x53bda402,
0x09a1d805, 0x3339d808, 0x299d7d48, 0x73eda753};
static constexpr storage_array<3, 8> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0xfffffffe, 0x00000001, 0x00034802, 0x5884b7fa, 0xecbc4ff5, 0x998c4fef, 0xacc5056f, 0x1824b159},
{0xf3f29c6d, 0xc999e990, 0x87925c23, 0x2b6cedcb, 0x7254398f, 0x05d31496, 0x9f59ff11, 0x0748d9d9}}};
static constexpr unsigned reduced_digits_count = 3;
PARAMS(modulus)

static constexpr storage<8> rou = {0x0b912f1f, 0x1b788f50, 0x70b3e094, 0xc4024ff2,
Expand Down
6 changes: 6 additions & 0 deletions icicle/include/icicle/fields/snark_fields/bn254_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ namespace bn254 {
struct fq_config {
static constexpr storage<8> modulus = {0xd87cfd47, 0x3c208c16, 0x6871ca8d, 0x97816a91,
0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72};
static constexpr storage_array<3, 8> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0xc58f0d9d, 0xd35d438d, 0xf5c70b3d, 0x0a78eb28, 0x7879462c, 0x666ea36f, 0x9a07df2f, 0x0e0a77c1},
{0x538afa89, 0xf32cfc5b, 0xd44501fb, 0xb5e71911, 0x0a417ff6, 0x47ab1eff, 0xcab8351f, 0x06d89f71}}};
static constexpr unsigned reduced_digits_count = 3;

PARAMS(modulus)

// nonresidue to generate the extension field
Expand Down
5 changes: 5 additions & 0 deletions icicle/include/icicle/fields/snark_fields/bn254_scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ namespace bn254 {
struct fp_config {
static constexpr storage<8> modulus = {0xf0000001, 0x43e1f593, 0x79b97091, 0x2833e848,
0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72};
static constexpr storage_array<3, 8> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x4ffffffb, 0xac96341c, 0x9f60cd29, 0x36fc7695, 0x7879462e, 0x666ea36f, 0x9a07df2f, 0x0e0a77c1},
{0xae216da7, 0x1bb8e645, 0xe35c59e3, 0x53fe3ab1, 0x53bb8085, 0x8c49833d, 0x7f4e44a5, 0x0216d0b1}}};
static constexpr unsigned reduced_digits_count = 3;
PARAMS(modulus)

static constexpr storage<8> rou = {0x725b19f0, 0x9bd61b6e, 0x41112ed4, 0x402d111e,
Expand Down
19 changes: 19 additions & 0 deletions icicle/include/icicle/fields/stark_fields/babybear.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@
namespace babybear {
struct fp_config {
static constexpr storage<1> modulus = {0x78000001};
static constexpr storage_array<17, 1> reduced_digits = {
{{0x1},
{0xffffffe},
{0x45dddde3},
{0x12f37bfb},
{0x27922ab6},
{0x6394fa39},
{0xb8efb44},
{0x57578192},
{0x25abb864},
{0x6fa2bae8},
{0x11d80ae0},
{0x71eed7bd},
{0x4cf166f8},
{0x43dae013},
{0x173e21fb},
{0x5e6a622e},
{0x169483e4}}};
static constexpr unsigned reduced_digits_count = 17;
PARAMS(modulus)

static constexpr storage<1> rou = {0x00000089};
Expand Down
19 changes: 19 additions & 0 deletions icicle/include/icicle/fields/stark_fields/koalabear.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@
namespace koalabear {
struct fp_config {
static constexpr storage<1> modulus = {0x7f000001};
static constexpr storage_array<17, 1> reduced_digits = {
{{0x00000001},
{0x01fffffe},
{0x17f7efe4},
{0x18af7f37},
{0x423d7c8c},
{0x1b79fadf},
{0x7b9d44cd},
{0x64d31ca2},
{0x5bc34d59},
{0x0f077438},
{0x4fb48092},
{0x2d55aa32},
{0x389de76c},
{0x02dff10b},
{0x023486f8},
{0x4e8e0e2d},
{0x55a7320c}}};
static constexpr unsigned reduced_digits_count = 17;
PARAMS(modulus)

static constexpr storage<1> rou = {0x6ac49f88};
Expand Down
19 changes: 19 additions & 0 deletions icicle/include/icicle/fields/stark_fields/m31.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,25 @@ namespace m31 {
static constexpr unsigned num_of_reductions = 1;

static constexpr storage<limbs_count> modulus = {0x7fffffff};
static constexpr storage_array<17, 1> reduced_digits = {
{{0x00000001},
{0x00000002},
{0x00000004},
{0x00000008},
{0x00000010},
{0x00000020},
{0x00000040},
{0x00000080},
{0x00000100},
{0x00000200},
{0x00000400},
{0x00000800},
{0x00001000},
{0x00002000},
{0x00004000},
{0x00008000},
{0x00010000}}};
static constexpr unsigned reduced_digits_count = 17;
static constexpr storage<limbs_count> modulus_2 = {0xfffffffe};
static constexpr uint64_t modulus_3 = 0x17ffffffd;
static constexpr storage<limbs_count> modulus_4 = {0xfffffffc};
Expand Down
6 changes: 6 additions & 0 deletions icicle/include/icicle/fields/stark_fields/stark252.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ namespace stark252 {
struct fp_config {
static constexpr storage<8> modulus = {0x00000001, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000011, 0x08000000};

static constexpr storage_array<3, 8> reduced_digits = {
{{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0xffffffe1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdf0, 0x07ffffff},
{0x7e000401, 0xfffffd73, 0x330fffff, 0x00000001, 0xff6f8000, 0xffffffff, 0x5e008810, 0x07ffd4ab}}};
static constexpr unsigned reduced_digits_count = 3;
PARAMS(modulus)

static constexpr storage<8> rou = {0x42f8ef94, 0x6070024f, 0xe11a6161, 0xad187148,
Expand Down
42 changes: 42 additions & 0 deletions icicle/tests/test_field_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,48 @@ TYPED_TEST(FieldApiTest, FieldSanityTest)
ASSERT_EQ(a * scalar_t::from(2), a + a);
}

#ifndef EXT_FIELD
TYPED_TEST(FieldApiTest, FieldStorageReduceTest)
{
typename TypeParam::Wide res_wide = {};
HadarIngonyama marked this conversation as resolved.
Show resolved Hide resolved
typename TypeParam::Wide temp = {};
storage<2 * TypeParam::TLC + 2> res_storage = {};
for (int i = 0; i < 10000; i++) {
auto a = TypeParam::rand_host();
TypeParam::multiply_raw(a.limbs_storage, a.limbs_storage, temp.limbs_storage);
res_wide = res_wide + temp;
storage<2 * TypeParam::TLC + 2> temp2 = {};
for (int j = 0; j < 2 * TypeParam::TLC; j++) {
temp2.limbs[j] = temp.limbs_storage.limbs[j];
}
base_math::template add_sub_limbs<2 * TypeParam::TLC + 2, false, false, true>(res_storage, temp2, res_storage);
}
ASSERT_EQ(TypeParam::reduce(res_wide), TypeParam::from(res_storage));
}

TYPED_TEST(FieldApiTest, FieldStorageReduceSanityTest)
{
/*
SR - storage reduce
check that:
1. SR(x1) + SR(x1) = SR(x1+x2)
2. SR(INV(SR(x))*x) = 1
*/
storage<18> a = TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition
storage<18> b = TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition
storage<18> sum = {};
const storage<18 - TypeParam::TLC> c =
TypeParam::template rand_storage<18 - TypeParam::TLC>(); // -TLC so wi don't overflow in multiplication
storage<18> product = {};
base_math::template add_sub_limbs<18, false, false, true>(a, b, sum);
auto c_red = TypeParam::from(c);
auto c_inv = TypeParam::inverse(c_red);
base_math::multiply_raw(c, c_inv.limbs_storage, product);
ASSERT_EQ(TypeParam::from(a) + TypeParam::from(b), TypeParam::from(sum));
ASSERT_EQ(TypeParam::from(product), TypeParam::one());
}
#endif

TYPED_TEST(FieldApiTest, vectorVectorOps)
{
const uint64_t N = 1 << rand_uint_32b(3, 17);
Expand Down
17 changes: 17 additions & 0 deletions scripts/format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# Check if directory is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 <directory>"
exit 1
fi

DIRECTORY="$1"

# Find and format all C, C++, header, and other relevant files
find "$DIRECTORY" -name '*.c' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' | while read -r file; do
echo "Formatting $file"
clang-format -i "$file"
done

echo "All files formatted."
Loading