Friday, May 4, 2012

Code:

#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <time.h>
#include <ctime>
#include <cmath>
#include <iterator>
#include <functional>
#include <algorithm>
#include <vector>
#include<iostream>
#include<mpi.h>


#include <stack>
using namespace std;
void swap1(signed int &a, signed int &b)
{
signed int temp;
temp = a;
a = b;
b = temp;
}

#define KILO (1024)
#define MEGA (1024*1024)
#define giga (1024*MEGA)
#define MAX_ITEMS (100*MEGA)
#define swap(v, a, b) {unsigned tmp; tmp=v[a]; v[a]=v[b]; v[b]=tmp;}



typedef struct{
int *v;
unsigned low;
unsigned high;
}qsortinput;

void sample_qsort( signed int * begin, signed int * end)
{
    if (begin != end) {
        --end;  // Exclude last element (pivot) from partition
        signed int * middle = std::partition(begin, end,
                          std::bind2nd(std::less<signed int>(), *end));
        using std::swap;
        swap1(*end, *middle);    // move pivot to middle
     
        sample_qsort(begin, middle);
        sample_qsort(++middle, ++end); // Exclude pivot and restore end
     
    }
}


static int *v;

static void
print_array(void)
{
   int i;

   for (i = 0; i < MAX_ITEMS; i++)
       printf("%d\n ", v[i]);
   printf("\n");
}

static void
init_array(void)
{
   int i;

   v = (int *) malloc(MAX_ITEMS*sizeof(int));
   for (i = 0; i < MAX_ITEMS; i++)
       v[i] = rand();
}

static unsigned
partition(int *v, unsigned low, unsigned high, unsigned pivot_index)
{
     if (pivot_index != low)
       swap(v, low, pivot_index);

   pivot_index = low;
   low++;

      while (low <= high) {
       if (v[low] <= v[pivot_index])
           low++;
       else if (v[high] > v[pivot_index])
           high--;
       else
           swap(v, low, high);
   }

     if (high != pivot_index)
       swap(v, pivot_index, high);
   return high;
}



int
main(int argc, char **argv)
{
//double start,end;
clock_t begin=clock();
init_array();



   stack<qsortinput*> xx;


   qsortinput* fx = (qsortinput*)malloc(sizeof(qsortinput));
   fx->v = v;
   fx->low = 0;
   fx->high = MAX_ITEMS-1;
   xx.push(fx);



   while(xx.size()){
       qsortinput *i = xx.top();
       int pivot_index;
       xx.pop();
       if (i->low < i->high){

       pivot_index = (i->low + i->high) / 2;
       pivot_index = partition(i->v, i->low, i->high, pivot_index);
       //printf(" size of the stack ::%d\n",xx.size());

       if (i->low < pivot_index){
       qsortinput* l = (qsortinput*)malloc(sizeof(qsortinput));
       l->low = i->low;
       l->high = pivot_index;
       l->v = v;
       xx.push(l); // add left to the stack
       }
       if (pivot_index < i->high){
       qsortinput* r = (qsortinput*)malloc(sizeof(qsortinput));
       r->low = pivot_index+1;
       r->high = i->high;
       r->v = v;
       xx.push(r); // add right to the stack
       }

        if(xx.size() == 7){
               break;
       }


       }
}

   //printf("size of the stack total ::%d\n",xx.size());


    int proc;
int rank;

 int done;
MPI_Request request;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &proc);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Barrier(MPI_COMM_WORLD);
//double start,end;
//clock_t begin=clock();
if (rank == 0)
{
clock_t begin=clock();
int j=1;
while(xx.size())
{
qsortinput* o = xx.top();
xx.pop();
int h=(o->high)-(o->low)+1;
 MPI_Send(&h,1, MPI_INT, j, 666,MPI_COMM_WORLD);
MPI_Send(v+o->low,h, MPI_INT, j, 666,MPI_COMM_WORLD);
//printf("send to rank :%d: size:%d  \n\t",j,h);
MPI_Recv(v+o->low,h,MPI_INT,j,55,MPI_COMM_WORLD,&status);
//for ( int f =o->low; f < o->high; f++)
//{
//printf(" array from %d::%d \n \t ",rank,v[f]);
//}
 MPI_Test(&request,&done,&status);
j++;
}

clock_t end=clock();
////end=MPI_Wtime();
printf("time at master::%f",((double) (end - begin)) / CLOCKS_PER_SEC);
//cout << "Time elapsed: " << double(diffclock(end,begin)) << " ms"<< endl;
//print_array();

}

else
{
    clock_t begin1=clock();
    MPI_Status status;
int count;
 MPI_Recv(&count,1,MPI_INT,0,666,MPI_COMM_WORLD,&status);
 //printf("count%d \n \t",count);

 int* sub=(int*)malloc(sizeof(int) * count);
    MPI_Recv(sub,count,MPI_INT,0,666,MPI_COMM_WORLD,&status);
//for ( int f =0; f <count; f++)
//{
//printf(" array from %d::%d \n \t ",rank,sub[f]);
//}
//quick_sort(sub,0,count);
    sample_qsort(sub, sub+count);
MPI_Send(sub,count,MPI_INT,0,55,MPI_COMM_WORLD);
delete [] sub;
sub = NULL;
clock_t end1=clock();
//end=MPI_Wtime();
printf("time at %d::%f \n \t",rank,((double) (end1 - begin1)) / CLOCKS_PER_SEC);
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();


}