| 1 | #include <stdio.h>
|
|---|
| 2 | #include <stdlib.h>
|
|---|
| 3 | #include <mpi.h>
|
|---|
| 4 | /****
|
|---|
| 5 | ! This program is designed to show how to set up a new communicator.
|
|---|
| 6 | ! We set up a communicator that includes all but one of the processors,
|
|---|
| 7 | ! The last processor is not part of the new communcator, TIMS_COMM_WORLD
|
|---|
| 8 | ! We use the routine MPI_Group_rank to find the rank within the new
|
|---|
| 9 | ! connunicator. For the last processor the rank is MPI_UNDEFINED because
|
|---|
| 10 | ! it is not part of the communicator. For this processor we call get_input
|
|---|
| 11 | ! The processors in TIMS_COMM_WORLD pass a token between themselves in the
|
|---|
| 12 | ! subroutine pass_token. The remaining processor gets input, i, from the terminal
|
|---|
| 13 | ! and passes it to processor 1 of MPI_COMM_WORLD. If i > 100 the program stops
|
|---|
| 14 | *****/
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 | /* global variables */
|
|---|
| 18 | int numnodes,myid,mpi_err;
|
|---|
| 19 | #define mpi_root 0
|
|---|
| 20 | /* end of global variables */
|
|---|
| 21 |
|
|---|
| 22 | void pass_token(MPI_Comm THE_COMM_WORLD);
|
|---|
| 23 | void init_it(int *argc, char ***argv);
|
|---|
| 24 | void get_input();
|
|---|
| 25 |
|
|---|
| 26 | void init_it(int *argc, char ***argv) {
|
|---|
| 27 | mpi_err = MPI_Init(argc,argv);
|
|---|
| 28 | mpi_err = MPI_Comm_size( MPI_COMM_WORLD, &numnodes );
|
|---|
| 29 | mpi_err = MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | int main(int argc,char *argv[]){
|
|---|
| 33 | /* poe a.out -procs 3 -rmpool 1 */
|
|---|
| 34 | int *will_use;
|
|---|
| 35 | MPI_Comm TIMS_COMM_WORLD;
|
|---|
| 36 | MPI_Group new_group,old_group;
|
|---|
| 37 | int ijk,num_used,used_id;
|
|---|
| 38 | init_it(&argc,&argv);
|
|---|
| 39 | printf("hello from %d\n",myid);
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 | /* num_used is the # of processors that are part of the new communicator */
|
|---|
| 43 | /* for this case hardwire to not include 1 processor */
|
|---|
| 44 | num_used=numnodes-1;
|
|---|
| 45 | if(numnodes > num_used){
|
|---|
| 46 | /* get our old group from MPI_COMM_WORLD */
|
|---|
| 47 | mpi_err = MPI_Comm_group(MPI_COMM_WORLD,&old_group);
|
|---|
| 48 | /* create a new group from the old group */
|
|---|
| 49 | /* that will contain a subset of the processors */
|
|---|
| 50 | will_use=(int*)malloc(num_used*sizeof(int));
|
|---|
| 51 | for (ijk=0;ijk <= num_used-1;ijk++){
|
|---|
| 52 | will_use[ijk]=ijk;
|
|---|
| 53 | }
|
|---|
| 54 | mpi_err = MPI_Group_incl(old_group,num_used,will_use,&new_group);
|
|---|
| 55 | /* create the new communicator */
|
|---|
| 56 | mpi_err = MPI_Comm_create(MPI_COMM_WORLD,new_group,&TIMS_COMM_WORLD);
|
|---|
| 57 | /* test to see if I am part of new_group. */
|
|---|
| 58 | mpi_err = MPI_Group_rank(new_group,&used_id);
|
|---|
| 59 | if(used_id == MPI_UNDEFINED){
|
|---|
| 60 | /* if not part of the new group do keyboard i/o. */
|
|---|
| 61 | get_input();
|
|---|
| 62 | mpi_err = MPI_Barrier(MPI_COMM_WORLD);
|
|---|
| 63 | mpi_err = MPI_Finalize();
|
|---|
| 64 | exit(0);
|
|---|
| 65 | }
|
|---|
| 66 | }
|
|---|
| 67 | else {
|
|---|
| 68 | mpi_err = MPI_Comm_dup( MPI_COMM_WORLD, &TIMS_COMM_WORLD );
|
|---|
| 69 | }
|
|---|
| 70 | mpi_err = MPI_Comm_rank( TIMS_COMM_WORLD, &myid );
|
|---|
| 71 | mpi_err = MPI_Comm_size( TIMS_COMM_WORLD, &numnodes );
|
|---|
| 72 | pass_token(TIMS_COMM_WORLD);
|
|---|
| 73 | printf("back\n");
|
|---|
| 74 | mpi_err = MPI_Barrier(MPI_COMM_WORLD);
|
|---|
| 75 | mpi_err = MPI_Finalize();
|
|---|
| 76 | exit(0);
|
|---|
| 77 | }
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 | void get_input(){
|
|---|
| 82 | int to,my_tag,i;
|
|---|
| 83 | FILE *IN;
|
|---|
| 84 | to=0;
|
|---|
| 85 | my_tag=0;
|
|---|
| 86 | i=0;
|
|---|
| 87 | IN=fopen("ex10.in","r");
|
|---|
| 88 | while(i < 100) {
|
|---|
| 89 | printf("waiting for input:\n");
|
|---|
| 90 | fscanf(IN,"%d",&i);
|
|---|
| 91 | printf("i = %d\n",i);
|
|---|
| 92 | mpi_err = MPI_Send((void*)&i,1, MPI_INT,to,my_tag,MPI_COMM_WORLD);
|
|---|
| 93 | }
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 | void pass_token(MPI_Comm THE_COMM_WORLD) {
|
|---|
| 99 | int my_tag,j,i,to,from,ierr;
|
|---|
| 100 | MPI_Status status;
|
|---|
| 101 | int flag;
|
|---|
| 102 | my_tag=1234;
|
|---|
| 103 | j=0;
|
|---|
| 104 | flag=1;
|
|---|
| 105 | to=myid+1;
|
|---|
| 106 | if(to == numnodes)to=0;
|
|---|
| 107 | from=myid-1;
|
|---|
| 108 | if(from < 0)from=numnodes-1;
|
|---|
| 109 | i=0;
|
|---|
| 110 | while(i < 100) {
|
|---|
| 111 | if(myid == j){
|
|---|
| 112 | ierr = MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,
|
|---|
| 113 | MPI_COMM_WORLD,&flag,&status);
|
|---|
| 114 | if(flag){
|
|---|
| 115 | ierr = MPI_Recv((void*)&i,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,
|
|---|
| 116 | MPI_COMM_WORLD,&status);
|
|---|
| 117 | printf("got i %d\n",i);
|
|---|
| 118 | }
|
|---|
| 119 | ierr = MPI_Send((void*)&i,1, MPI_INT,to,my_tag,THE_COMM_WORLD);
|
|---|
| 120 | j=-1;
|
|---|
| 121 | }
|
|---|
| 122 | else {
|
|---|
| 123 | ierr = MPI_Recv((void*)&i,1,MPI_INT,from,my_tag,THE_COMM_WORLD,&status);
|
|---|
| 124 | j=myid;
|
|---|
| 125 | }
|
|---|
| 126 | }
|
|---|
| 127 | if(myid < numnodes-1)
|
|---|
| 128 | ierr = MPI_Send((void*)&i,1, MPI_INT,to,my_tag,THE_COMM_WORLD);
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|