File: attrerrcomm.c

package info (click to toggle)
mpich 4.3.0%2Breally4.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, trixie
  • size: 419,120 kB
  • sloc: ansic: 1,215,557; cpp: 74,755; javascript: 40,763; f90: 20,649; sh: 18,463; xml: 14,418; python: 14,397; perl: 13,772; makefile: 9,279; fortran: 8,063; java: 4,553; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (138 lines) | stat: -rw-r--r-- 3,952 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/*

  Exercise attribute routines.
  This version checks for correct behavior of the copy and delete functions
  on an attribute, particularly the correct behavior when the routine returns
  failure.

 */
#include <stdio.h>
#include "mpi.h"
#include "mpitest.h"

int test_communicators(void);
void abort_msg(const char *, int);
int copybomb_fn(MPI_Comm, int, void *, void *, void *, int *);
int deletebomb_fn(MPI_Comm, int, void *, void *);

int main(int argc, char **argv)
{
    int errs;
    MTest_Init(&argc, &argv);
    errs = test_communicators();
    MTest_Finalize(errs);
    return MTestReturnValue(errs);
}

/*
 * MPI 1.2 Clarification: Clarification of Error Behavior of
 *                        Attribute Callback Functions
 * Any return value other than MPI_SUCCESS is erroneous.  The specific value
 * returned to the user is undefined (other than it can't be MPI_SUCCESS).
 * Proposals to specify particular values (e.g., user's value) failed.
 */
/* Return an error as the value */
int copybomb_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
                void *attribute_val_in, void *attribute_val_out, int *flag)
{
    /* Note that if (sizeof(int) < sizeof(void *), just setting the int
     * part of attribute_val_out may leave some dirty bits
     */
    *flag = 1;
    return MPI_ERR_OTHER;
}

/* Set delete flag to 1 to allow the attribute to be deleted */
static int delete_flag = 0;

int deletebomb_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
{
    if (delete_flag)
        return MPI_SUCCESS;
    return MPI_ERR_OTHER;
}

void abort_msg(const char *str, int code)
{
    fprintf(stderr, "%s, err = %d\n", str, code);
    MPI_Abort(MPI_COMM_WORLD, code);
}

int test_communicators(void)
{
    MPI_Comm dup_comm_world, d2;
    int world_rank, world_size, key_1;
    int err, errs = 0;
    MPI_Aint value;

    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
#ifdef DEBUG
    if (world_rank == 0) {
        printf("*** Attribute copy/delete return codes ***\n");
    }
#endif

    MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
    MPI_Barrier(dup_comm_world);

    MPI_Comm_set_errhandler(dup_comm_world, MPI_ERRORS_RETURN);

    value = -11;
    if ((err = MPI_Comm_create_keyval(copybomb_fn, deletebomb_fn, &key_1, &value)))
        abort_msg("Keyval_create", err);

    err = MPI_Comm_set_attr(dup_comm_world, key_1, (void *) (MPI_Aint) world_rank);
    if (err) {
        errs++;
        printf("Error with first put\n");
    }

    err = MPI_Comm_set_attr(dup_comm_world, key_1, (void *) (MPI_Aint) (2 * world_rank));
    if (err == MPI_SUCCESS) {
        errs++;
        printf("delete function return code was MPI_SUCCESS in put\n");
    }

    /* Because the attribute delete function should fail, the attribute
     * should *not be removed* */
    err = MPI_Comm_delete_attr(dup_comm_world, key_1);
    if (err == MPI_SUCCESS) {
        errs++;
        printf("delete function return code was MPI_SUCCESS in delete\n");
    }

    err = MPI_Comm_dup(dup_comm_world, &d2);
    if (err == MPI_SUCCESS) {
        errs++;
        printf("copy function return code was MPI_SUCCESS in dup\n");
    }
    if (err != MPI_ERR_OTHER) {
        int lerrclass;
        MPI_Error_class(err, &lerrclass);
        if (lerrclass != MPI_ERR_OTHER) {
            errs++;
            printf("dup did not return an error code of class ERR_OTHER; ");
            printf("err = %d, class = %d\n", err, lerrclass);
        }
    }
#ifndef USE_STRICT_MPI
    /* Another interpretation is to leave d2 unchanged on error */
    if (err && d2 != MPI_COMM_NULL) {
        errs++;
        printf("dup did not return MPI_COMM_NULL on error\n");
    }
#endif

    delete_flag = 1;
    MPI_Comm_free(&dup_comm_world);

    MPI_Comm_free_keyval(&key_1);

    return errs;
}