16 #include "../../sequential/sequential/sequential.hpp" 29 const std::set<nat_type> &previous_bad_table,
31 unsigned int range_size,
32 unsigned int master_range_size) {
35 assert(first_n <= last_n);
45 const nat_type bad_first_n = (previous_bad_table.empty()
49 std::set<nat_type> bad_table(previous_bad_table);
51 std::set<nat_type>* bad_tables =
new std::set<nat_type>[nb_process]();
55 for (
unsigned int i = 1; i < nb_process; ++i) {
57 first_ns[i] = first_n;
60 for (
nat_type n = first_n; n <= last_n; ) {
67 n += master_range_size;
69 for (
unsigned int i = 1; (i < nb_process) && (n <= last_n); ++i) {
81 bad_table.insert(new_bad_table.cbegin(), new_bad_table.cend());
88 bad_first_n, bad_last_n,
92 std::set<nat_type> diff;
94 std::set_difference(bad_table.cbegin(), bad_table.cend(),
95 bad_tables[i].cbegin(),
97 std::inserter(diff, diff.begin()));
98 bad_tables[i].insert(diff.cbegin(), diff.cend());
108 const std::set<nat_type> new_bad_table
111 std::min(first_ns[0] + master_range_size - 1, last_n),
113 bad_first_n, bad_last_n,
117 bad_table.insert(new_bad_table.cbegin(), new_bad_table.cend());
125 for (
unsigned int i = 1; i < nb_process; ++i) {
133 bad_table.insert(new_bad_table.cbegin(), new_bad_table.cend());
148 const std::set<nat_type> &previous_bad_table,
151 assert(3 <= first_n);
152 assert(first_n <= last_n);
160 const nat_type bad_first_n = (previous_bad_table.empty()
164 std::set<nat_type> bad_table(previous_bad_table);
166 std::set<nat_type>* bad_tables =
new std::set<nat_type>[nb_process]();
167 bool* is_lowers =
new bool[nb_process];
170 for (
nat_type n = first_n; n <= last_n; ) {
171 unsigned int nb_process_required = 0;
175 for ( ; (nb_process_required < nb_process) && (n <= last_n); n += 2) {
177 ns[nb_process_required] = n;
179 if (nb_process_required > 0) {
181 bad_first_n, ns[0] - 1,
182 nb_process_required);
185 std::set<nat_type> diff;
187 std::set_difference(bad_table.cbegin(), bad_table.cend(),
188 bad_tables[nb_process_required].cbegin(),
189 bad_tables[nb_process_required].cend(),
190 std::inserter(diff, diff.begin()));
191 bad_tables[nb_process_required].insert(diff.cbegin(), diff.cend());
195 ++nb_process_required;
203 bad_first_n, ns[0] - 1);
206 for (
unsigned int i = 1; i < nb_process_required; ++i) {
211 for (
unsigned int i = 0; i < nb_process_required; ++i) {
213 bad_table.insert(ns[i]);
215 std::cout << ns[i] << std::endl;
224 for (
unsigned int i = 1; i < nb_process; ++i) {
238 static std::set<nat_type> static_bad_table;
250 static_bad_table.insert(bad_table.cbegin(), bad_table.cend());
266 static std::set<nat_type> static_bad_table;
274 std::set<nat_type> new_bad_table;
280 static_bad_table.insert(bad_table.cbegin(), bad_table.cend());
303 char version_str[MPI_MAX_LIBRARY_VERSION_STRING];
306 MPI_Get_version(&version, &subversion);
307 MPI_Get_library_version(version_str, &version_str_len);
309 std::cout <<
"Open MPI standard version: " << version <<
"." << subversion
310 <<
"\tLibrary version: " << version_str << std::endl;
318 const uint32_t size =
static_cast<uint32_t
>(bad_table.size());
322 const std::vector<nat_type> bad_table_vector(bad_table.cbegin(), bad_table.cend());
324 #pragma GCC diagnostic push 325 #pragma GCC diagnostic ignored "-Wold-style-cast" 326 MPI_Send(bad_table_vector.data(), size, MPI_UINT64_T, to_rank, 0, MPI_COMM_WORLD);
327 #pragma GCC diagnostic pop 337 std::vector<nat_type> bad_table_vector(size);
339 #pragma GCC diagnostic push 340 #pragma GCC diagnostic ignored "-Wold-style-cast" 341 MPI_Recv(bad_table_vector.data(), size, MPI_UINT64_T, from_rank, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
342 #pragma GCC diagnostic pop 344 const std::set<nat_type> bad_table(bad_table_vector.cbegin(), bad_table_vector.cend());
std::vector< nat_type > sequential_print_in_order(const std::set< nat_type > &ns)
Print number from ns, in increasing order and return a list of these number in the same order...
std::set< nat_type > sequential_check_gentle_varsigma_odd(nat_type first_n, nat_type last_n, bool print_bad)
Check in the order all odd gentle numbers between first_n and last_n, and if print_bad then print all...
void send_size_to(unsigned int size, rank_type to_rank)
Send a size to a process.
bool mpi_slave_wait_compute_n()
Computation of one n by a slave, for the mpi_check_gentle_varsigma_odd__one_by_one() master function...
unsigned int wait_size_from(rank_type from_rank)
Wait and receive a size from a process.
Structure for n, first_n and last_n values.
void send_bool_to_master(bool b)
Send a boolean value to the master.
constexpr bool is_odd(nat_type n)
Return true iff n is odd.
first_last_bad_bad_type wait_first_last_bad_bad_from_master()
Wait and receive values first_n, last_n and bad_last_n from the master.
constexpr bool is_even(nat_type n)
Return true iff n is even.
bool sequential_is_varsigma_odd_lower(nat_type n, const std::set< nat_type > &bad_table, nat_type bad_first_n)
Return true iff varsigma_odd(n) < n.
void print_mpi_versions()
Print the Open MPI version and the library version.
void send_finished_to_master()
Send a finished empty message to the master.
sigmaodd::nat_type nat_type
std::set< nat_type > wait_bad_table_from(rank_type from_rank)
Wait and receive bad values from a process.
bool wait_bool_from(rank_type from_rank)
Wait and receive a boolean value from a process.
unsigned int mpi_nb_process()
Return the number of process.
constexpr nat_type MAX_POSSIBLE_N
Lower bound of the bigger number such that it is possible to compute the result of the sigma function...
constexpr nat_type sequential_min_array(const nat_type ns[], size_t size)
Return the minimum of the first size values of ns.
unsigned int rank_type
Type of MPI rank.
bool is_finished_from(rank_type from_rank)
Return true iff the process send an empty finished message.
void send_bad_table_to(const std::set< nat_type > &bad_table, rank_type to_rank)
Send bad values to a process.
Structure for first_n, last_n, bad_first_n and bad_last_n values.
std::set< nat_type > mpi_check_gentle_varsigma_odd__one_by_one(nat_type first_n, nat_type last_n, const std::set< nat_type > &previous_bad_table, bool print_bad)
constexpr bool is_first_mersenne_prime_unitary_divide_or_square(nat_type n)
Return true iff is_first_mersenne_prime_unitary_divide(n) or is_square(n).
void send_first_last_bad_bad_to(nat_type first_n, nat_type last_n, nat_type bad_first_n, nat_type bad_last_n, rank_type to_rank)
Send first_n, last_n, bad_first and bad_last_n to a process.
std::set< nat_type > mpi_check_gentle_varsigma_odd__dynamic(nat_type first_n, nat_type last_n, const std::set< nat_type > &previous_bad_table, bool print_bad, unsigned int range_size, unsigned int master_range_size)
Check in the order all odd gentle numbers between first_n and last_n, and if print_bad then print all...
Implementation of the message-passing (MPI) algorithms presented in the report.
bool mpi_slave_wait_compute_range()
Computation of one range by a slave, for the mpi_check_gentle_varsigma_odd__dynamic() master function...
n_bad_bad_type wait_n_bad_bad_from_master()
Wait and receive values n, first_n and last_n from the master.
void wait_finished_from(rank_type from_rank)
Wait and received a finished empty message from a process.
void send_n_bad_bad_to(nat_type n, nat_type first_n, nat_type last_n, rank_type to_rank)
Send n, first_n and last_n to a process.