#include <mpi.h>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
void sieve_of_eratosthenes(int start, int end, std::vector<int>& primes) {
std::vector<bool> is_prime(end - start + 1, true);
int limit
= std
::sqrt(end
);
for (int i = 2; i <= limit; ++i) {
int multiple_start = std::max(i * i, (start + i - 1) / i * i);
for (int j = multiple_start; j <= end; j += i) {
is_prime[j - start] = false;
}
}
for (int i = start; i <= end; ++i) {
if (i > 1 && is_prime[i - start]) {
primes.push_back(i);
}
}
}
int main(int argc, char* argv[]) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (argc < 2) {
if (rank == 0) {
std::cerr << "Usage: " << argv[0] << " <n>" << std::endl;
}
MPI_Finalize();
return 1;
}
int n
= std
::atoi(argv
[1]); double start_time = MPI_Wtime();
// Distribute ranges among processes
int local_start = (rank * n) / size + 1;
int local_end = ((rank + 1) * n) / size;
std::vector<int> primes;
sieve_of_eratosthenes(local_start, local_end, primes);
// Compute local maximum gap
int local_max_gap = 0;
for (size_t i = 1; i < primes.size(); ++i) {
int gap = primes[i] - primes[i - 1];
local_max_gap = std::max(local_max_gap, gap);
}
// Share boundary primes with neighboring processes
int left_prime = (primes.empty() ? 0 : primes.front());
int right_prime = (primes.empty() ? 0 : primes.back());
int left_neighbor_prime = 0, right_neighbor_prime = 0;
MPI_Request requests[4];
MPI_Isend(&left_prime, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, &requests[0]);
MPI_Isend(&right_prime, 1, MPI_INT, rank + 1, 1, MPI_COMM_WORLD, &requests[1]);
MPI_Irecv(&left_neighbor_prime, 1, MPI_INT, rank - 1, 1, MPI_COMM_WORLD, &requests[2]);
MPI_Irecv(&right_neighbor_prime, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD, &requests[3]);
MPI_Waitall(4, requests, MPI_STATUSES_IGNORE);
// Adjust gaps with boundary primes
if (left_neighbor_prime > 0 && !primes.empty()) {
int boundary_gap = primes.front() - left_neighbor_prime;
local_max_gap = std::max(local_max_gap, boundary_gap);
}
if (right_neighbor_prime > 0 && !primes.empty()) {
int boundary_gap = right_neighbor_prime - primes.back();
local_max_gap = std::max(local_max_gap, boundary_gap);
}
// Find global maximum gap using reduction
int global_max_gap = 0;
MPI_Reduce(&local_max_gap, &global_max_gap, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
double end_time = MPI_Wtime();
if (rank == 0) {
std::cout << "Max Gap: " << global_max_gap << std::endl;
std::cout << "Time: " << end_time - start_time << " seconds" << std::endl;
}
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPG1waS5oPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxjbWF0aD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCnZvaWQgc2lldmVfb2ZfZXJhdG9zdGhlbmVzKGludCBzdGFydCwgaW50IGVuZCwgc3RkOjp2ZWN0b3I8aW50PiYgcHJpbWVzKSB7CiAgICBzdGQ6OnZlY3Rvcjxib29sPiBpc19wcmltZShlbmQgLSBzdGFydCArIDEsIHRydWUpOwogICAgaW50IGxpbWl0ID0gc3RkOjpzcXJ0KGVuZCk7CgogICAgZm9yIChpbnQgaSA9IDI7IGkgPD0gbGltaXQ7ICsraSkgewogICAgICAgIGludCBtdWx0aXBsZV9zdGFydCA9IHN0ZDo6bWF4KGkgKiBpLCAoc3RhcnQgKyBpIC0gMSkgLyBpICogaSk7CiAgICAgICAgZm9yIChpbnQgaiA9IG11bHRpcGxlX3N0YXJ0OyBqIDw9IGVuZDsgaiArPSBpKSB7CiAgICAgICAgICAgIGlzX3ByaW1lW2ogLSBzdGFydF0gPSBmYWxzZTsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChpbnQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgKytpKSB7CiAgICAgICAgaWYgKGkgPiAxICYmIGlzX3ByaW1lW2kgLSBzdGFydF0pIHsKICAgICAgICAgICAgcHJpbWVzLnB1c2hfYmFjayhpKTsKICAgICAgICB9CiAgICB9Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2W10pIHsKICAgIE1QSV9Jbml0KCZhcmdjLCAmYXJndik7CgogICAgaW50IHJhbmssIHNpemU7CiAgICBNUElfQ29tbV9yYW5rKE1QSV9DT01NX1dPUkxELCAmcmFuayk7CiAgICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmc2l6ZSk7CgogICAgaWYgKGFyZ2MgPCAyKSB7CiAgICAgICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgICAgICBzdGQ6OmNlcnIgPDwgIlVzYWdlOiAiIDw8IGFyZ3ZbMF0gPDwgIiA8bj4iIDw8IHN0ZDo6ZW5kbDsKICAgICAgICB9CiAgICAgICAgTVBJX0ZpbmFsaXplKCk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgaW50IG4gPSBzdGQ6OmF0b2koYXJndlsxXSk7CiAgICBkb3VibGUgc3RhcnRfdGltZSA9IE1QSV9XdGltZSgpOwoKICAgIC8vIERpc3RyaWJ1dGUgcmFuZ2VzIGFtb25nIHByb2Nlc3NlcwogICAgaW50IGxvY2FsX3N0YXJ0ID0gKHJhbmsgKiBuKSAvIHNpemUgKyAxOwogICAgaW50IGxvY2FsX2VuZCA9ICgocmFuayArIDEpICogbikgLyBzaXplOwoKICAgIHN0ZDo6dmVjdG9yPGludD4gcHJpbWVzOwogICAgc2lldmVfb2ZfZXJhdG9zdGhlbmVzKGxvY2FsX3N0YXJ0LCBsb2NhbF9lbmQsIHByaW1lcyk7CgogICAgLy8gQ29tcHV0ZSBsb2NhbCBtYXhpbXVtIGdhcAogICAgaW50IGxvY2FsX21heF9nYXAgPSAwOwogICAgZm9yIChzaXplX3QgaSA9IDE7IGkgPCBwcmltZXMuc2l6ZSgpOyArK2kpIHsKICAgICAgICBpbnQgZ2FwID0gcHJpbWVzW2ldIC0gcHJpbWVzW2kgLSAxXTsKICAgICAgICBsb2NhbF9tYXhfZ2FwID0gc3RkOjptYXgobG9jYWxfbWF4X2dhcCwgZ2FwKTsKICAgIH0KCiAgICAvLyBTaGFyZSBib3VuZGFyeSBwcmltZXMgd2l0aCBuZWlnaGJvcmluZyBwcm9jZXNzZXMKICAgIGludCBsZWZ0X3ByaW1lID0gKHByaW1lcy5lbXB0eSgpID8gMCA6IHByaW1lcy5mcm9udCgpKTsKICAgIGludCByaWdodF9wcmltZSA9IChwcmltZXMuZW1wdHkoKSA/IDAgOiBwcmltZXMuYmFjaygpKTsKICAgIGludCBsZWZ0X25laWdoYm9yX3ByaW1lID0gMCwgcmlnaHRfbmVpZ2hib3JfcHJpbWUgPSAwOwoKICAgIE1QSV9SZXF1ZXN0IHJlcXVlc3RzWzRdOwogICAgTVBJX0lzZW5kKCZsZWZ0X3ByaW1lLCAxLCBNUElfSU5ULCByYW5rIC0gMSwgMCwgTVBJX0NPTU1fV09STEQsICZyZXF1ZXN0c1swXSk7CiAgICBNUElfSXNlbmQoJnJpZ2h0X3ByaW1lLCAxLCBNUElfSU5ULCByYW5rICsgMSwgMSwgTVBJX0NPTU1fV09STEQsICZyZXF1ZXN0c1sxXSk7CiAgICBNUElfSXJlY3YoJmxlZnRfbmVpZ2hib3JfcHJpbWUsIDEsIE1QSV9JTlQsIHJhbmsgLSAxLCAxLCBNUElfQ09NTV9XT1JMRCwgJnJlcXVlc3RzWzJdKTsKICAgIE1QSV9JcmVjdigmcmlnaHRfbmVpZ2hib3JfcHJpbWUsIDEsIE1QSV9JTlQsIHJhbmsgKyAxLCAwLCBNUElfQ09NTV9XT1JMRCwgJnJlcXVlc3RzWzNdKTsKCiAgICBNUElfV2FpdGFsbCg0LCByZXF1ZXN0cywgTVBJX1NUQVRVU0VTX0lHTk9SRSk7CgogICAgLy8gQWRqdXN0IGdhcHMgd2l0aCBib3VuZGFyeSBwcmltZXMKICAgIGlmIChsZWZ0X25laWdoYm9yX3ByaW1lID4gMCAmJiAhcHJpbWVzLmVtcHR5KCkpIHsKICAgICAgICBpbnQgYm91bmRhcnlfZ2FwID0gcHJpbWVzLmZyb250KCkgLSBsZWZ0X25laWdoYm9yX3ByaW1lOwogICAgICAgIGxvY2FsX21heF9nYXAgPSBzdGQ6Om1heChsb2NhbF9tYXhfZ2FwLCBib3VuZGFyeV9nYXApOwogICAgfQogICAgaWYgKHJpZ2h0X25laWdoYm9yX3ByaW1lID4gMCAmJiAhcHJpbWVzLmVtcHR5KCkpIHsKICAgICAgICBpbnQgYm91bmRhcnlfZ2FwID0gcmlnaHRfbmVpZ2hib3JfcHJpbWUgLSBwcmltZXMuYmFjaygpOwogICAgICAgIGxvY2FsX21heF9nYXAgPSBzdGQ6Om1heChsb2NhbF9tYXhfZ2FwLCBib3VuZGFyeV9nYXApOwogICAgfQoKICAgIC8vIEZpbmQgZ2xvYmFsIG1heGltdW0gZ2FwIHVzaW5nIHJlZHVjdGlvbgogICAgaW50IGdsb2JhbF9tYXhfZ2FwID0gMDsKICAgIE1QSV9SZWR1Y2UoJmxvY2FsX21heF9nYXAsICZnbG9iYWxfbWF4X2dhcCwgMSwgTVBJX0lOVCwgTVBJX01BWCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIGRvdWJsZSBlbmRfdGltZSA9IE1QSV9XdGltZSgpOwogICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgIHN0ZDo6Y291dCA8PCAiTWF4IEdhcDogIiA8PCBnbG9iYWxfbWF4X2dhcCA8PCBzdGQ6OmVuZGw7CiAgICAgICAgc3RkOjpjb3V0IDw8ICJUaW1lOiAiIDw8IGVuZF90aW1lIC0gc3RhcnRfdGltZSA8PCAiIHNlY29uZHMiIDw8IHN0ZDo6ZW5kbDsKICAgIH0KCiAgICBNUElfRmluYWxpemUoKTsKICAgIHJldHVybiAwOwp9Cg==