Blame test/mpi/perf/allredtrace.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2008 by University of Illinois
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * This code is intended to test the trace overhead when using an
Packit Service c5cf8c
 * MPI tracing package.  To perform the test, follow these steps:
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * 1) Run with the versbose mode selected to determine the delay argument
Packit Service c5cf8c
 *    to use in subsequent tests:
Packit Service c5cf8c
 *      mpiexec -n 4096 allredtrace -v
Packit Service c5cf8c
 *    Assume that the computed delay count is 6237; that value is used in
Packit Service c5cf8c
 *    the following.
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * 2) Run with an explicit delay count, without tracing enabled:
Packit Service c5cf8c
 *      mpiexec -n 4096 allredtrace -delaycount 6237
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * 3) Build allredtrace with tracing enabled, then run:
Packit Service c5cf8c
 *      mpiexec -n 4096 allredtrace -delaycount 6237
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * Compare the total times.  The tracing version should take slightly
Packit Service c5cf8c
 * longer but no more than, for example, 15%.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
Packit Service c5cf8c
static int verbose = 0;
Packit Service c5cf8c
static int lCount = 0;
Packit Service c5cf8c
void Delay(int);
Packit Service c5cf8c
void SetupDelay(double);
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    double usecPerCall = 100;
Packit Service c5cf8c
    double t, t1, tsum;
Packit Service c5cf8c
    int i, nLoop = 100;
Packit Service c5cf8c
    int rank;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Init(&argc, &argv);
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
Packit Service c5cf8c
    /* Process arguments.  We allow the delay count to be set from the
Packit Service c5cf8c
     * command line to ensure reproducibility */
Packit Service c5cf8c
    for (i = 1; i < argc; i++) {
Packit Service c5cf8c
        if (strcmp(argv[i], "-delaycount") == 0) {
Packit Service c5cf8c
            i++;
Packit Service c5cf8c
            lCount = atoi(argv[i]);
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-v") == 0) {
Packit Service c5cf8c
            verbose = 1;
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            fprintf(stderr, "Unrecognized argument %s\n", argv[i]);
Packit Service c5cf8c
            exit(1);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (lCount == 0) {
Packit Service c5cf8c
        SetupDelay(usecPerCall);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
    t = MPI_Wtime();
Packit Service c5cf8c
    for (i = 0; i < nLoop; i++) {
Packit Service c5cf8c
        MPI_Allreduce(&t1, &tsum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
Packit Service c5cf8c
        Delay(lCount);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    t = MPI_Wtime() - t;
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        printf("For delay count %d, time is %e\n", lCount, t);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Finalize();
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void SetupDelay(double usec)
Packit Service c5cf8c
{
Packit Service c5cf8c
    double t, tick;
Packit Service c5cf8c
    double sec = 1.0e-6 * usec;
Packit Service c5cf8c
    int nLoop, i, direction;
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
    /* Compute the number of times to run the tests to get an accurate
Packit Service c5cf8c
     * number given the timer resolution. */
Packit Service c5cf8c
    nLoop = 1;
Packit Service c5cf8c
    tick = 100 * MPI_Wtick();
Packit Service c5cf8c
    do {
Packit Service c5cf8c
        nLoop = 2 * nLoop;
Packit Service c5cf8c
        t = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < nLoop; i++) {
Packit Service c5cf8c
            MPI_Wtime();
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t = MPI_Wtime() - t;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    while (t < tick && nLoop < 100000);
Packit Service c5cf8c
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf("nLoop = %d\n", nLoop);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Start with an estimated count */
Packit Service c5cf8c
    lCount = 128;
Packit Service c5cf8c
    direction = 0;
Packit Service c5cf8c
    while (1) {
Packit Service c5cf8c
        t = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < nLoop; i++) {
Packit Service c5cf8c
            Delay(lCount);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t = MPI_Wtime() - t;
Packit Service c5cf8c
        t = t / nLoop;
Packit Service c5cf8c
        if (verbose)
Packit Service c5cf8c
            printf("lCount = %d, time = %e\n", lCount, t);
Packit Service c5cf8c
        if (t > 10 * tick)
Packit Service c5cf8c
            nLoop = nLoop / 2;
Packit Service c5cf8c
Packit Service c5cf8c
        /* Compare measured delay */
Packit Service c5cf8c
        if (t > 2 * sec) {
Packit Service c5cf8c
            lCount = lCount / 2;
Packit Service c5cf8c
            if (direction == 1)
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            direction = -1;
Packit Service c5cf8c
        } else if (t < sec / 2) {
Packit Service c5cf8c
            lCount = lCount * 2;
Packit Service c5cf8c
            if (direction == -1)
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            direction = 1;
Packit Service c5cf8c
        } else if (t < sec) {
Packit Service c5cf8c
            /* sec/2 <= t < sec , so estimate the lCount to hit sec */
Packit Service c5cf8c
            lCount = (sec / t) * lCount;
Packit Service c5cf8c
        } else
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf("lCount = %d, t = %e\n", lCount, t);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Should coordinate with the other processes - take the max? */
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
volatile double delayCounter = 0;
Packit Service c5cf8c
void Delay(int count)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
Packit Service c5cf8c
    delayCounter = 0.0;
Packit Service c5cf8c
    for (i = 0; i < count; i++) {
Packit Service c5cf8c
        delayCounter += 2.73;
Packit Service c5cf8c
    }
Packit Service c5cf8c
}