|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2003 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_SYS_TIME_H
|
|
Packit Service |
c5cf8c |
#include <sys/time.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#include <time.h>
|
|
Packit Service |
c5cf8c |
#include <math.h>
|
|
Packit Service |
c5cf8c |
#include <assert.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: What is this test supposed to accomplish? */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define START_BUF (1)
|
|
Packit Service |
c5cf8c |
#define LARGE_BUF (256 * 1024)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: MAX_BUF is too large */
|
|
Packit Service |
c5cf8c |
#define MAX_BUF (128 * 1024 * 1024)
|
|
Packit Service |
c5cf8c |
#define LOOPS 10
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
char *sbuf, *rbuf;
|
|
Packit Service |
c5cf8c |
int *recvcounts, *displs;
|
|
Packit Service |
c5cf8c |
int errs = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* #define dprintf printf */
|
|
Packit Service |
c5cf8c |
#define dprintf(...)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
typedef enum {
|
|
Packit Service |
c5cf8c |
REGULAR,
|
|
Packit Service |
c5cf8c |
BCAST,
|
|
Packit Service |
c5cf8c |
SPIKE,
|
|
Packit Service |
c5cf8c |
HALF_FULL,
|
|
Packit Service |
c5cf8c |
LINEAR_DECREASE,
|
|
Packit Service |
c5cf8c |
BELL_CURVE
|
|
Packit Service |
c5cf8c |
} test_t;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void comm_tests(MPI_Comm comm);
|
|
Packit Service |
c5cf8c |
double run_test(long long msg_size, MPI_Comm comm, test_t test_type, double *max_time);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char **argv)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int comm_size, comm_rank;
|
|
Packit Service |
c5cf8c |
MPI_Comm comm;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (comm_size < 3) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "At least 3 processes required\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (LARGE_BUF * comm_size > MAX_BUF)
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
sbuf = (void *) calloc(MAX_BUF, 1);
|
|
Packit Service |
c5cf8c |
rbuf = (void *) calloc(MAX_BUF, 1);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
srand(time(NULL));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
recvcounts = (void *) malloc(comm_size * sizeof(int));
|
|
Packit Service |
c5cf8c |
displs = (void *) malloc(comm_size * sizeof(int));
|
|
Packit Service |
c5cf8c |
if (!recvcounts || !displs || !sbuf || !rbuf) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Unable to allocate memory:\n");
|
|
Packit Service |
c5cf8c |
if (!sbuf)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\tsbuf of %d bytes\n", MAX_BUF);
|
|
Packit Service |
c5cf8c |
if (!rbuf)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\trbuf of %d bytes\n", MAX_BUF);
|
|
Packit Service |
c5cf8c |
if (!recvcounts)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\trecvcounts of %zd bytes\n", comm_size * sizeof(int));
|
|
Packit Service |
c5cf8c |
if (!displs)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\tdispls of %zd bytes\n", comm_size * sizeof(int));
|
|
Packit Service |
c5cf8c |
fflush(stderr);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("Message Range: (%d, %d); System size: %d\n", START_BUF, LARGE_BUF, comm_size);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* COMM_WORLD tests */
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("\n\n==========================================================\n");
|
|
Packit Service |
c5cf8c |
dprintf(" MPI_COMM_WORLD\n");
|
|
Packit Service |
c5cf8c |
dprintf("==========================================================\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
comm_tests(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* non-COMM_WORLD tests */
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("\n\n==========================================================\n");
|
|
Packit Service |
c5cf8c |
dprintf(" non-COMM_WORLD\n");
|
|
Packit Service |
c5cf8c |
dprintf("==========================================================\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Comm_split(MPI_COMM_WORLD, (comm_rank == comm_size - 1) ? 0 : 1, 0, &comm);
|
|
Packit Service |
c5cf8c |
if (comm_rank < comm_size - 1)
|
|
Packit Service |
c5cf8c |
comm_tests(comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Randomized communicator tests */
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("\n\n==========================================================\n");
|
|
Packit Service |
c5cf8c |
dprintf(" Randomized Communicator\n");
|
|
Packit Service |
c5cf8c |
dprintf("==========================================================\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Comm_split(MPI_COMM_WORLD, 0, rand(), &comm);
|
|
Packit Service |
c5cf8c |
comm_tests(comm);
|
|
Packit Service |
c5cf8c |
MPI_Comm_free(&comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
free(sbuf);
|
|
Packit Service |
c5cf8c |
free(rbuf);
|
|
Packit Service |
c5cf8c |
free(recvcounts);
|
|
Packit Service |
c5cf8c |
free(displs);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
MTest_Finalize(errs);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void comm_tests(MPI_Comm comm)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int comm_size, comm_rank;
|
|
Packit Service |
c5cf8c |
double rtime, max_time;
|
|
Packit Service |
c5cf8c |
long long msg_size;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(comm, &comm_size);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(comm, &comm_rank);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (msg_size = START_BUF; msg_size <= LARGE_BUF; msg_size *= 2) {
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("\n====> MSG_SIZE: %d\n", (int) msg_size);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, REGULAR, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("REGULAR:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, BCAST, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("BCAST:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, SPIKE, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("SPIKE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, HALF_FULL, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("HALF_FULL:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, LINEAR_DECREASE, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("LINEAR_DECREASE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rtime = run_test(msg_size, comm, BELL_CURVE, &max_time);
|
|
Packit Service |
c5cf8c |
if (!comm_rank) {
|
|
Packit Service |
c5cf8c |
dprintf("BELL_CURVE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
|
|
Packit Service |
c5cf8c |
fflush(stdout);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
double run_test(long long msg_size, MPI_Comm comm, test_t test_type, double *max_time)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, j;
|
|
Packit Service |
c5cf8c |
int comm_size, comm_rank;
|
|
Packit Service |
c5cf8c |
double start, end;
|
|
Packit Service |
c5cf8c |
double total_time, avg_time;
|
|
Packit Service |
c5cf8c |
MPI_Aint tmp;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(comm, &comm_size);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(comm, &comm_rank);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
displs[0] = 0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < comm_size; i++) {
|
|
Packit Service |
c5cf8c |
if (test_type == REGULAR)
|
|
Packit Service |
c5cf8c |
recvcounts[i] = msg_size;
|
|
Packit Service |
c5cf8c |
else if (test_type == BCAST)
|
|
Packit Service |
c5cf8c |
recvcounts[i] = (!i) ? msg_size : 0;
|
|
Packit Service |
c5cf8c |
else if (test_type == SPIKE)
|
|
Packit Service |
c5cf8c |
recvcounts[i] = (!i) ? (msg_size / 2) : (msg_size / (2 * (comm_size - 1)));
|
|
Packit Service |
c5cf8c |
else if (test_type == HALF_FULL)
|
|
Packit Service |
c5cf8c |
recvcounts[i] = (i < (comm_size / 2)) ? (2 * msg_size) : 0;
|
|
Packit Service |
c5cf8c |
else if (test_type == LINEAR_DECREASE) {
|
|
Packit Service |
c5cf8c |
tmp = 2 * msg_size * (comm_size - 1 - i) / (comm_size - 1);
|
|
Packit Service |
c5cf8c |
if (tmp != (int) tmp) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Integer overflow in variable tmp\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
recvcounts[i] = (int) tmp;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* If the maximum message size is too large, don't run */
|
|
Packit Service |
c5cf8c |
if (tmp > MAX_BUF)
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
} else if (test_type == BELL_CURVE) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < i; j++) {
|
|
Packit Service |
c5cf8c |
if (i - 1 + j >= comm_size)
|
|
Packit Service |
c5cf8c |
continue;
|
|
Packit Service |
c5cf8c |
tmp = msg_size * comm_size / (log(comm_size) * i);
|
|
Packit Service |
c5cf8c |
recvcounts[i - 1 + j] = (int) tmp;
|
|
Packit Service |
c5cf8c |
displs[i - 1 + j] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* If the maximum message size is too large, don't run */
|
|
Packit Service |
c5cf8c |
if (tmp > MAX_BUF)
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (i < comm_size - 1)
|
|
Packit Service |
c5cf8c |
displs[i + 1] = displs[i] + recvcounts[i];
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Test that:
|
|
Packit Service |
c5cf8c |
* 1: sbuf is large enough
|
|
Packit Service |
c5cf8c |
* 2: rbuf is large enough
|
|
Packit Service |
c5cf8c |
* 3: There were no failures (e.g., tmp nowhere > rbuf size)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
MPI_Barrier(comm);
|
|
Packit Service |
c5cf8c |
start = MPI_Wtime();
|
|
Packit Service |
c5cf8c |
for (i = 0; i < LOOPS; i++) {
|
|
Packit Service |
c5cf8c |
MPI_Allgatherv(sbuf, recvcounts[comm_rank], MPI_CHAR,
|
|
Packit Service |
c5cf8c |
rbuf, recvcounts, displs, MPI_CHAR, comm);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
end = MPI_Wtime();
|
|
Packit Service |
c5cf8c |
MPI_Barrier(comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Convert to microseconds (why?) */
|
|
Packit Service |
c5cf8c |
total_time = 1.0e6 * (end - start);
|
|
Packit Service |
c5cf8c |
MPI_Reduce(&total_time, &avg_time, 1, MPI_DOUBLE, MPI_SUM, 0, comm);
|
|
Packit Service |
c5cf8c |
MPI_Reduce(&total_time, max_time, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return (avg_time / (LOOPS * comm_size));
|
|
Packit Service |
c5cf8c |
}
|