Bu Blogda Ara

7 Şubat 2010 Pazar

Functions for use in gathering performance information on parallel tree search

/* stats.c -- Functions for use in gathering performance information on
* parallel tree search.
*
* Note: All times are local!
*
* See Chap 14, pp. 328 & ff, in PPMPI for a discussion of parallel tree
* search.
*/

#include "stats.h"
#include "mpi.h"
#include
#include "cio.h"

STATS_T stats = {0, 0, 0, 0, 0, 0.0, 0.0, 0.0};
double overhead_time;
MPI_Datatype stats_mpi_t;

/********************************************************************/
void Get_overhead() {
int i;

stats.par_dfs_time = 0.0;
for (i = 0; i < MAX_TESTS; i++) {
Start_time(par_dfs_time);
Finish_time(par_dfs_time);
}
overhead_time = stats.par_dfs_time/MAX_TESTS;
stats.par_dfs_time = 0.0;
} /* Get_overhead */


/********************************************************************/
void Build_stats_mpi_t(void) {
int i;
int block_lengths[MEMBERS];
MPI_Datatype types[MEMBERS];
MPI_Aint displacements[MEMBERS];
MPI_Aint start;
MPI_Aint address;

for (i = 0; i < MEMBERS; i++)
block_lengths[i] = 1;

for (i = 0; i < INT_MEMBERS; i++) {
types[i] = MPI_INT;
}
for (i = INT_MEMBERS; i < MEMBERS; i++) {
types[i] = MPI_DOUBLE;
}

MPI_Address(&(stats.nodes_expanded), &start);
displacements[0] = (MPI_Aint) 0;
MPI_Address(&(stats.requests_sent), &address);
displacements[1] = address - start;
MPI_Address(&(stats.rejects_sent), &address);
displacements[2] = address - start;
MPI_Address(&(stats.work_sent), &address);
displacements[3] = address - start;
MPI_Address(&(stats.rejects_recd), &address);
displacements[4] = address - start;
MPI_Address(&(stats.work_recd), &address);
displacements[5] = address - start;
MPI_Address(&(stats.par_dfs_time), &address);
displacements[6] = address - start;
MPI_Address(&(stats.svc_req_time), &address);
displacements[7] = address - start;
MPI_Address(&(stats.work_rem_time), &address);
displacements[8] = address - start;

MPI_Type_struct(MEMBERS, block_lengths, displacements, types,
&stats_mpi_t);
MPI_Type_commit(&stats_mpi_t);
} /* Build_stats_mpi_t */


/********************************************************************/
void Set_stats_to_zero(
STATS_T* stats /* out */) {
stats->nodes_expanded = 0;
stats->requests_sent = 0;
stats->rejects_sent = 0;
stats->work_sent = 0;
stats->rejects_recd = 0;
stats->work_recd = 0;
stats->par_dfs_time = 0.0;
stats->svc_req_time = 0.0;
stats->work_rem_time = 0.0;
} /* Set_stats_to_zero */


/********************************************************************/
void Update_totals(
STATS_T* totals /* in/out */,
STATS_T* new /* in */) {
totals->nodes_expanded += new->nodes_expanded ;
totals->requests_sent += new->requests_sent ;
totals->rejects_sent += new->rejects_sent ;
totals->work_sent += new->work_sent ;
totals->rejects_recd += new->rejects_recd ;
totals->work_recd += new->work_recd ;
if (totals->par_dfs_time < new->par_dfs_time)
totals->par_dfs_time = new->par_dfs_time;
if (totals->svc_req_time < new->svc_req_time)
totals->svc_req_time = new->svc_req_time;
if (totals->work_rem_time < new->work_rem_time)
totals->work_rem_time = new->work_rem_time;
} /* Update_totals */


/********************************************************************/
void Print_title(void) {
printf(" Performance Statistics\n");
printf(" (Totals are sums for counts and maxima for times)\n");
printf(" Nodes Reqs Rejs Work Rejs Work DFS Svc Wk_rm\n");
printf("Proc Exp Sent Sent Sent Recd Recd Time Time Time\n");
printf("---- ----- ---- ---- ---- ---- ---- ---- ---- -----\n");
} /* Print_title */


/********************************************************************/
void Print_ind_stats(
int rank /* in */,
STATS_T* stats /* in */) {

if (rank < 0)
printf("Totals ");
else
printf(" %2d ", rank);

printf("%3d %2d %2d %2d %2d %2d ",
stats->nodes_expanded, stats->requests_sent,
stats->rejects_sent, stats->work_sent,
stats->rejects_recd, stats->work_recd);
printf("%7.2e %7.2e %7.2e\n",
stats->par_dfs_time, stats->svc_req_time,
stats->work_rem_time);
} /* Print_ind_stats */


/********************************************************************/
void Print_stats(
MPI_Comm io_comm /* in */) {
STATS_T recd_stats;
STATS_T totals;
int p;
int io_rank;
int my_rank;
int q;
MPI_Status status;

MPI_Comm_size(io_comm, &p);
MPI_Comm_rank(io_comm, &my_rank);
Get_io_rank(io_comm, &io_rank);

Build_stats_mpi_t();
Set_stats_to_zero(&totals);

if (my_rank == io_rank) {
printf("\n");
Print_title();
for (q = 0; q < io_rank; q++) {
MPI_Recv(&recd_stats, 1, stats_mpi_t, q, 0, io_comm,
&status);
Print_ind_stats(q, &recd_stats);
Update_totals(&totals, &recd_stats);
} /* for */
Print_ind_stats(io_rank, &stats);
Update_totals(&totals, &stats);
for (q = io_rank+1; q < p; q++) {
MPI_Recv(&recd_stats, 1, stats_mpi_t, q, 0, io_comm,
&status);
Print_ind_stats(q, &recd_stats);
Update_totals(&totals, &recd_stats);
} /* for */
Print_ind_stats(-1, &totals);
} else {
MPI_Send(&stats, 1, stats_mpi_t, 0, 0, io_comm);
}
} /* Print_stats */

Hiç yorum yok:

Yorum Gönder