From 07bf357748b134a471c075b65b37fa3407f5edb2 Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Mon, 29 Jan 2024 18:48:02 +0400 Subject: [PATCH] Done with math library. --- .../math/multithreading/thread_pool.hpp | 7 ++++--- .../math/polynomial/basic_operations.hpp | 17 ++++++++-------- .../math/polynomial/polynomial_dfs.hpp | 15 ++++++++++---- .../math/polynomial/polynomial_view.hpp | 7 ++++--- test/polynomial_dfs.cpp | 20 +++++++++++++++---- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/include/nil/crypto3/math/multithreading/thread_pool.hpp b/include/nil/crypto3/math/multithreading/thread_pool.hpp index f718d41..a4b86c3 100644 --- a/include/nil/crypto3/math/multithreading/thread_pool.hpp +++ b/include/nil/crypto3/math/multithreading/thread_pool.hpp @@ -76,7 +76,7 @@ namespace nil { std::function func) { std::vector> fut; - std::size_t cpu_usage = std::min(elements_count, pool_size); + std::size_t cpu_usage = std::max((size_t)1, std::min(elements_count, pool_size)); std::size_t element_per_cpu = elements_count / cpu_usage; // Pool #0 will take care of the lowest level of operations, like polynomial operations. @@ -86,12 +86,13 @@ namespace nil { element_per_cpu = elements_count / cpu_usage; } + std::size_t begin = 0; for (int i = 0; i < cpu_usage; i++) { - auto begin = element_per_cpu * i; - auto end = (i == cpu_usage - 1) ? elements_count : element_per_cpu * (i + 1); + auto end = begin + (elements_count - begin) / (cpu_usage - i); fut.emplace_back(post([begin, end, func]() { return func(begin, end); })); + begin = end; } return fut; } diff --git a/include/nil/crypto3/math/polynomial/basic_operations.hpp b/include/nil/crypto3/math/polynomial/basic_operations.hpp index 66478df..e0c0b0a 100755 --- a/include/nil/crypto3/math/polynomial/basic_operations.hpp +++ b/include/nil/crypto3/math/polynomial/basic_operations.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace nil { namespace crypto3 { @@ -101,12 +102,12 @@ namespace nil { if (a_size > b_size) { c.resize(a_size); - std::transform( + nil::crypto3::parallel_transform( std::begin(b), std::end(b), std::begin(a), std::begin(c), std::plus()); std::copy(std::begin(a) + b_size, std::end(a), std::begin(c) + b_size); } else { c.resize(b_size); - std::transform( + nil::crypto3::parallel_transform( std::begin(a), std::end(a), std::begin(b), std::begin(c), std::plus()); std::copy(std::begin(b) + a_size, std::end(b), std::begin(c) + a_size); } @@ -129,19 +130,19 @@ namespace nil { c = a; } else if (is_zero(a)) { c.resize(b.size()); - std::transform(b.begin(), b.end(), c.begin(), std::negate()); + nil::crypto3::parallel_transform(b.begin(), b.end(), c.begin(), std::negate()); } else { std::size_t a_size = a.size(); std::size_t b_size = b.size(); if (a_size > b_size) { c.resize(a_size); - std::transform(a.begin(), a.begin() + b_size, b.begin(), c.begin(), std::minus()); + nil::crypto3::parallel_transform(a.begin(), a.begin() + b_size, b.begin(), c.begin(), std::minus()); std::copy(a.begin() + b_size, a.end(), c.begin() + b_size); } else { c.resize(b_size); - std::transform(a.begin(), a.end(), b.begin(), c.begin(), std::minus()); - std::transform(b.begin() + a_size, b.end(), c.begin() + a_size, std::negate()); + nil::crypto3::parallel_transform(a.begin(), a.end(), b.begin(), c.begin(), std::minus()); + nil::crypto3::parallel_transform(b.begin() + a_size, b.end(), c.begin() + a_size, std::negate()); } } @@ -239,7 +240,7 @@ namespace nil { if (d == 0) { value_type c = b[0].inversed(); q.resize(a.size()); - std::transform( + nil::crypto3::parallel_transform( std::begin(a), std::end(a), std::begin(q), [&c](const value_type& value) {return value * c;}); // We will always have no reminder here. r.resize(1); @@ -279,7 +280,7 @@ namespace nil { if (b.size() + shift + 1 > r.size()) r.resize(b.size() + shift + 1); auto glambda = [=](value_type x, value_type y) { return y - (x * lead_coeff); }; - std::transform(b.begin(), b.end(), r.begin() + shift, r.begin() + shift, glambda); + nil::crypto3::parallel_transform(b.begin(), b.end(), r.begin() + shift, r.begin() + shift, glambda); condense(r); r_deg = r.size() - 1; diff --git a/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp b/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp index 4608e77..0311c59 100644 --- a/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp +++ b/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp @@ -527,10 +527,15 @@ namespace nil { if (this->size() > other.size()) { polynomial_dfs tmp(other); tmp.resize(this->size()); - nil::crypto3::parallel_transform(this->begin(), this->end(), tmp.begin(), this->begin(), std::minus()); + + nil::crypto3::in_place_parallel_transform(this->begin(), this->end(), tmp.begin(), + [](FieldValueType& v1, const FieldValueType& v2){v1-=v2;}); + return *this; } - nil::crypto3::parallel_transform(this->begin(), this->end(), other.begin(), this->begin(), std::minus()); + + nil::crypto3::in_place_parallel_transform(this->begin(), this->end(), other.begin(), + [](FieldValueType& v1, const FieldValueType& v2){v1-=v2;}); return *this; } @@ -590,11 +595,13 @@ namespace nil { polynomial_dfs tmp(other); tmp.resize(polynomial_s); - nil::crypto3::parallel_transform(tmp.begin(), tmp.end(), this->begin(), this->begin(), std::multiplies()); + nil::crypto3::in_place_parallel_transform(this->begin(), this->end(), tmp.begin(), + [](FieldValueType& v1, const FieldValueType& v2){v1*=v2;}); return *this; } - nil::crypto3::parallel_transform(this->begin(), this->end(), other.begin(), this->begin(), std::multiplies()); + nil::crypto3::in_place_parallel_transform(this->begin(), this->end(), other.begin(), + [](FieldValueType& v1, const FieldValueType& v2){v1*=v2;}); return *this; } diff --git a/include/nil/crypto3/math/polynomial/polynomial_view.hpp b/include/nil/crypto3/math/polynomial/polynomial_view.hpp index baf3ccf..fe73b5a 100644 --- a/include/nil/crypto3/math/polynomial/polynomial_view.hpp +++ b/include/nil/crypto3/math/polynomial/polynomial_view.hpp @@ -31,6 +31,7 @@ #include #include +#include namespace nil { namespace crypto3 { @@ -352,7 +353,7 @@ namespace nil { // polynomial_view operator-() const { void neg() { - std::transform(this->begin(), this->end(), this->begin(), std::negate()); + nil::crypto3::parallel_transform(this->begin(), this->end(), this->begin(), std::negate()); } /** @@ -400,7 +401,7 @@ namespace nil { auto glambda = [=](const FieldValueType& x, const FieldValueType& y) { return y - (x * lead_coeff); }; - std::transform(other.begin(), other.end(), r.begin() + shift, r.begin() + shift, glambda); + nil::crypto3::parallel_transform(other.begin(), other.end(), r.begin() + shift, r.begin() + shift, glambda); r.condense(); r_deg = r.size() - 1; @@ -433,7 +434,7 @@ namespace nil { auto glambda = [=](const FieldValueType& x, const FieldValueType& y) { return y - (x * lead_coeff); }; - std::transform(other.begin(), other.end(), this->begin() + shift, this->begin() + shift, glambda); + nil::crypto3::parallel_transform(other.begin(), other.end(), this->begin() + shift, this->begin() + shift, glambda); this->condense(); r_deg = this->size() - 1; diff --git a/test/polynomial_dfs.cpp b/test/polynomial_dfs.cpp index 8161cb9..a2b7af4 100644 --- a/test/polynomial_dfs.cpp +++ b/test/polynomial_dfs.cpp @@ -1347,12 +1347,24 @@ BOOST_AUTO_TEST_CASE(polynomial_dfs_resize_perf_test, *boost::unit_test::disable values.push_back(nil::crypto3::algebra::random_element()); } + polynomial_dfs poly = { + size - 1, values}; + + auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < 10; ++i) { - polynomial_dfs poly = { - size - 1, values}; - poly.resize(8 * size); - BOOST_CHECK(poly.size() == 8 * size); + auto poly2 = poly; + poly2.resize(8 * size); + + BOOST_CHECK(poly2.size() == 8 * size); } + + // Record the end time + auto end = std::chrono::high_resolution_clock::now(); + + // Calculate the duration + auto duration = std::chrono::duration_cast(end - start); + + std::cout << "Resize time: " << duration.count() << " microseconds." << std::endl; } BOOST_AUTO_TEST_SUITE_END()