/* Author: Landon Bland */
 
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <gmp.h>
#include <time.h>
#include "mpi.h"
int main (int argc, char *argv[]){
    int i, rank, num_procs, sharedbuffer=0, localbuffer=0, flag=0;
    clock_t start, end;
    double elapsed;
    start = clock();
    mpz_t     N;
    mpz_t     B,A,test,two,Q;
    mpz_init(N);
    mpz_init_set_str (N, argv[1], 10);   /* 2533965587 136868736177707213657 951481467360591658636268654185633689926419097 */
    mpz_init(A);
    mpz_init(B);
    mpz_init(Q);
    mpz_init(test);
    mpz_init(two);
    mpz_init_set_str(two,"2",10);
    mpz_tdiv_qr(Q,test,N,two);  
    if (mpz_cmp_ui(test,0) == 0) {
        end = clock();
        elapsed=((double) (end - start)) / CLOCKS_PER_SEC;
        mpz_out_str (stdout, 10, N);
        printf("=2 * ");
        mpz_out_str (stdout, 10, Q);
        printf("\nelapsed time = ");
        printf(" %f seconds \n", elapsed);
        return 0;
    }
    mpz_init_set_str(B,"3",10);
    mpz_sqrt(A,N);
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
    MPI_Win win;
    MPI_Win_create(&sharedbuffer, 1, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
    MPI_Request request;
    MPI_Status status;
    mpz_t mpz_proc_rank;
    mpz_init(mpz_proc_rank);
    mpz_set_si(mpz_proc_rank, i);
    mpz_add_ui(B, B, 2*rank);
    MPI_Win_fence(0, win);
    int working=0, count=0;
    while ( mpz_cmp(A,B) >= 0) {
        if (!working) {
            for (i=0; i<num_procs; i++) {
                MPI_Irecv(&localbuffer, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &request);
            }
            MPI_Test(&request, &flag, &status);
            working=1;
        } else {
            if (flag) {
                working=0;
                count=0;
            } else if (count % 1000 == 0) {
                MPI_Test(&request, &flag, &status);
            }
        }
        mpz_tdiv_qr(Q,test,N,B);  
        if (mpz_cmp_ui(test,0) == 0) {
            end = clock();
            elapsed=((double) (end - start)) / CLOCKS_PER_SEC;
            sharedbuffer=1; localbuffer=1;
            MPI_Put(&sharedbuffer, 1, MPI_INT, 0, 0, 1, MPI_INT, win);
            for (i=0; i<num_procs; i++) {
                MPI_Isend(&localbuffer, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &request);
            }
            mpz_out_str (stdout, 10, N);
            printf("=  ");
            mpz_out_str (stdout, 10, Q);
            printf(" * ");
            mpz_out_str (stdout, 10, B);
            printf("   \n");
            printf("elapsed time = ");
            printf(" %f seconds  \n", elapsed);
            break;
        }
        if (localbuffer) {
            break;
        }
        mpz_add_ui(B,B,(2*num_procs));
        count++;
    }
    MPI_Win_fence(0, win);
    if (rank==0) {
        for (i=1; i<num_procs; i++) {
            MPI_Get(&sharedbuffer, 1, MPI_INT, i, 0, 1, MPI_INT, win);
        }
    }
    MPI_Finalize();
    if (rank == 0) {
        if (!sharedbuffer) {
            mpz_out_str (stdout, 10, N);
            printf(" is a prime. \n");
        }
        end = clock();
        elapsed=((double) (end - start)) / CLOCKS_PER_SEC;
        printf("total elapsed time = ");
        printf(" %f seconds  \n", elapsed);
    }
    return 0;
}


Command Line


SLURM 4 Tasks



136868736177707213657=  32416183339 * 4222234763   
elapsed time =  28.550000 seconds  
total elapsed time =  28.560000 seconds