Blame test/mpi/attr/attrerr.c

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