* so far -- for use in parallel tree search.
*
* See Chap 14, pp. 328 & ff, in PPMPI for a discussion of parallel tree
* search.
*/
#include
#include "mpi.h"
#include "cio.h"
#include "node_stack.h"
#include "solution.h"
static int* best_solution;
static int* temp_solution;
static int* solution1;
/* first entry = cost, remaining entries, sibling */
/* ranks on path from root to solution node */
/* Thus solution_size = 1 + max_depth + 1 */
static int* solution2;
static int solution_size;
extern int max_depth;
/*********************************************************************/
/* Check queue for new solutions. Return best solution found */
COST_T Best_solution(
MPI_Comm comm /* in */) {
MPI_Status probe_status;
MPI_Status recv_status;
int done = FALSE;
int message_pending;
int* temp;
while (!done) {
MPI_Iprobe(MPI_ANY_SOURCE, SOLUTION_TAG, comm,
&message_pending, &probe_status);
if (message_pending) {
MPI_Recv(temp_solution, solution_size, MPI_INT,
probe_status.MPI_SOURCE, SOLUTION_TAG, comm,
&recv_status);
if (*temp_solution < *best_solution) {
temp = temp_solution;
temp_solution = best_solution;
best_solution = temp;
}
} else {
done = TRUE;
}
} /* while */
return Local_best_solution();
} /* Best_solution */
/*********************************************************************/
COST_T Local_best_solution(void) {
return *best_solution;
} /* Local_best_solution */
/********************************************************************/
void Local_solution_update(
COST_T cost /* in */,
NODE_T node /* in */) {
int i;
int* bs_ptr;
int* a_ptr;
*best_solution = cost;
for (i = 0, bs_ptr = best_solution+1, a_ptr = Ancestors(node);
i < max_depth; i++, bs_ptr++, a_ptr++)
*bs_ptr = *a_ptr;
*bs_ptr = Sibling_rank(node);
} /* Local_solution_update */
/********************************************************************/
/* Assumes plenty of system buffering. So beware! */
void Bcast_solution(MPI_Comm comm){
int my_rank;
int p;
int q;
MPI_Comm_rank(comm, &my_rank);
MPI_Comm_size(comm, &p);
for (q = 0; q < my_rank; q++)
MPI_Send(best_solution, solution_size, MPI_INT, q,
SOLUTION_TAG, comm);
for (q = my_rank+1; q < p; q++)
MPI_Send(best_solution, solution_size, MPI_INT, q,
SOLUTION_TAG, comm);
} /* Bcast_solution */
/*********************************************************************/
/* Return 0 if OK, -1 otherwise */
int Initialize_soln(
int max_depth /* in */) {
int i;
solution_size = max_depth+2;
solution1 = (int*) malloc(solution_size*sizeof(int));
solution2 = (int*) malloc(solution_size*sizeof(int));
if ((solution1 == (int*) NULL) || (solution2 == (int*) NULL))
return -1;
best_solution = solution1;
temp_solution = solution2;
best_solution[0] = INFINITY;
best_solution[1] = 0; /* root is on best path */
for (i = 1; i < solution_size; i++)
best_solution[i] = -1;
return 0;
} /* Initialize_soln */
/*********************************************************************/
void Free_soln(void) {
free(best_solution);
free(temp_solution);
} /* Free_soln */
/*********************************************************************/
/* Assumes each process has access to stdout */
void Print_local_soln(
MPI_Comm comm /* in */) {
int i;
int my_rank;
MPI_Comm_rank(comm, &my_rank);
printf("*************************************************************\n");
printf("Process %d > Minimum cost = %d\n", my_rank,
Local_best_solution());
printf("Min cost path = ");
for (i = 1; i < solution_size; i++)
printf("%d ", best_solution[i]);
printf("\n");
} /* Print_local_soln */
/*********************************************************************/
void Print_solution(
MPI_Comm io_comm /* in */) {
int io_rank;
int my_rank;
int i;
MPI_Comm_rank(io_comm, &my_rank);
Get_io_rank(io_comm, &io_rank);
if (my_rank == io_rank) {
printf("Minimum cost = %d\n", Local_best_solution());
printf("Path to minimum cost =\n");
printf(" ");
for (i = 1; i < solution_size; i++)
printf("%d ", best_solution[i]);
printf("\n");
}
} /* Print_soln */
/*********************************************************************/
/* Find owner of global best solution and broadcast */
void Update_solution(MPI_Comm comm){
UPDATE_STRUCT_T local_data;
UPDATE_STRUCT_T global_data;
local_data.soln = Local_best_solution();
MPI_Comm_rank(comm, &(local_data.rank));
MPI_Allreduce(&local_data, &global_data, 1, update_mpi_t,
MPI_MINLOC, comm);
MPI_Bcast(best_solution, solution_size, MPI_INT,
global_data.rank, comm);
} /* Update_solution */
Hiç yorum yok:
Yorum Gönder