Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Free dynamically allocated memory.
[simgrid.git] / teshsuite / smpi / mpich3-test / perf / dtpack.c
index a31a55d..029c2a4 100644 (file)
@@ -4,13 +4,13 @@
  *      See COPYRIGHT in top-level directory.
  */
 /*
- * This code may be used to test the performance of some of the 
+ * This code may be used to test the performance of some of the
  * noncontiguous datatype operations, including vector and indexed
- * pack and unpack operations.  To simplify the use of this code for 
+ * pack and unpack operations.  To simplify the use of this code for
  * tuning an MPI implementation, it uses no communication, just the
  * MPI_Pack and MPI_Unpack routines.  In addition, the individual tests are
  * in separate routines, making it easier to compare the compiler-generated
- * code for the user (manual) pack/unpack with the code used by 
+ * code for the user (manual) pack/unpack with the code used by
  * the MPI implementation.  Further, to be fair to the MPI implementation,
  * the routines are passed the source and destination buffers; this ensures
  * that the compiler can't optimize for statically allocated buffers.
@@ -25,7 +25,7 @@
 
 static int verbose = 0;
 
-#define N_REPS 1000
+#define N_REPS 50
 #define THRESHOLD 0.10
 #define VARIANCE_THRESHOLD ((THRESHOLD * THRESHOLD) / 2)
 #define NTRIALS 10
@@ -33,441 +33,456 @@ static int verbose = 0;
 double mean(double *list, int count);
 double mean(double *list, int count)
 {
-       double retval;
-       int i;
+    double retval;
+    int i;
 
-       retval = 0;
-       for (i = 0; i < count; i++)
-               retval += list[i];
-       retval /= count;
+    retval = 0;
+    for (i = 0; i < count; i++)
+        retval += list[i];
+    retval /= count;
 
-       return retval;
+    return retval;
 }
 
 double noise(double *list, int count);
 double noise(double *list, int count)
 {
-       double *margin, retval;
-       int i;
+    double *margin, retval;
+    int i;
 
-       if (!(margin = malloc(count * sizeof(double)))) {
-               printf("Unable to allocate memory\n");
-               return -1;
-       }
+    if (!(margin = malloc(count * sizeof(double)))) {
+        printf("Unable to allocate memory\n");
+        return -1;
+    }
 
-       for (i = 0; i < count; i++)
-               margin[i] = list[i] / mean(list, count);
+    for (i = 0; i < count; i++)
+        margin[i] = list[i] / mean(list, count);
 
-       retval = 0;
-       for (i = 0; i < count; i++) {
-               retval += ((margin[i] - 1) * (margin[i] - 1));
-       }
-       retval /= count;
-       if (retval < 0) retval = -retval;
+    retval = 0;
+    for (i = 0; i < count; i++) {
+        retval += ((margin[i] - 1) * (margin[i] - 1));
+    }
+    retval /= count;
+    if (retval < 0)
+        retval = -retval;
 
-       return retval;
+    free(margin);
+    return retval;
 }
 
 /* Here are the tests */
 
 /* Test packing a vector of individual doubles */
 /* We don't use restrict in the function args because assignments between
-   restrict pointers is not valid in C and some compilers, such as the 
+   restrict pointers is not valid in C and some compilers, such as the
    IBM xlc compilers, flag that use as an error.*/
-int TestVecPackDouble( int n, int stride, 
-                      double *avgTimeUser, double *avgTimeMPI,
-                      double *dest, const double *src );
-int TestVecPackDouble( int n, int stride, 
-                      double *avgTimeUser, double *avgTimeMPI,
-                      double *dest, const double *src )
+int TestVecPackDouble(int n, int stride,
+                      double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src);
+int TestVecPackDouble(int n, int stride,
+                      double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src)
 {
-       double *restrict d_dest;
-       const double *restrict d_src;
-       register int i, j;
-       int          rep, position;
-       double       t1, t2, t[NTRIALS];
-       MPI_Datatype vectype;
-
-       /* User code */
-       if (verbose) printf("TestVecPackDouble (USER): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       i = n;
-                       d_dest = dest;
-                       d_src  = src;
-                       while (i--) {
-                               *d_dest++ = *d_src;
-                               d_src += stride;
-                       }
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-               return 0;
-       }
-       *avgTimeUser = mean(t, NTRIALS) / N_REPS;
-
-       /* MPI Vector code */
-       MPI_Type_vector( n, 1, stride, MPI_DOUBLE, &vectype );
-       MPI_Type_commit( &vectype );
-
-       if (verbose) printf("TestVecPackDouble (MPI): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       position = 0;
-                       MPI_Pack( (void *)src, 1, vectype, dest, n*sizeof(double),
-                                 &position, MPI_COMM_SELF );
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-       }
-       else {
-           *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
-       }
-
-       MPI_Type_free( &vectype );
-
-       return 0;
+    double *restrict d_dest;
+    const double *restrict d_src;
+    register int i, j;
+    int rep, position;
+    double t1, t2, t[NTRIALS];
+    MPI_Datatype vectype;
+
+    /* User code */
+    if (verbose)
+        printf("TestVecPackDouble (USER): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            i = n;
+            d_dest = dest;
+            d_src = src;
+            while (i--) {
+                *d_dest++ = *d_src;
+                d_src += stride;
+            }
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+        return 0;
+    }
+    *avgTimeUser = mean(t, NTRIALS) / N_REPS;
+
+    /* MPI Vector code */
+    MPI_Type_vector(n, 1, stride, MPI_DOUBLE, &vectype);
+    MPI_Type_commit(&vectype);
+
+    if (verbose)
+        printf("TestVecPackDouble (MPI): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            position = 0;
+            MPI_Pack((void *) src, 1, vectype, dest, n * sizeof(double), &position, MPI_COMM_SELF);
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+    }
+    else {
+        *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
+    }
+
+    MPI_Type_free(&vectype);
+
+    return 0;
 }
 
 /* Test unpacking a vector of individual doubles */
 /* See above for why restrict is not used in the function args */
-int TestVecUnPackDouble( int n, int stride, 
-                      double *avgTimeUser, double *avgTimeMPI,
-                      double *dest, const double *src );
-int TestVecUnPackDouble( int n, int stride, 
-                      double *avgTimeUser, double *avgTimeMPI,
-                      double *dest, const double *src )
+int TestVecUnPackDouble(int n, int stride,
+                        double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src);
+int TestVecUnPackDouble(int n, int stride,
+                        double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src)
 {
-       double *restrict d_dest;
-       const double *restrict d_src;
-       register int i, j;
-       int          rep, position;
-       double       t1, t2, t[NTRIALS];
-       MPI_Datatype vectype;
-
-       /* User code */
-       if (verbose) printf("TestVecUnPackDouble (USER): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       i = n;
-                       d_dest = dest;
-                       d_src  = src;
-                       while (i--) {
-                               *d_dest = *d_src++;
-                               d_dest += stride;
-                       }
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-               return 0;
-       }
-       *avgTimeUser = mean(t, NTRIALS) / N_REPS;
-    
-       /* MPI Vector code */
-       MPI_Type_vector( n, 1, stride, MPI_DOUBLE, &vectype );
-       MPI_Type_commit( &vectype );
-
-       if (verbose) printf("TestVecUnPackDouble (MPI): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       position = 0;
-                       MPI_Unpack( (void *)src, n*sizeof(double), 
-                                   &position, dest, 1, vectype, MPI_COMM_SELF );
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-       }
-       else {
-           *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
-       }
-
-       MPI_Type_free( &vectype );
-
-       return 0;
+    double *restrict d_dest;
+    const double *restrict d_src;
+    register int i, j;
+    int rep, position;
+    double t1, t2, t[NTRIALS];
+    MPI_Datatype vectype;
+
+    /* User code */
+    if (verbose)
+        printf("TestVecUnPackDouble (USER): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            i = n;
+            d_dest = dest;
+            d_src = src;
+            while (i--) {
+                *d_dest = *d_src++;
+                d_dest += stride;
+            }
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+        return 0;
+    }
+    *avgTimeUser = mean(t, NTRIALS) / N_REPS;
+
+    /* MPI Vector code */
+    MPI_Type_vector(n, 1, stride, MPI_DOUBLE, &vectype);
+    MPI_Type_commit(&vectype);
+
+    if (verbose)
+        printf("TestVecUnPackDouble (MPI): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            position = 0;
+            MPI_Unpack((void *) src, n * sizeof(double),
+                       &position, dest, 1, vectype, MPI_COMM_SELF);
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+    }
+    else {
+        *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
+    }
+
+    MPI_Type_free(&vectype);
+
+    return 0;
 }
 
 /* Test packing a vector of 2-individual doubles */
 /* See above for why restrict is not used in the function args */
-int TestVecPack2Double( int n, int stride, 
-                       double *avgTimeUser, double *avgTimeMPI,
-                       double *dest, const double *src );
-int TestVecPack2Double( int n, int stride, 
-                       double *avgTimeUser, double *avgTimeMPI,
-                       double *dest, const double *src )
+int TestVecPack2Double(int n, int stride,
+                       double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src);
+int TestVecPack2Double(int n, int stride,
+                       double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src)
 {
-       double *restrict d_dest;
-       const double *restrict d_src;
-       register int i, j;
-       int          rep, position;
-       double       t1, t2, t[NTRIALS];
-       MPI_Datatype vectype;
-
-       /* User code */
-       if (verbose) printf("TestVecPack2Double (USER): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       i = n;
-                       d_dest = dest;
-                       d_src  = src;
-                       while (i--) {
-                               *d_dest++ = d_src[0];
-                               *d_dest++ = d_src[1];
-                               d_src += stride;
-                       }
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-               return 0;
-       }
-       *avgTimeUser = mean(t, NTRIALS) / N_REPS;
-    
-       /* MPI Vector code */
-       MPI_Type_vector( n, 2, stride, MPI_DOUBLE, &vectype );
-       MPI_Type_commit( &vectype );
-    
-       if (verbose) printf("TestVecPack2Double (MPI): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       position = 0;
-                       MPI_Pack( (void *)src, 1, vectype, dest, 2*n*sizeof(double),
-                                 &position, MPI_COMM_SELF );
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-       }
-       else {
-           *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
-       }
-       MPI_Type_free( &vectype );
-
-       return 0;
+    double *restrict d_dest;
+    const double *restrict d_src;
+    register int i, j;
+    int rep, position;
+    double t1, t2, t[NTRIALS];
+    MPI_Datatype vectype;
+
+    /* User code */
+    if (verbose)
+        printf("TestVecPack2Double (USER): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            i = n;
+            d_dest = dest;
+            d_src = src;
+            while (i--) {
+                *d_dest++ = d_src[0];
+                *d_dest++ = d_src[1];
+                d_src += stride;
+            }
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+        return 0;
+    }
+    *avgTimeUser = mean(t, NTRIALS) / N_REPS;
+
+    /* MPI Vector code */
+    MPI_Type_vector(n, 2, stride, MPI_DOUBLE, &vectype);
+    MPI_Type_commit(&vectype);
+
+    if (verbose)
+        printf("TestVecPack2Double (MPI): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            position = 0;
+            MPI_Pack((void *) src, 1, vectype, dest, 2 * n * sizeof(double),
+                     &position, MPI_COMM_SELF);
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+    }
+    else {
+        *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
+    }
+    MPI_Type_free(&vectype);
+
+    return 0;
 }
 
 /* This creates an indexed type that is like a vector (for simplicity
-   of construction).  There is a possibility that the MPI implementation 
+   of construction).  There is a possibility that the MPI implementation
    will recognize and simplify this (e.g., in MPI_Type_commit); if so,
-   let us know and we'll add a version that is not as regular 
+   let us know and we'll add a version that is not as regular
 */
 /* See above for why restrict is not used in the function args */
-int TestIndexPackDouble( int n, int stride, 
-                        double *avgTimeUser, double *avgTimeMPI,
-                        double *dest, const double *src );
-int TestIndexPackDouble( int n, int stride, 
-                        double *avgTimeUser, double *avgTimeMPI,
-                        double *dest, const double *src )
+int TestIndexPackDouble(int n, int stride,
+                        double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src);
+int TestIndexPackDouble(int n, int stride,
+                        double *avgTimeUser, double *avgTimeMPI, double *dest, const double *src)
 {
-       double *restrict d_dest;
-       const double *restrict d_src;
-       register int i, j;
-       int          rep, position;
-       int          *restrict displs = 0;
-       double       t1, t2, t[NTRIALS];
-       MPI_Datatype indextype;
-
-       displs = (int *)malloc( n * sizeof(int) );
-       for (i=0; i<n; i++) displs[i] = i * stride;
-
-       /* User code */
-       if (verbose) printf("TestIndexPackDouble (USER): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       i = n;
-                       d_dest = dest;
-                       d_src  = src;
-                       for (i=0; i<n; i++) {
-                               *d_dest++ = d_src[displs[i]];
-                       }
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-               return 0;
-       }
-       *avgTimeUser = mean(t, NTRIALS) / N_REPS;
-    
-       /* MPI Index code */
-       MPI_Type_create_indexed_block( n, 1, displs, MPI_DOUBLE, &indextype );
-       MPI_Type_commit( &indextype );
-
-       free( displs );
-    
-       if (verbose) printf("TestIndexPackDouble (MPI): ");
-       for (j = 0; j < NTRIALS; j++) {
-               t1 = MPI_Wtime();
-               for (rep=0; rep<N_REPS; rep++) {
-                       position = 0;
-                       MPI_Pack( (void *)src, 1, indextype, dest, n*sizeof(double),
-                                 &position, MPI_COMM_SELF );
-               }
-               t2 = MPI_Wtime() - t1;
-               t[j] = t2;
-               if (verbose) printf("%.3f ", t[j]);
-       }
-       if (verbose) printf("[%.3f]\n", noise(t, NTRIALS));
-       /* If there is too much noise, discard the test */
-       if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
-               *avgTimeUser = 0;
-               *avgTimeMPI = 0;
-               if (verbose)
-                       printf("Too much noise; discarding measurement\n");
-       }
-       else {
-           *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
-       }
-       MPI_Type_free( &indextype );
-
-       return 0;
+    double *restrict d_dest;
+    const double *restrict d_src;
+    register int i, j;
+    int rep, position;
+    int *restrict displs = 0;
+    double t1, t2, t[NTRIALS];
+    MPI_Datatype indextype;
+
+    displs = (int *) malloc(n * sizeof(int));
+    for (i = 0; i < n; i++)
+        displs[i] = i * stride;
+
+    /* User code */
+    if (verbose)
+        printf("TestIndexPackDouble (USER): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            i = n;
+            d_dest = dest;
+            d_src = src;
+            for (i = 0; i < n; i++) {
+                *d_dest++ = d_src[displs[i]];
+            }
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+        return 0;
+    }
+    *avgTimeUser = mean(t, NTRIALS) / N_REPS;
+
+    /* MPI Index code */
+    MPI_Type_create_indexed_block(n, 1, displs, MPI_DOUBLE, &indextype);
+    MPI_Type_commit(&indextype);
+
+    free(displs);
+
+    if (verbose)
+        printf("TestIndexPackDouble (MPI): ");
+    for (j = 0; j < NTRIALS; j++) {
+        t1 = MPI_Wtime();
+        for (rep = 0; rep < N_REPS; rep++) {
+            position = 0;
+            MPI_Pack((void *) src, 1, indextype, dest, n * sizeof(double),
+                     &position, MPI_COMM_SELF);
+        }
+        t2 = MPI_Wtime() - t1;
+        t[j] = t2;
+        if (verbose)
+            printf("%.3f ", t[j]);
+    }
+    if (verbose)
+        printf("[%.3f]\n", noise(t, NTRIALS));
+    /* If there is too much noise, discard the test */
+    if (noise(t, NTRIALS) > VARIANCE_THRESHOLD) {
+        *avgTimeUser = 0;
+        *avgTimeMPI = 0;
+        if (verbose)
+            printf("Too much noise; discarding measurement\n");
+    }
+    else {
+        *avgTimeMPI = mean(t, NTRIALS) / N_REPS;
+    }
+    MPI_Type_free(&indextype);
+
+    return 0;
 }
 
-int Report( const char *name, const char *packname, 
-           double avgTimeMPI, double avgTimeUser );
-int Report( const char *name, const char *packname, 
-           double avgTimeMPI, double avgTimeUser )
+int Report(const char *name, const char *packname, double avgTimeMPI, double avgTimeUser);
+int Report(const char *name, const char *packname, double avgTimeMPI, double avgTimeUser)
 {
-       double diffTime, maxTime;
-       int errs=0;
-
-       /* Move this into a common routine */
-       diffTime = avgTimeMPI - avgTimeUser;
-       if (diffTime < 0) diffTime = - diffTime;
-       if (avgTimeMPI > avgTimeUser) maxTime = avgTimeMPI;
-       else                          maxTime = avgTimeUser;
-
-       if (verbose) {
-               printf( "%-30s:\t%g\t%g\t(%g%%)\n", name, 
-                       avgTimeMPI, avgTimeUser,
-                       100 * (diffTime / maxTime) );
-               fflush(stdout);
-       }
-       if (avgTimeMPI > avgTimeUser && (diffTime > THRESHOLD * maxTime)) {
-               errs++;
-               printf( "%s:\tMPI %s code is too slow: MPI %g\t User %g\n",
-                       name, packname, avgTimeMPI, avgTimeUser );
-       }
-
-       return errs;
+    double diffTime, maxTime;
+    int errs = 0;
+
+    /* Move this into a common routine */
+    diffTime = avgTimeMPI - avgTimeUser;
+    if (diffTime < 0)
+        diffTime = -diffTime;
+    if (avgTimeMPI > avgTimeUser)
+        maxTime = avgTimeMPI;
+    else
+        maxTime = avgTimeUser;
+
+    if (verbose) {
+        printf("%-30s:\t%g\t%g\t(%g%%)\n", name,
+               avgTimeMPI, avgTimeUser, 100 * (diffTime / maxTime));
+        fflush(stdout);
+    }
+    if (avgTimeMPI > avgTimeUser && (diffTime > THRESHOLD * maxTime)) {
+        errs++;
+        printf("%s:\tMPI %s code is too slow: MPI %g\t User %g\n",
+               name, packname, avgTimeMPI, avgTimeUser);
+    }
+
+    return errs;
 }
 
 /* Finally, here's the main program */
-int main( int argc, char *argv[] )
+int main(int argc, char *argv[])
 {
-    int n, stride, err, errs = 0;
+    int n, stride, errs = 0;
     void *dest, *src;
     double avgTimeUser, avgTimeMPI;
 
-    MPI_Init( &argc, &argv );
-    if (getenv("MPITEST_VERBOSE")) verbose = 1;
+    MPI_Init(&argc, &argv);
+    if (getenv("MPITEST_VERBOSE"))
+        verbose = 1;
 
-    n      = 30000;
+    n = 30000;
     stride = 4;
-    dest = (void *)malloc( n * sizeof(double) );
-    src  = (void *)malloc( n * ((1+stride)*sizeof(double)) );
+    dest = (void *) malloc(n * sizeof(double));
+    src = (void *) malloc(n * ((1 + stride) * sizeof(double)));
     /* Touch the source and destination arrays */
-    memset( src, 0, n * (1+stride)*sizeof(double) );
-    memset( dest, 0, n * sizeof(double) );
+    memset(src, 0, n * (1 + stride) * sizeof(double));
+    memset(dest, 0, n * sizeof(double));
 
-    err = TestVecPackDouble( n, stride, &avgTimeUser, &avgTimeMPI,
-                            dest, src );
-    errs += Report( "VecPackDouble", "Pack", avgTimeMPI, avgTimeUser );
+    TestVecPackDouble(n, stride, &avgTimeUser, &avgTimeMPI, dest, src);
+    errs += Report("VecPackDouble", "Pack", avgTimeMPI, avgTimeUser);
 
-    err = TestVecUnPackDouble( n, stride, &avgTimeUser, &avgTimeMPI,
-                              src, dest );
-    errs += Report( "VecUnPackDouble", "Unpack", avgTimeMPI, avgTimeUser );
+    TestVecUnPackDouble(n, stride, &avgTimeUser, &avgTimeMPI, src, dest);
+    errs += Report("VecUnPackDouble", "Unpack", avgTimeMPI, avgTimeUser);
 
-    err = TestIndexPackDouble( n, stride, &avgTimeUser, &avgTimeMPI,
-                            dest, src );
-    errs += Report( "VecIndexDouble", "Pack", avgTimeMPI, avgTimeUser );
+    TestIndexPackDouble(n, stride, &avgTimeUser, &avgTimeMPI, dest, src);
+    errs += Report("VecIndexDouble", "Pack", avgTimeMPI, avgTimeUser);
 
     free(dest);
     free(src);
-    
-    dest = (void *)malloc( 2*n * sizeof(double) );
-    src  = (void *)malloc( (1 + n) * ((1+stride)*sizeof(double)) );
-    memset( dest, 0, 2*n * sizeof(double) );
-    memset( src, 0, (1+n) * (1+stride)*sizeof(double) );
-    err = TestVecPack2Double( n, stride, &avgTimeUser, &avgTimeMPI,
-                             dest, src );
-    errs += Report( "VecPack2Double", "Pack", avgTimeMPI, avgTimeUser );
+
+    dest = (void *) malloc(2 * n * sizeof(double));
+    src = (void *) malloc((1 + n) * ((1 + stride) * sizeof(double)));
+    memset(dest, 0, 2 * n * sizeof(double));
+    memset(src, 0, (1 + n) * (1 + stride) * sizeof(double));
+    TestVecPack2Double(n, stride, &avgTimeUser, &avgTimeMPI, dest, src);
+    errs += Report("VecPack2Double", "Pack", avgTimeMPI, avgTimeUser);
 
     free(dest);
     free(src);
-    
+
 
 
     if (errs == 0) {
-       printf( " No Errors\n" );
+        printf(" No Errors\n");
     }
     else {
-       printf( " Found %d performance problems\n", errs );
+        printf(" Found %d performance problems\n", errs);
     }
 
     fflush(stdout);