MPI design about prime number an
2019-11-07 本文已影响0人
五长生
MPI: message exchange in the processes
in this article, I just use MPI_SEND and MPI_RECV.
C++ version
#include<stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator> // ostream_iterator
#include "/usr/include/mpi/mpi.h"
const int MAX_NUMBERS = 100;
using namespace std;
int prime_number(int n)
{
int i;
if(n < 2 ) return 0;
for(i = 2; i < n; i++)
{
if( n % i == 0)
return 0;
}
return 1;
}
int find_min_prime(int number, int rank)
{
int temp;
int check_number;
temp = int(number / 8);
if( 8 * temp + 2 * rank + 1 <= number )
temp = temp + 1;
while (1)
{
check_number = temp * 8 + 2 * rank + 1;
if (prime_number(check_number))
break;
temp += 1 ;
}
return check_number;
}
int find_twin_number(int number, int rank)
{
int n;
while(1)
{
n = find_min_prime(number, rank);
if( prime_number(n+2))
return (n,n+2);
else
number += 1;
}
}
vector<int> count_twin(int number, int rank)
{
int bottom;
int above;
int n;
bottom = rank;
above = number;
vector< int> list;
int * twin = new int[100]();
int i = 0;
while(1)
{
n = find_min_prime(bottom,rank);
if (n + 2 > above)
break;
if (prime_number(n+2))
{
list.push_back(n);
}
bottom += 1;
}
std::vector<int>::iterator it;
it = std::unique (list.begin(), list.end()); // 10 20 30 20 10 ? ? ? ?
list.resize( std::distance(list.begin(),it) ); // 10 20 30 20 10
return list;
}
int main(int argc, char* argv[])
{
int a ;
int prime;
int state = 0;
int number_amount;
vector<int> list;
vector<int> un_list;
vector< int> list_prime_number;
vector< int> list_twin_number;
int numprocs, myid, source;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
int number = 20;
int message;
if (myid == 4)
{
for(int i = 0; i<4; i++)
{
MPI_Send(&number, 1, MPI_INT, i, 11,MPI_COMM_WORLD);
cout<< "send " << number << " to processes "<< i <<" for problem 3"<< endl;
}
for(int i = 0; i<4; i++)
{
MPI_Recv(&message, 1, MPI_INT, i, 12,MPI_COMM_WORLD,NULL);
list_prime_number.push_back(message);
MPI_Recv(&message, 1, MPI_INT, i, 13,MPI_COMM_WORLD,NULL);
list_twin_number.push_back(message);
}
int least_prime_number = *min_element(list_prime_number.begin(),list_prime_number.end());
int least_twin_number = *min_element(list_twin_number.begin(),list_twin_number.end());
cout<< "the least prime number is " << least_prime_number <<endl;
cout<< "the least twin number is (" << least_twin_number <<","<< least_twin_number +2<< ")" << endl;
}
else
{
MPI_Recv(&message, 1, MPI_INT, 4, 11,MPI_COMM_WORLD,NULL);
int prime_number = find_min_prime(message,myid);
int twin_number = find_twin_number(message,myid);
cout<< "the prime number is " << prime_number << " at process "<< myid<<" for problem 4 "<<endl;
cout<< "the twin number is (" << twin_number <<","<< twin_number +2<< ")" << " at process "<< myid<<" for problem 4 "<<endl;
MPI_Send(&prime_number, 1, MPI_INT, 4, 12,MPI_COMM_WORLD);
MPI_Send(&twin_number, 1, MPI_INT, 4, 13,MPI_COMM_WORLD);
list = count_twin(message,myid);
MPI_Send(&list[0], list.size(), MPI_INT, 4, 14,MPI_COMM_WORLD);
}
vector<int> twin_list;
if (myid == 4)
{
// MPI_Status status;
for(int i = 0;i < 4;i++)
{
vector<int> list2(MAX_NUMBERS);
MPI_Recv(&list2[0], MAX_NUMBERS, MPI_INT, i, 14,MPI_COMM_WORLD,NULL);
for(int f = 0;f<list2.size();f++)
{
if (list2[f] != 0)
{
// cout<<list2[f] << " get from process :"<< i <<endl;
twin_list.push_back(list2[f]);}
}
}
for (int i = 0;i < twin_list.size();i++)
cout<< twin_list[i] <<" the twin list"<<endl;
int length = twin_list.size();
cout<<" the twin list counts number is : "<<length <<endl;
}
MPI_Finalize();
return 0;
}
python version
from mpi4py import MPI
import numpy as np
import argparse
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
parser = argparse.ArgumentParser()
parser.add_argument('--n', nargs='?', type=int, default=50,
help='must be int')
arg = parser.parse_args()
n = arg.n
def prime_number(n):
if n < 2 :
return False
for i in range(2,n):
if n%i == 0:
return False
return True
def find_min_prime(number,rank):
temp = number // 8
if 8 * temp + 2 * rank + 1 <= number :
temp = temp + 1
while (1):
check_number = temp * 8 + 2 * rank + 1
# print(check_number)
if prime_number(check_number):
break
temp += 1
return check_number
def find_twin_number(number, rank):
while(1):
n = find_min_prime(number, rank)
if prime_number(n+2):
return (n,n+2)
else:
number += 1
def count_twin(number, rank):
bottom = int(rank)
above = int(number)
twin = []
while(1):
n = find_min_prime(bottom,rank)
if n + 2 > above:
break
if prime_number(n+2):
if (n,n+2) not in twin:
twin.append ((n,n+2))
bottom += 1
return twin
if rank == 4:
data = int(n)
for i in range(4):
comm.isend(data, dest=i, tag=11)
print("process {} immediate send {}...for problem 2".format(rank, data))
else:
# for rank in range(4)
data_count_twin = count_twin(n,rank)
data = comm.recv(source=4, tag=11)
print("process {} recv {}...".format(rank, data))
# data = data + 2 * rank +1
prime_number,twin_number = find_min_prime(data,rank),find_twin_number(data,rank)
data = {'prime_number':prime_number,'twin_number':twin_number}
comm.isend(data, dest=4, tag=12)
print("process {} immediate send {}... for problem 4".format(rank, data))
# print('rank',rank, 'count', data_count_twin)
comm.isend(data_count_twin, dest=4, tag=13)
print("process {} immediate send {}... for problem 5".format(rank, data_count_twin))
data_twin = []
data_fin = []
if rank == 4:
for i in range(4):
temp = comm.recv(source = i, tag = 12)
data_fin.append(temp)
print("process {} immediate recv {}...".format(rank, temp))
least_min_twin = min([i['twin_number'][0] for i in data_fin])
print('min_prime_number: ',min([i['prime_number'] for i in data_fin]), 'min_twin_number: ',(least_min_twin,least_min_twin+2))
for i in range(4):
data_twin.extend(comm.recv(source = i, tag = 13))
data_count = list(set(data_twin))
print('the total number of twin numbers less than n: ',len(data_count))
print(data_count)