/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * * (C) 2009 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */ #include "mpi.h" #include #include "mpitest.h" /* static char MTestDescrip[] = "Test creating and inserting attributes in \ different orders to ensure that the list management code handles all cases."; */ int checkAttrs(MPI_Comm, int, int[], int[]); int delete_fn(MPI_Comm, int, void *, void *); #define NKEYS 5 static int key[NKEYS]; /* Keys in creation order */ static int keyorder[NKEYS]; /* Index (into key) of keys in order added to comm * (key[keyorder[0]] is first set) */ static int nkeys = 0; static int ncall = 0; static int errs = 0; /* * Test that attributes on comm self are deleted in LIFO order */ int main(int argc, char *argv[]) { int attrval[10]; int wrank, i; MPI_Comm comm; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &wrank); comm = MPI_COMM_SELF; /* Create key values */ for (nkeys = 0; nkeys < NKEYS; nkeys++) { MPI_Comm_create_keyval(MPI_NULL_COPY_FN, delete_fn, &key[nkeys], (void *) 0); attrval[nkeys] = 1024 * nkeys; } /* Insert attribute in several orders. Test after put with get, * then delete, then confirm delete with get. */ MPI_Comm_set_attr(comm, key[3], &attrval[3]); keyorder[0] = 3; MPI_Comm_set_attr(comm, key[2], &attrval[2]); keyorder[1] = 2; MPI_Comm_set_attr(comm, key[0], &attrval[0]); keyorder[2] = 0; MPI_Comm_set_attr(comm, key[1], &attrval[1]); keyorder[3] = 1; MPI_Comm_set_attr(comm, key[4], &attrval[4]); keyorder[4] = 4; errs += checkAttrs(comm, NKEYS, key, attrval); for (i = 0; i < NKEYS; i++) { /* Save the key value so that we can compare it in the * delete function */ int keyval = key[i]; MPI_Comm_free_keyval(&keyval); } MPI_Finalize(); if (wrank == 0) { if (ncall != nkeys) { printf("Deleted %d keys but should have deleted %d\n", ncall, nkeys); errs++; } if (errs == 0) printf(" No Errors\n"); else printf(" Found %d errors\n", errs); } return MTestReturnValue(errs); } int checkAttrs(MPI_Comm comm, int n, int lkey[], int attrval[]) { int lerrs = 0; int i, flag, *val_p; for (i = 0; i < n; i++) { MPI_Comm_get_attr(comm, lkey[i], &val_p, &flag); if (!flag) { lerrs++; fprintf(stderr, "Attribute for key %d not set\n", i); } else if (val_p != &attrval[i]) { lerrs++; fprintf(stderr, "Atribute value for key %d not correct\n", i); } } return lerrs; } /* We *should* be deleting key[keyorder[nkeys-ncall]] */ int delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state) { if (ncall >= nkeys) { printf("delete function called too many times!\n"); errs++; } /* As of MPI 2.2, the order of deletion of attributes on * MPI_COMM_SELF is defined */ if (MPI_VERSION > 2 || (MPI_VERSION == 2 && MPI_SUBVERSION >= 2)) { if (keyval != key[keyorder[nkeys - 1 - ncall]]) { printf("Expected key # %d but found key with value %d\n", keyorder[nkeys - 1 - ncall], keyval); errs++; } } ncall++; return MPI_SUCCESS; } /* int checkNoAttrs(MPI_Comm comm, int n, int lkey[]) { int lerrs = 0; int i, flag, *val_p; for (i=0; i