client/src/unifycr.c
static int CountTasksPerNode(int rank, int numTasks)
{
    char       hostname[UNIFYCR_MAX_FILENAME],
			   localhost[UNIFYCR_MAX_FILENAME];
    int        count               = 1,
               resultsLen          = 30,
               i;

    MPI_Status status;
    int rc;

   rc = MPI_Get_processor_name(localhost, &resultsLen);
   if (rc != 0) {
	   debug("failed to get the processor's name");
   }



   if (numTasks > 0) {
        if (rank == 0) {
        	  /* a container of (rank, host) mappings*/
        	 name_rank_pair_t *host_set =\
        			   (name_rank_pair_t *)malloc(numTasks\
        					   * sizeof(name_rank_pair_t));
            /* MPI_receive all hostnames, and compare to local hostname */
        	/* ToDo: handle the case when the length of hostname is larger
        	 * than 30*/
            for (i = 1; i < numTasks; i++) {
                rc = MPI_Recv(hostname, UNIFYCR_MAX_FILENAME,\
                		MPI_CHAR, MPI_ANY_SOURCE,
                                   MPI_ANY_TAG, MPI_COMM_WORLD,\
								   &status);

                if (rc != 0) {
                	debug("cannot receive hostnames");
                	return -1;
                }
                    strcpy(host_set[i].hostname, hostname);
                    host_set[i].rank = status.MPI_SOURCE;
            }
            strcpy(host_set[0].hostname, localhost);
            host_set[0].rank = 0;

            /*sort according to the hostname*/
        	qsort(host_set, numTasks, sizeof(name_rank_pair_t),\
        			compare_name_rank_pair);

        	/* rank_cnt: records the number of processes on each node
        	 * rank_set: the list of ranks for each node
        	 * */
        	int **rank_set = (int **)malloc(numTasks * sizeof(int *));
        	int *rank_cnt = (int *)malloc(numTasks * sizeof(int));

        	int cursor = 0, set_counter = 0;
        	for (i = 1; i < numTasks; i++) {
        		if (strcmp(host_set[i].hostname,\
        				host_set[i-1].hostname) == 0) {
        			/*do nothing*/
        		} else {
        			// find a different rank, so switch to a new set
        			int j, k = 0;
        			rank_set[set_counter] = \
        					(int *)malloc((i - cursor) * sizeof(int));
    				rank_cnt[set_counter] = i - cursor;
        			for (j = cursor; j <= i - 1; j++) {

        				rank_set[set_counter][k] =	host_set[j].rank;
    					k++;
        			}

        			set_counter++;
        			cursor = i;
        		}

        	}


        	/*fill rank_cnt and rank_set entry for the last node*/
        	int j = 0;

			rank_set[set_counter] = \
					(int *)malloc((i - cursor) * sizeof(int));
    		rank_cnt[set_counter] = numTasks - cursor;
    		/*
    		printf("cursor is %d\n", cursor); fflush(stdout);
    		*/
    		for (i = cursor; i <= numTasks - 1; i++) {
    			rank_set[set_counter][j] = host_set[i].rank;
    			j++;
    		}
      		set_counter++;

    		/*broadcast the rank_cnt and rank_set information to each
    		 * rank*/
    		int root_set_no;
    		for (i = 0; i < set_counter; i++) {
    			for (j = 0; j < rank_cnt[i]; j++) {
    				if (rank_set[i][j] != 0) {
    					/*
    					printf("i is %d, j is %d\n", i, j); fflush(stdout);
    					printf("rank:%d, 1sending to %d, rank_cnt[%d] is %d\n", rank, \
    							rank_set[i][j], i, rank_cnt[i]); fflush(stdout);
    							*/
    					rc = MPI_Send(&rank_cnt[i], 1,\
    							MPI_INT, rank_set[i][j], 0, MPI_COMM_WORLD);
    					if (rc != 0) {
    	                	debug("cannot send local rank cnt");
    	                	return -1;
    					}



    					/*send the local rank set to the corresponding rank*/
    					rc = MPI_Send(rank_set[i], rank_cnt[i],\
    							MPI_INT, rank_set[i][j], 0, MPI_COMM_WORLD);
    					/*
    					printf("rank:%d, 2sending to %d, rank_cnt[%d] is %d\n", rank, \
    							rank_set[i][j], i, rank_cnt[i]); fflush(stdout);*/
    					if (rc != 0) {
    	                	debug("cannot send local rank list");
    	                	return -1;
    					}
    				} else {
    					root_set_no = i;
    				}
    			}
    		}


    		/* root process set its own local rank set and rank_cnt*/
    		local_rank_lst = (int *)malloc(rank_cnt[root_set_no] * sizeof(int));
    		for (i = 0; i < rank_cnt[root_set_no]; i++) {
    			local_rank_lst[i] = rank_set[root_set_no][i];
    		}
    		local_rank_cnt = rank_cnt[root_set_no];

    		for (i = 0; i < set_counter; i++) {
    			free(rank_set[i]);
    		}
    		free(rank_cnt);
    		free(host_set);
    		free(rank_set);

        } else {
            /* non-root process performs MPI_send to send
             * hostname to root node */
           rc = MPI_Send(localhost, UNIFYCR_MAX_FILENAME,\
        		   MPI_CHAR, 0, 0, MPI_COMM_WORLD);
           if (rc != 0) {
        	   debug("cannot send host name");
        	   return -1;
           }
           /*receive the local rank count */
           rc = MPI_Recv(&local_rank_cnt, 1, MPI_INT, 0,
                              0, MPI_COMM_WORLD, &status);
           if (rc != 0) {
        	   debug("cannot receive local rank cnt");
        	   return -1;
           }

           /* receive the the local rank list */
           local_rank_lst = (int *)malloc(local_rank_cnt * sizeof(int));
           rc = MPI_Recv(local_rank_lst, local_rank_cnt, MPI_INT, 0,
                              0, MPI_COMM_WORLD, &status);
           if (rc != 0) {
        	   free(local_rank_lst);
        	   debug("cannot receive local rank list");
        	   return -1;
           }

        }

    	qsort(local_rank_lst, local_rank_cnt, sizeof(int),\
    			compare_int);

		// scatter ranks out
    } else {
    	debug("number of tasks is smaller than 0");
    	return -1;
    }

   return 0;
}
/**
* calculate the number of ranks per node,
*
* @param numTasks: number of tasks in the application
* @return success/error code
* @return local_rank_lst: a list of local ranks
* @return local_rank_cnt: number of local ranks
*/
calculate the number of ranks per node.
calculate the number of ranks per node .
static int CountTasksPerNode(int rank, int numTasks)
{
    char       hostname[UNIFYCR_MAX_FILENAME],
			   localhost[UNIFYCR_MAX_FILENAME];
    int        count               = 1,
               resultsLen          = 30,
               i;
    MPI_Status status;
    int rc;
   rc = MPI_Get_processor_name(localhost, &resultsLen);
   if (rc != 0) {
	   debug("failed to get the processor's name");
   }
   if (numTasks > 0) {
        if (rank == 0) {
        	 name_rank_pair_t *host_set =\
        			   (name_rank_pair_t *)malloc(numTasks\
        					   * sizeof(name_rank_pair_t));
            for (i = 1; i < numTasks; i++) {
                rc = MPI_Recv(hostname, UNIFYCR_MAX_FILENAME,\
                		MPI_CHAR, MPI_ANY_SOURCE,
                                   MPI_ANY_TAG, MPI_COMM_WORLD,\
								   &status);
                if (rc != 0) {
                	debug("cannot receive hostnames");
                	return -1;
                }
                    strcpy(host_set[i].hostname, hostname);
                    host_set[i].rank = status.MPI_SOURCE;
            }
            strcpy(host_set[0].hostname, localhost);
            host_set[0].rank = 0;
        	qsort(host_set, numTasks, sizeof(name_rank_pair_t),\
        			compare_name_rank_pair);
        	int **rank_set = (int **)malloc(numTasks * sizeof(int *));
        	int *rank_cnt = (int *)malloc(numTasks * sizeof(int));
        	int cursor = 0, set_counter = 0;
        	for (i = 1; i < numTasks; i++) {
        		if (strcmp(host_set[i].hostname,\
        				host_set[i-1].hostname) == 0) {
        		} else {
        			int j, k = 0;
        			rank_set[set_counter] = \
        					(int *)malloc((i - cursor) * sizeof(int));
    				rank_cnt[set_counter] = i - cursor;
        			for (j = cursor; j <= i - 1; j++) {
        				rank_set[set_counter][k] =	host_set[j].rank;
    					k++;
        			}
        			set_counter++;
        			cursor = i;
        		}
        	}
        	int j = 0;
			rank_set[set_counter] = \
					(int *)malloc((i - cursor) * sizeof(int));
    		rank_cnt[set_counter] = numTasks - cursor;
    		for (i = cursor; i <= numTasks - 1; i++) {
    			rank_set[set_counter][j] = host_set[i].rank;
    			j++;
    		}
      		set_counter++;
    		int root_set_no;
    		for (i = 0; i < set_counter; i++) {
    			for (j = 0; j < rank_cnt[i]; j++) {
    				if (rank_set[i][j] != 0) {
    					rc = MPI_Send(&rank_cnt[i], 1,\
    							MPI_INT, rank_set[i][j], 0, MPI_COMM_WORLD);
    					if (rc != 0) {
    	                	debug("cannot send local rank cnt");
    	                	return -1;
    					}
    					rc = MPI_Send(rank_set[i], rank_cnt[i],\
    							MPI_INT, rank_set[i][j], 0, MPI_COMM_WORLD);
    					if (rc != 0) {
    	                	debug("cannot send local rank list");
    	                	return -1;
    					}
    				} else {
    					root_set_no = i;
    				}
    			}
    		}
    		local_rank_lst = (int *)malloc(rank_cnt[root_set_no] * sizeof(int));
    		for (i = 0; i < rank_cnt[root_set_no]; i++) {
    			local_rank_lst[i] = rank_set[root_set_no][i];
    		}
    		local_rank_cnt = rank_cnt[root_set_no];
    		for (i = 0; i < set_counter; i++) {
    			free(rank_set[i]);
    		}
    		free(rank_cnt);
    		free(host_set);
    		free(rank_set);
        } else {
           rc = MPI_Send(localhost, UNIFYCR_MAX_FILENAME,\
        		   MPI_CHAR, 0, 0, MPI_COMM_WORLD);
           if (rc != 0) {
        	   debug("cannot send host name");
        	   return -1;
           }
           rc = MPI_Recv(&local_rank_cnt, 1, MPI_INT, 0,
                              0, MPI_COMM_WORLD, &status);
           if (rc != 0) {
        	   debug("cannot receive local rank cnt");
        	   return -1;
           }
           local_rank_lst = (int *)malloc(local_rank_cnt * sizeof(int));
           rc = MPI_Recv(local_rank_lst, local_rank_cnt, MPI_INT, 0,
                              0, MPI_COMM_WORLD, &status);
           if (rc != 0) {
        	   free(local_rank_lst);
        	   debug("cannot receive local rank list");
        	   return -1;
           }
        }
    	qsort(local_rank_lst, local_rank_cnt, sizeof(int),\
    			compare_int);
    } else {
    	debug("number of tasks is smaller than 0");
    	return -1;
    }
   return 0;
}
static int CountTasksPerNode ( int rank , int numTasks ) { char hostname [ UNIFYCR_MAX_FILENAME ] , localhost [ UNIFYCR_MAX_FILENAME ] ; int count = 1 , resultsLen = 30 , i ; MPI_Status status ; int rc ; rc = MPI_Get_processor_name ( localhost , & resultsLen ) ; if ( rc != 0 ) { debug ( " " ) ; } if ( numTasks > 0 ) { if ( rank == 0 ) { name_rank_pair_t * host_set = ( name_rank_pair_t * ) malloc ( numTasks * sizeof ( name_rank_pair_t ) ) ; for ( i = 1 ; i < numTasks ; i ++ ) { rc = MPI_Recv ( hostname , UNIFYCR_MAX_FILENAME , MPI_CHAR , MPI_ANY_SOURCE , MPI_ANY_TAG , MPI_COMM_WORLD , & status ) ; if ( rc != 0 ) { debug ( " " ) ; return -1 ; } strcpy ( host_set [ i ] . hostname , hostname ) ; host_set [ i ] . rank = status . MPI_SOURCE ; } strcpy ( host_set [ 0 ] . hostname , localhost ) ; host_set [ 0 ] . rank = 0 ; qsort ( host_set , numTasks , sizeof ( name_rank_pair_t ) , compare_name_rank_pair ) ; int * * rank_set = ( int * * ) malloc ( numTasks * sizeof ( int * ) ) ; int * rank_cnt = ( int * ) malloc ( numTasks * sizeof ( int ) ) ; int cursor = 0 , set_counter = 0 ; for ( i = 1 ; i < numTasks ; i ++ ) { if ( strcmp ( host_set [ i ] . hostname , host_set [ i - 1 ] . hostname ) == 0 ) { } else { int j , k = 0 ; rank_set [ set_counter ] = ( int * ) malloc ( ( i - cursor ) * sizeof ( int ) ) ; rank_cnt [ set_counter ] = i - cursor ; for ( j = cursor ; j <= i - 1 ; j ++ ) { rank_set [ set_counter ] [ k ] = host_set [ j ] . rank ; k ++ ; } set_counter ++ ; cursor = i ; } } int j = 0 ; rank_set [ set_counter ] = ( int * ) malloc ( ( i - cursor ) * sizeof ( int ) ) ; rank_cnt [ set_counter ] = numTasks - cursor ; for ( i = cursor ; i <= numTasks - 1 ; i ++ ) { rank_set [ set_counter ] [ j ] = host_set [ i ] . rank ; j ++ ; } set_counter ++ ; int root_set_no ; for ( i = 0 ; i < set_counter ; i ++ ) { for ( j = 0 ; j < rank_cnt [ i ] ; j ++ ) { if ( rank_set [ i ] [ j ] != 0 ) { rc = MPI_Send ( & rank_cnt [ i ] , 1 , MPI_INT , rank_set [ i ] [ j ] , 0 , MPI_COMM_WORLD ) ; if ( rc != 0 ) { debug ( " " ) ; return -1 ; } rc = MPI_Send ( rank_set [ i ] , rank_cnt [ i ] , MPI_INT , rank_set [ i ] [ j ] , 0 , MPI_COMM_WORLD ) ; if ( rc != 0 ) { debug ( " " ) ; return -1 ; } } else { root_set_no = i ; } } } local_rank_lst = ( int * ) malloc ( rank_cnt [ root_set_no ] * sizeof ( int ) ) ; for ( i = 0 ; i < rank_cnt [ root_set_no ] ; i ++ ) { local_rank_lst [ i ] = rank_set [ root_set_no ] [ i ] ; } local_rank_cnt = rank_cnt [ root_set_no ] ; for ( i = 0 ; i < set_counter ; i ++ ) { free ( rank_set [ i ] ) ; } free ( rank_cnt ) ; free ( host_set ) ; free ( rank_set ) ; } else { rc = MPI_Send ( localhost , UNIFYCR_MAX_FILENAME , MPI_CHAR , 0 , 0 , MPI_COMM_WORLD ) ; if ( rc != 0 ) { debug ( " " ) ; return -1 ; } rc = MPI_Recv ( & local_rank_cnt , 1 , MPI_INT , 0 , 0 , MPI_COMM_WORLD , & status ) ; if ( rc != 0 ) { debug ( " " ) ; return -1 ; } local_rank_lst = ( int * ) malloc ( local_rank_cnt * sizeof ( int ) ) ; rc = MPI_Recv ( local_rank_lst , local_rank_cnt , MPI_INT , 0 , 0 , MPI_COMM_WORLD , & status ) ; if ( rc != 0 ) { free ( local_rank_lst ) ; debug ( " " ) ; return -1 ; } } qsort ( local_rank_lst , local_rank_cnt , sizeof ( int ) , compare_int ) ; } else { debug ( " " ) ; return -1 ; } return 0 ; }
calculate the number of ranks per node,
calculate the number of ranks per node
/* a container of (rank, host) mappings*/ /* MPI_receive all hostnames, and compare to local hostname */ /* ToDo: handle the case when the length of hostname is larger
        	 * than 30*/ /*sort according to the hostname*/ /* rank_cnt: records the number of processes on each node
        	 * rank_set: the list of ranks for each node
        	 * */ /*do nothing*/ // find a different rank, so switch to a new set /*fill rank_cnt and rank_set entry for the last node*/ /*
    		printf("cursor is %d\n", cursor); fflush(stdout);
    		*/ /*broadcast the rank_cnt and rank_set information to each
    		 * rank*/ /*
    					printf("i is %d, j is %d\n", i, j); fflush(stdout);
    					printf("rank:%d, 1sending to %d, rank_cnt[%d] is %d\n", rank, \
    							rank_set[i][j], i, rank_cnt[i]); fflush(stdout);
    							*/ /*send the local rank set to the corresponding rank*/ /*
    					printf("rank:%d, 2sending to %d, rank_cnt[%d] is %d\n", rank, \
    							rank_set[i][j], i, rank_cnt[i]); fflush(stdout);*/ /* root process set its own local rank set and rank_cnt*/ /* non-root process performs MPI_send to send
             * hostname to root node */ /*receive the local rank count */ /* receive the the local rank list */ // scatter ranks out