Simple Factoring


#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