Blame test/mpi/attr/attrerr.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *
Packit 0848f5
 *  (C) 2003 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
/*
Packit 0848f5
Packit 0848f5
  Exercise attribute routines.
Packit 0848f5
  This version checks for correct behavior of the copy and delete functions
Packit 0848f5
  on an attribute, particularly the correct behavior when the routine returns
Packit 0848f5
  failure.
Packit 0848f5
Packit 0848f5
 */
Packit 0848f5
#include <stdio.h>
Packit 0848f5
#include "mpi.h"
Packit 0848f5
#include "mpitest.h"
Packit 0848f5
Packit 0848f5
int test_communicators(void);
Packit 0848f5
void abort_msg(const char *, int);
Packit 0848f5
int copybomb_fn(MPI_Comm, int, void *, void *, void *, int *);
Packit 0848f5
int deletebomb_fn(MPI_Comm, int, void *, void *);
Packit 0848f5
Packit 0848f5
int main(int argc, char **argv)
Packit 0848f5
{
Packit 0848f5
    int errs;
Packit 0848f5
    MTest_Init(&argc, &argv);
Packit 0848f5
    errs = test_communicators();
Packit 0848f5
    MTest_Finalize(errs);
Packit 0848f5
    MPI_Finalize();
Packit 0848f5
    return 0;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
/*
Packit 0848f5
 * MPI 1.2 Clarification: Clarification of Error Behavior of
Packit 0848f5
 *                        Attribute Callback Functions
Packit 0848f5
 * Any return value other than MPI_SUCCESS is erroneous.  The specific value
Packit 0848f5
 * returned to the user is undefined (other than it can't be MPI_SUCCESS).
Packit 0848f5
 * Proposals to specify particular values (e.g., user's value) failed.
Packit 0848f5
 */
Packit 0848f5
/* Return an error as the value */
Packit 0848f5
int copybomb_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
Packit 0848f5
                void *attribute_val_in, void *attribute_val_out, int *flag)
Packit 0848f5
{
Packit 0848f5
    /* Note that if (sizeof(int) < sizeof(void *), just setting the int
Packit 0848f5
     * part of attribute_val_out may leave some dirty bits
Packit 0848f5
     */
Packit 0848f5
    *flag = 1;
Packit 0848f5
    return MPI_ERR_OTHER;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
/* Set delete flag to 1 to allow the attribute to be deleted */
Packit 0848f5
static int delete_flag = 0;
Packit 0848f5
Packit 0848f5
int deletebomb_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
Packit 0848f5
{
Packit 0848f5
    if (delete_flag)
Packit 0848f5
        return MPI_SUCCESS;
Packit 0848f5
    return MPI_ERR_OTHER;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
void abort_msg(const char *str, int code)
Packit 0848f5
{
Packit 0848f5
    fprintf(stderr, "%s, err = %d\n", str, code);
Packit 0848f5
    MPI_Abort(MPI_COMM_WORLD, code);
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
int test_communicators(void)
Packit 0848f5
{
Packit 0848f5
    MPI_Comm dup_comm_world, d2;
Packit 0848f5
    int world_rank, world_size, key_1;
Packit 0848f5
    int err, errs = 0;
Packit 0848f5
    MPI_Aint value;
Packit 0848f5
Packit 0848f5
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
Packit 0848f5
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
Packit 0848f5
#ifdef DEBUG
Packit 0848f5
    if (world_rank == 0) {
Packit 0848f5
        printf("*** Attribute copy/delete return codes ***\n");
Packit 0848f5
    }
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
    MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
Packit 0848f5
    MPI_Barrier(dup_comm_world);
Packit 0848f5
Packit 0848f5
    MPI_Errhandler_set(dup_comm_world, MPI_ERRORS_RETURN);
Packit 0848f5
Packit 0848f5
    value = -11;
Packit 0848f5
    if ((err = MPI_Keyval_create(copybomb_fn, deletebomb_fn, &key_1, &value)))
Packit 0848f5
        abort_msg("Keyval_create", err);
Packit 0848f5
Packit 0848f5
    err = MPI_Attr_put(dup_comm_world, key_1, (void *) (MPI_Aint) world_rank);
Packit 0848f5
    if (err) {
Packit 0848f5
        errs++;
Packit 0848f5
        printf("Error with first put\n");
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    err = MPI_Attr_put(dup_comm_world, key_1, (void *) (MPI_Aint) (2 * world_rank));
Packit 0848f5
    if (err == MPI_SUCCESS) {
Packit 0848f5
        errs++;
Packit 0848f5
        printf("delete function return code was MPI_SUCCESS in put\n");
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* Because the attribute delete function should fail, the attribute
Packit 0848f5
     * should *not be removed* */
Packit 0848f5
    err = MPI_Attr_delete(dup_comm_world, key_1);
Packit 0848f5
    if (err == MPI_SUCCESS) {
Packit 0848f5
        errs++;
Packit 0848f5
        printf("delete function return code was MPI_SUCCESS in delete\n");
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    err = MPI_Comm_dup(dup_comm_world, &d2;;
Packit 0848f5
    if (err == MPI_SUCCESS) {
Packit 0848f5
        errs++;
Packit 0848f5
        printf("copy function return code was MPI_SUCCESS in dup\n");
Packit 0848f5
    }
Packit 0848f5
#ifndef USE_STRICT_MPI
Packit 0848f5
    /* Another interpretation is to leave d2 unchanged on error */
Packit 0848f5
    if (err && d2 != MPI_COMM_NULL) {
Packit 0848f5
        errs++;
Packit 0848f5
        printf("dup did not return MPI_COMM_NULL on error\n");
Packit 0848f5
    }
Packit 0848f5
#endif
Packit 0848f5
Packit 0848f5
    delete_flag = 1;
Packit 0848f5
    MPI_Comm_free(&dup_comm_world);
Packit 0848f5
    MPI_Keyval_free(&key_1);
Packit 0848f5
Packit 0848f5
    return errs;
Packit 0848f5
}