1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
9 Exercise attribute routines.
10 This version checks for correct behavior of the copy and delete functions
11 on an attribute, particularly the correct behavior when the routine returns
19 int test_communicators(void);
20 void abort_msg(const char *, int);
21 int copybomb_fn(MPI_Comm, int, void *, void *, void *, int *);
22 int deletebomb_fn(MPI_Comm, int, void *, void *);
24 int main(int argc, char **argv)
27 MTest_Init(&argc, &argv);
28 errs = test_communicators();
35 * MPI 1.2 Clarification: Clarification of Error Behavior of
36 * Attribute Callback Functions
37 * Any return value other than MPI_SUCCESS is erroneous. The specific value
38 * returned to the user is undefined (other than it can't be MPI_SUCCESS).
39 * Proposals to specify particular values (e.g., user's value) failed.
41 /* Return an error as the value */
42 int copybomb_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
43 void *attribute_val_in, void *attribute_val_out, int *flag)
45 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
46 * part of attribute_val_out may leave some dirty bits
52 /* Set delete flag to 1 to allow the attribute to be deleted */
53 static int delete_flag = 0;
55 int deletebomb_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
62 void abort_msg(const char *str, int code)
64 fprintf(stderr, "%s, err = %d\n", str, code);
65 MPI_Abort(MPI_COMM_WORLD, code);
68 int test_communicators(void)
70 MPI_Comm dup_comm_world, d2;
71 int world_rank, world_size, key_1;
75 MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
76 MPI_Comm_size(MPI_COMM_WORLD, &world_size);
78 if (world_rank == 0) {
79 printf("*** Attribute copy/delete return codes ***\n");
83 MPI_Comm_dup(MPI_COMM_WORLD, &dup_comm_world);
84 MPI_Barrier(dup_comm_world);
86 MPI_Errhandler_set(dup_comm_world, MPI_ERRORS_RETURN);
89 if ((err = MPI_Comm_create_keyval(copybomb_fn, deletebomb_fn, &key_1, &value)))
90 abort_msg("Keyval_create", err);
92 err = MPI_Comm_set_attr(dup_comm_world, key_1, (void *) (MPI_Aint) world_rank);
95 printf("Error with first put\n");
98 err = MPI_Comm_set_attr(dup_comm_world, key_1, (void *) (MPI_Aint) (2 * world_rank));
99 if (err == MPI_SUCCESS) {
101 printf("delete function return code was MPI_SUCCESS in put\n");
104 /* Because the attribute delete function should fail, the attribute
105 * should *not be removed* */
106 err = MPI_Comm_delete_attr(dup_comm_world, key_1);
107 if (err == MPI_SUCCESS) {
109 printf("delete function return code was MPI_SUCCESS in delete\n");
112 err = MPI_Comm_dup(dup_comm_world, &d2);
113 if (err == MPI_SUCCESS) {
115 printf("copy function return code was MPI_SUCCESS in dup\n");
117 if (err != MPI_ERR_OTHER) {
119 MPI_Error_class(err, &lerrclass);
120 if (lerrclass != MPI_ERR_OTHER) {
122 printf("dup did not return an error code of class ERR_OTHER; ");
123 printf("err = %d, class = %d\n", err, lerrclass);
126 #ifndef USE_STRICT_MPI
127 /* Another interpretation is to leave d2 unchanged on error */
128 if (err && d2 != MPI_COMM_NULL) {
130 printf("dup did not return MPI_COMM_NULL on error\n");
135 MPI_Comm_free(&dup_comm_world);
137 MPI_Comm_free_keyval(&key_1);