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

Apply commits from actor repos #8

Merged
merged 4 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "cmake/modules"]
path = cmake/modules
url = [email protected]:BoostCMake/cmake_modules.git
url = ../../BoostCMake/cmake_modules.git
8 changes: 2 additions & 6 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,8 @@
ninja
clang
gcc
(boost183.override {
enableShared = true;
enableStatic = true;
enableRelease = true;
enableDebug = true;
})
boost183
crypto3.packages.${system}.default
];

shellHook = ''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,6 @@ namespace nil {
*/
template<typename Range>
void division(Range &q, Range &r, const Range &a, const Range &b) {

// TODO(martun): parallelize division better.

typedef
typename std::iterator_traits<decltype(std::begin(std::declval<Range>()))>::value_type value_type;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,23 @@ namespace nil {

polynomial(polynomial&& x) BOOST_NOEXCEPT
(std::is_nothrow_move_constructible<allocator_type>::value) :
val(x.val) {
val(std::move(x.val)) {
}

polynomial(polynomial&& x, const allocator_type& a) : val(x.val, a) {
polynomial(polynomial&& x, const allocator_type& a) : val(std::move(x.val), a) {
}

polynomial(const FieldValueType& value, std::size_t power = 0) : val(power + 1, FieldValueType::zero()) {
this->operator[](power) = value;
}

template<typename T>
explicit polynomial(T&& c) : val(std::forward<T>(c)) {
explicit polynomial(const container_type &c) : val(c) {
if (val.empty()) {
val.push_back(FieldValueType::zero());
}
}

explicit polynomial(container_type &&c) : val(std::move(c)) {
if (val.empty()) {
val.push_back(FieldValueType::zero());
}
Expand Down Expand Up @@ -544,24 +549,34 @@ namespace nil {
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial<FieldValueType, Allocator> operator*(const polynomial<FieldValueType, Allocator>& A,
const FieldValueType& B) {

return A * polynomial<FieldValueType>(B);
polynomial<FieldValueType> result(A);
parallel_foreach(result.begin(), result.end(),
[&B](FieldValueType& v) {
v *= B;
}, ThreadPool::PoolLevel::LOW);
return result;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial<FieldValueType, Allocator> operator*(const FieldValueType& A,
const polynomial<FieldValueType, Allocator>& B) {

return polynomial<FieldValueType>(A) * B;
// Call the upper function.
return B * A;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial<FieldValueType, Allocator> operator/(const polynomial<FieldValueType, Allocator>& A,
const FieldValueType& B) {

return A / polynomial<FieldValueType>(B);
polynomial<FieldValueType> result(A);
FieldValueType B_inversed = B.inversed();
parallel_foreach(result.begin(), result.end(),
[&B_inversed](FieldValueType& v) {
v *= B_inversed;
}, ThreadPool::PoolLevel::LOW);

return result;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ namespace nil {
return;
}
BOOST_ASSERT_MSG(_sz >= _d, "Resizing DFS polynomial to a size less than degree is prohibited: can't restore the polynomial in the future.");

if (this->degree() == 0) {
// Here we cannot write this->val.resize(_sz, this->val[0]), it will segfault.
auto value = this->val[0];
Expand Down Expand Up @@ -552,6 +553,7 @@ namespace nil {
this->resize(polynomial_s, domain, new_domain);
}


// Change the degree only here, after a possible resize, otherwise we have a polynomial
// with a high degree but small size, which sometimes segfaults.
this->_d += other._d;
Expand Down Expand Up @@ -724,29 +726,35 @@ namespace nil {
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial_dfs<FieldValueType, Allocator> operator*(const polynomial_dfs<FieldValueType, Allocator>& A,
const FieldValueType& B) {

polynomial_dfs<FieldValueType> result(A);
for( auto it = result.begin(); it != result.end(); it++ ){
*it *= B;
}
parallel_foreach(result.begin(), result.end(),
[&B](FieldValueType& v) {
v *= B;
}, ThreadPool::PoolLevel::LOW);
return result;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial_dfs<FieldValueType, Allocator> operator*(const FieldValueType& A,
const polynomial_dfs<FieldValueType, Allocator>& B) {
polynomial_dfs<FieldValueType> result(B);
for( auto it = result.begin(); it != result.end(); it++ ){
*it *= A;
}
return result;
// Call the upper function.
return B * A;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
typename = typename std::enable_if<detail::is_field_element<FieldValueType>::value>::type>
polynomial_dfs<FieldValueType, Allocator> operator/(const polynomial_dfs<FieldValueType, Allocator>& A,
const FieldValueType& B) {
return A / polynomial_dfs<FieldValueType>(0, A.size(), B);
polynomial_dfs<FieldValueType> result(A);
FieldValueType B_inversed = B.inversed();
parallel_foreach(result.begin(), result.end(),
[&B_inversed](FieldValueType& v) {
v *= B_inversed;
}, ThreadPool::PoolLevel::LOW);

return result;
}

template<typename FieldValueType, typename Allocator = std::allocator<FieldValueType>,
Expand Down Expand Up @@ -786,6 +794,10 @@ namespace nil {
std::vector<math::polynomial_dfs<typename FieldType::value_type>> addends) {
using FieldValueType = typename FieldType::value_type;

if (addends.empty()) {
return {};
}

// Since there are only ~20 addends, we will just use that many maps
std::vector<std::unordered_map<std::size_t, polynomial_dfs<FieldValueType>>> maps(addends.size());
for (size_t i = 0; i < addends.size(); ++i) {
Expand Down Expand Up @@ -820,15 +832,25 @@ namespace nil {
}

std::unordered_map<std::size_t, polynomial_dfs<FieldValueType>>& size_to_part_sum = maps[0];
std::vector<polynomial_dfs<FieldValueType>> grouped_addends;

std::size_t max_size = 0;
for (const auto& [size, _] : size_to_part_sum) {
for (const auto& [size, partial_sum] : size_to_part_sum) {
max_size = std::max(max_size, size);
grouped_addends.push_back(std::move(partial_sum));
}

auto coef_result = polynomial<FieldValueType>(max_size, FieldValueType::zero());
for (auto& [_, partial_sum] : size_to_part_sum) {
coef_result += polynomial<FieldValueType>(std::move(partial_sum.coefficients()));
std::vector<polynomial<FieldValueType>> grouped_addends_coefs(grouped_addends.size());

nil::crypto3::parallel_for(0, grouped_addends.size(), [&grouped_addends_coefs, &grouped_addends] (std::size_t i) {
grouped_addends_coefs[i] = grouped_addends[i].coefficients();
}, ThreadPool::PoolLevel::HIGH);

// We can parallelize this by adding pairwise, like it's done in multiplication, but it's pretty fast
// so skipping it for now.
polynomial<FieldValueType> coef_result;
for (const auto& partial_sum : grouped_addends_coefs) {
coef_result += partial_sum;
}

polynomial_dfs<FieldValueType> dfs_result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <utility>
#include <map>

#include <boost/functional/hash.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

Expand Down Expand Up @@ -75,6 +76,25 @@ namespace nil {
std::map<std::size_t, bool> _locked; // _locked[batch] is true after it is commited
std::map<std::size_t, std::vector<std::vector<typename field_type::value_type>>> _points;

// We frequently search over the this->_points structure, and it's better to keep a hashmap that maps point to
// it's index in vector for faster search. We need to duplicate this data for now, because the order of points matters.
std::map<std::size_t, std::vector<std::unordered_map<typename field_type::value_type, std::size_t>>> _points_map;

// Creates '_points_map'. We need to think about re-designing this class later. Currently this is used from LPC.
void build_points_map() {
for (const auto& [i, V]: this->_points) {
_points_map[i].resize(V.size());
for (std::size_t j = 0; j < V.size(); ++j) {
const auto& batch = V[j];
for (std::size_t k = 0; k < batch.size(); ++k) {
// We need to store the index of the first occurance of each point.
if (_points_map[i][j].find(batch[k]) == _points_map[i][j].end())
_points_map[i][j][batch[k]] = k;
}
}
}
}

protected:
math::polynomial<typename field_type::value_type> get_V(
const std::vector<typename field_type::value_type> &points) const {
Expand Down Expand Up @@ -111,16 +131,18 @@ namespace nil {
}

// We call them singles in recursive verifier
// We keep the order of points, not sure if that was required.
std::vector<typename field_type::value_type> get_unique_points() const {

std::vector<typename field_type::value_type> result;
// std::unordered_set<typename field_type::value_type> result_set;
std::unordered_set<typename field_type::value_type> result_set;

for( auto const &[k, point_batch]:_points ){
for( auto const &[k, point_batch]: _points ){
for( auto const &point_set: point_batch ){
for( auto const &point:point_set ){
if( std::find(result.begin(), result.end(), point) == result.end() ){
for( auto const &point: point_set ){
if (result_set.find(point) == result_set.end()) {
result.push_back(point);
// result_set.insert(point);
result_set.insert(point);
}
}
}
Expand Down Expand Up @@ -195,7 +217,7 @@ namespace nil {
for (std::size_t j = 0; j < point[i].size(); j++) {
_z.set(k, i, j, poly[i].evaluate(point[i][j]));
}
}, ThreadPool::PoolLevel::HIGH);
}, ThreadPool::PoolLevel::HIGH);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -764,20 +764,34 @@ namespace nil {
) {
std::unordered_map<std::size_t,
std::shared_ptr<math::evaluation_domain<typename FRI::field_type>>> d_cache;
std::vector<std::size_t> required_domains;
std::vector<std::pair<std::size_t, std::size_t>> key_index_pairs;
for (const auto &[key, poly_vector]: g) {
for (const auto& poly: poly_vector) {
g_coeffs[key].resize(poly_vector.size());

for (std::size_t poly_index = 0; poly_index < poly_vector.size(); ++poly_index) {
const auto& poly = poly_vector[poly_index];
if (poly.size() != fri_params.D[0]->size()) {
if (d_cache.find(poly.size()) == d_cache.end()) {
d_cache[poly.size()] =
math::make_evaluation_domain<typename FRI::field_type>(poly.size());
required_domains.push_back(poly.size());
d_cache[poly.size()] = nullptr;
}
g_coeffs[key].emplace_back(poly.coefficients(d_cache[poly.size()]));
} else {
// These polynomials won't be used
g_coeffs[key].emplace_back(math::polynomial<typename FRI::field_type::value_type>());
key_index_pairs.push_back({key, poly_index});
}
}
}

parallel_for(0, required_domains.size(),
[&required_domains, &d_cache](std::size_t i) {
d_cache[required_domains[i]] = math::make_evaluation_domain<typename FRI::field_type>(required_domains[i]);
}, ThreadPool::PoolLevel::HIGH);

parallel_for(0, key_index_pairs.size(),
[&d_cache, &g_coeffs, &key_index_pairs, &g](std::size_t pair_index) {
auto [key, index] = key_index_pairs[pair_index];
const auto& poly = g.at(key)[index];
g_coeffs[key][index] = poly.coefficients(d_cache[poly.size()]);
}, ThreadPool::PoolLevel::HIGH);
}

std::vector<typename FRI::field_type::value_type> challenges(fri_params.lambda);
Expand Down
Loading
Loading