#include<mpi.h>
#include<stdio.h>
#include <stdlib.h>
#include "tree_sorter.h"
/* A 7 node binary tree*/
int main(int argc, char *argv[]) {
MPI_Status status;
int len;
char name[MPI_MAX_PROCESSOR_NAME];
int rank,i,j,tag_starter=34;
int permute[64];
int part0[32],part1[32]; /*needed for the shuffles*/
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
/*Generate a permutation and send chunks to what will be the top of the tree*/
if (rank==0) {
random64();
j=0;
for (i=3;i<7;i++) {
MPI_Send(&the_permutation[16*j],16, MPI_INT, i, i,MPI_COMM_WORLD);
j++;
}
}
if (rank>2) {
MPI_Recv(&permute,16, MPI_INT, 0, rank, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for (i = 0; i < 16; i++)printf("%i - %d\n", rank, permute[i]);
}
/*Now build the tree*/
int reorder=1; /* Can the processes be reordered, may result in improved performance.*/
int index[] = { 2,5,8,9,10,11,12};
int edges[] = { 1,2,0,3,4,0,5,6,1,1,2,2};
int nneighbors, send_rank=-2,receive_ranks[]={-2,-2};
int tags[7][7];
for (i=0;i<7;i++) {
for (j=0;j<7;j++) {
(i<j)?tags[i][j]=tag_starter++:-2;
}
}
/* One could use the tags either way but this code will only use them in a downward direction, which is being emphasized by
the array values*/
int * intptr=&nneighbors;
int the_neighbors[10];
MPI_Comm MPI_Tree_World;
MPI_Graph_create(MPI_COMM_WORLD, 7, index, edges, reorder,&MPI_Tree_World);
/*int MPI_Graph_neighbors_count(MPI_Comm comm,int rank, int *nneighbors); */
MPI_Graph_neighbors_count(MPI_Tree_World,rank, intptr);
/* int MPI_Graph_neighbors (MPI_Comm comm,int rank,int mneighbors, int *neighbors); */
MPI_Graph_neighbors (MPI_Tree_World,rank,nneighbors, the_neighbors);
j=0;
for (i=0;i<nneighbors;i++) {
if (the_neighbors[i]<rank) {
send_rank=the_neighbors[i];
} else {
receive_ranks[j++]=the_neighbors[i];
}
}
MPI_Get_processor_name(name, &len);
if (receive_ranks[0]==-2) {
bubble(permute,16);
MPI_Send(&permute,16, MPI_INT, send_rank, tags[send_rank][rank], MPI_Tree_World);
for (i = 0; i < 16; i++)printf("%i - %d\n", rank, permute[i]);
} else {
if (rank!=0) {
MPI_Recv(&part0,16, MPI_INT, receive_ranks[0], tags[rank][receive_ranks[0]], MPI_Tree_World, MPI_STATUS_IGNORE);
MPI_Recv(&part1,16, MPI_INT, receive_ranks[1], tags[rank][receive_ranks[1]], MPI_Tree_World, MPI_STATUS_IGNORE);
shuffle(part0, part1,permute,16);
MPI_Send(&permute,32, MPI_INT, send_rank, tags[send_rank][rank], MPI_Tree_World);
for (i = 0; i < 32; i++)printf("%i - %d\n", rank, permute[i]);
} else {
MPI_Recv(&part0,32, MPI_INT, receive_ranks[0], tags[rank][receive_ranks[0]], MPI_Tree_World, MPI_STATUS_IGNORE);
MPI_Recv(&part1,32, MPI_INT, receive_ranks[1], tags[rank][receive_ranks[1]], MPI_Tree_World, MPI_STATUS_IGNORE);
shuffle(part0, part1,permute,32);
printf("Sorted list in ascending order:\n");
for (i = 0; i < 64; i++)printf("%d\n", permute[i]);
}
}
MPI_Finalize();
}