+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2015 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+/*
+ * Test MPI_Dims_create and the choice of decompositions. These should match
+ * the definition in MPI, which wants a "balanced" decomposition. There
+ * is some ambiguity in the definition, so this test attempts to deal with
+ * that.
+ */
+#define MAX_DIMS 20
+
+typedef struct {
+ int size, dim;
+ int orderedDecomp[MAX_DIMS];
+} DimsTestVal_t;
+
+/* MPI 3.1, page 293, line 31, output values of Dims_create are in
+ non-increasing order */
+DimsTestVal_t tests[] = {
+#include "baddims.h"
+ };
+
+/* Forward refs */
+void zeroDims(int, int []);
+int checkDims(DimsTestVal_t *, const int []);
+int compareDims(int, const int[], const int[], int);
+
+int main(int argc, char *argv[])
+{
+ int i, k, wrank, errs = 0;
+ int dims[MAX_DIMS];
+
+ MTest_Init(0, 0);
+ MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
+
+ if (wrank == 0) {
+
+ for (k=0; tests[k].size > 0; k++) {
+ zeroDims(tests[k].dim, dims);
+ MPI_Dims_create(tests[k].size, tests[k].dim, dims);
+ if (checkDims(&tests[k], dims)) {
+ errs++;
+ MTestPrintfMsg(1, "Test %d failed with mismatched output", k);
+ if (errs < 10) {
+ fprintf(stderr, "%d in %dd: ", tests[k].size, tests[k].dim);
+ for (i=0; i<tests[k].dim-1; i++)
+ fprintf(stderr, "%d x ", dims[i]);
+ fprintf(stderr, "%d != %d", dims[tests[k].dim-1],
+ tests[k].orderedDecomp[0]);
+ for (i=1; i<tests[k].dim; i++)
+ fprintf(stderr," x %d", tests[k].orderedDecomp[i]);
+ fprintf(stderr,"\n");
+ }
+ }
+ }
+ }
+
+ MTest_Finalize(errs);
+ MPI_Finalize();
+ return MTestReturnValue(errs);
+}
+
+void zeroDims(int dim, int dims[])
+{
+ int k;
+ for (k=0; k<dim; k++) dims[k] = 0;
+}
+
+int checkDims(DimsTestVal_t *test, const int dims[])
+{
+ int k, errs=0;
+
+ for (k=0; k<test->dim; k++) {
+ if (dims[k] != test->orderedDecomp[k]) {
+ errs ++;
+ }
+ }
+ return errs;
+}
+
+int compareDims(int dim, const int d1[], const int d2[], int isweak)
+{
+ int diff = 0, k;
+ if (isweak) {
+ diff = d1[0] - d1[dim-1] - (d2[0] - d2[dim-1]);
+ if (diff < 0) diff = - diff;
+ }
+ else {
+ for (k=0; k<dim; k++) {
+ int d = d1[k] - d2[k];
+ if (d < 0) d = -d;
+ diff += d;
+ }
+ }
+ return diff;
+}
+
+