/*
Some not so big primes
524287, 2147483647, 2305843009213693951,618970019642690137449562111,
162259276829213363391578010288127, 170141183460469231731687303715884105727
*/


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <signal.h>
#include <string.h>
#include "mpi.h"
#include "gmp.h"

int main(int argc,char *argv[]){
    int done = 0, myid, numprocs, i,check_another,result=0,not_prime,mpi_error;
    char prime_buffer[1000];
    mpz_t isprime,divisor,sqroot,remainder,numprocs_z,range,my_range_top;
    unsigned long zero=0;
    unsigned long one=1;
    unsigned long two=2;
    int true=1,first_time=1;
    int is_prime=1,is_not_prime=0;
    double startwtime, endwtime;
    int  namelen;
    char *zero_string="0";
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    FILE *file_pointer;
    char file_name[50];
    MPI_Status status;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Get_processor_name(processor_name,&namelen);
    /*Create one debug info file for each process*/
    sprintf(file_name,"iofile%d",myid);
    file_pointer=fopen(file_name,"w");
    fprintf(file_pointer,"iofile%d\n",myid);
    fflush(file_pointer);
    /*****************************************/
    while (!done) {
        if (myid == 0) {
            strcpy(prime_buffer,zero_string);
            printf("\nDo you want to test a number?\n 0= done \n 1=yes\n ");
            fflush(stdout);
            scanf("%d",&check_another);
            not_prime=0;
            if (check_another!=1)done=1;
            if (!done) {
                printf("\nPlease input the number you wish to check\n");
                fflush(stdout);
                scanf("%s",prime_buffer);
            }
            startwtime = MPI_Wtime();
        }
        MPI_Bcast(prime_buffer, 1000, MPI_CHAR, 0, MPI_COMM_WORLD);
        if ((strlen(prime_buffer) == 1)&&(prime_buffer[0]='0'))
            done = 1;
        else {
            if (first_time) {
                mpz_init (isprime);
                mpz_init (divisor);
                mpz_init(sqroot);
                mpz_init(remainder);
                mpz_init(numprocs_z);
                mpz_init(range);
                mpz_init(my_range_top);
                first_time=0;
            }
            //Make initial Assignments
            mpz_set_ui(numprocs_z,(unsigned long)numprocs);
            mpz_set_str (isprime,prime_buffer, 10);
            mpz_sqrt (sqroot, isprime); //greatest int in square root
            mpz_add_ui(sqroot,sqroot,one);
            mpz_tdiv_q (range, sqroot, numprocs_z); //tdiv means truncate
            if (myid==(numprocs-1))
                mpz_set(my_range_top,sqroot);
            else
                mpz_mul_ui (my_range_top,range, (unsigned long) (myid+1));
            /*--------------------------------*/
            mpz_out_str(file_pointer, 10,numprocs_z);fprintf(file_pointer," is  the numprocs\n");
            mpz_out_str(file_pointer, 10,isprime);fprintf(file_pointer," is  the number.\n");
            mpz_out_str(file_pointer, 10,sqroot);fprintf(file_pointer," is  the square root.\n");
            mpz_out_str(file_pointer, 10,range);fprintf(file_pointer," is  the range.\n");
            mpz_out_str(file_pointer, 10,my_range_top);fprintf(file_pointer," is  the top of my range.\n");
            /*--------------------------------*/
            if (myid==0) {
                mpz_set_str(divisor,"2",10);
                mpz_out_str(file_pointer, 10,divisor);fprintf(file_pointer," is  the divisor\n\n");
                fflush(file_pointer);
            } else {
                mpz_mul_ui (divisor,range, (unsigned long) myid);
                mpz_out_str(file_pointer, 10,divisor);fprintf(file_pointer," is  the divisor\n\n");
                fflush(file_pointer);


            }

            while (true) {
                mpz_tdiv_r (remainder, isprime, divisor);  //use q for quotient
                if (mpz_cmp_ui(remainder, zero)==0) {
                    MPI_Send(&is_not_prime, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
                    break;
                }
                mpz_add_ui(divisor,divisor,one);
                if (mpz_cmp(my_range_top, divisor)<0) {
                    MPI_Send(&is_prime, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
                    break;
                }
            }
            if (myid == 0) {
                for (i = 0; i < numprocs; i++) {
                    MPI_Recv(&result,1, MPI_INT, i,0, MPI_COMM_WORLD, &status);
                    if (result==is_not_prime) not_prime=1;
                    printf(" I heard %d from %d.\n",result,i);
                    fflush(stdout);
                }
                if (not_prime==1)
                    printf("This is not a prime.\n");
                else
                    printf("This is a prime.\n");
                endwtime = MPI_Wtime();
                printf("wall clock time = %f\n",  endwtime-startwtime); 
                fflush(stdout);
            }
        }
    }
    mpi_error=MPI_Finalize();
    if (MPI_SUCCESS!=mpi_error)
        return mpi_error;
    else
        return 0;
}
 /*----------------------------------------------------------------*/
 Brought To You By CToHTML 
http://www.cs.washington.edu/homes/zahorjan/homepage/Tools/index.htm
 
/*----------------------------------------------------------------*/