#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <gmp.h>
#include <time.h>
#include <mpi.h>
#define NUM_ELEMENT 1
int main (int argc, char *argv[]){
int i, rank, num_procs, len, localbuffer[NUM_ELEMENT], sharedbuffer[NUM_ELEMENT];
char name[MPI_MAX_PROCESSOR_NAME];
char holder[50];
int len_holder;
MPI_Win win;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Win_create(sharedbuffer, NUM_ELEMENT, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &win);
for (i = 0; i < rank; i++) {
sharedbuffer[0] =-1;
localbuffer[0] = rank;
}
clock_t start, end;
double elapsed;
start = clock();
mpz_t N,rank_start,rank_end,rank_length;
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(rank_start); mpz_init(rank_end);mpz_init(rank_length);
mpz_init_set_str(two,"2",10);
mpz_tdiv_qr(Q,test,N,two);
if (mpz_cmp_ui(test,0) == 0) {
if (rank==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);
}
MPI_Win_free(&win);
MPI_Finalize();
return 0;
}
mpz_sqrt(A,N);
mpz_div_ui(rank_length,A,num_procs);//I want to be sure this is an even number
mpz_tdiv_qr(Q,test,rank_length,two);
if (mpz_cmp_ui(test,0) != 0) {
mpz_add_ui(rank_length,rank_length,1);
}
if (rank==0) {
mpz_init_set_str(rank_start,"3",10);
} else {
mpz_mul_ui(B,rank_length,rank);
mpz_add_ui(rank_start,B,3);
}
if (rank==(num_procs-1)) {
mpz_set(rank_end,A);
} else {
mpz_add(rank_end,rank_start,rank_length);
}
mpz_set(B,rank_start);
MPI_Win_fence(0, win);
while ( mpz_cmp(rank_end,B) >= 0) {
mpz_tdiv_qr(Q,test,N,B);
if (mpz_cmp_ui(test,0) == 0) {
MPI_Put(&localbuffer[0], NUM_ELEMENT, MPI_INT, 0, 0, NUM_ELEMENT, MPI_INT, win);
sharedbuffer[0]=rank;
break;
}
if (sharedbuffer[0]!=-1)break;/* Not really useful */
mpz_add_ui(B,B,2);
}
MPI_Win_fence(0, win);
if (sharedbuffer[0]==rank) {
mpz_get_str(holder,10,B);
len_holder=strlen(holder);
MPI_Send(&len_holder,1, MPI_INT, 0, 123, MPI_COMM_WORLD);
MPI_Send(&holder,len_holder, MPI_CHAR, 0, 1234, MPI_COMM_WORLD);
}
if (rank==0) {
MPI_Recv(&len_holder,1, MPI_INT, sharedbuffer[0], 123, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&holder, len_holder, MPI_CHAR, sharedbuffer[0], 1234, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("%s\n",holder);
end = clock();
elapsed=((double) (end - start)) / CLOCKS_PER_SEC;
printf("elapsed time = ");
printf(" %f seconds \n", elapsed);
}
MPI_Win_free(&win);
MPI_Finalize();
return 0;;
}
The Teaching Cluster
The Original Serial Code
4222234763
elapsed time = 106.660000 seconds
A Command Line Run
4 Tasks 4 Nodes
4222234763
elapsed time = 68.820000 seconds
4 Tasks 4 Cores
4222234763
elapsed time = 69.020000 seconds
The Research Cluster
4 Tasks 4 Nodes
4222234763
elapsed time = 60.220000 seconds
8 Tasks 8 Nodes
4222234763
elapsed time = 28.080000 seconds
16 Tasks 16 Nodes
4222234763
elapsed time = 15.350000 seconds
20 Tasks 20 Nodes
4222234763
elapsed time = 12.710000 seconds
24 Tasks 24 Nodes
4222234763
elapsed time = 10.560000 seconds