Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MPI_Abort can theorically fail. Add a call to exit() to ensure that the program...
[simgrid.git] / teshsuite / smpi / mpich3-test / attr / attrerrcomm.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2003 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 /*
8
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
12   failure.
13
14  */
15 #include <stdio.h>
16 #include "mpi.h"
17 #include "mpitest.h"
18
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 * );
23
24 int main( int argc, char **argv )
25 {
26     int errs;
27     MTest_Init( &argc, &argv );
28     errs = test_communicators();
29     MTest_Finalize( errs );
30     MPI_Finalize();
31     return 0;
32 }
33
34 /* 
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.
40  */
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)
44 {
45     /* Note that if (sizeof(int) < sizeof(void *), just setting the int
46        part of attribute_val_out may leave some dirty bits
47     */
48     *flag = 1;
49     return MPI_ERR_OTHER;
50 }
51
52 /* Set delete flag to 1 to allow the attribute to be deleted */
53 static int delete_flag = 0;
54
55 int deletebomb_fn( MPI_Comm comm, int keyval, void *attribute_val, 
56                    void *extra_state)
57 {
58     if (delete_flag) return MPI_SUCCESS;
59     return MPI_ERR_OTHER;
60 }
61
62 void abort_msg( const char *str, int code )
63 {
64     fprintf( stderr, "%s, err = %d\n", str, code );
65     MPI_Abort( MPI_COMM_WORLD, code );
66     exit(code);
67 }
68
69 int test_communicators( void )
70 {
71     MPI_Comm dup_comm_world, d2;
72     int world_rank, world_size, key_1;
73     int err, errs = 0;
74     MPI_Aint value;
75
76     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
77     MPI_Comm_size( MPI_COMM_WORLD, &world_size );
78 #ifdef DEBUG
79     if (world_rank == 0) {
80         printf( "*** Attribute copy/delete return codes ***\n" );
81     }
82 #endif
83
84     MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
85     MPI_Barrier( dup_comm_world );
86
87     MPI_Errhandler_set( dup_comm_world, MPI_ERRORS_RETURN );
88
89     value = - 11;
90     if ((err=MPI_Comm_create_keyval( copybomb_fn, deletebomb_fn, &key_1, &value )))
91         abort_msg( "Keyval_create", err );
92
93     err = MPI_Comm_set_attr( dup_comm_world, key_1, (void *) (MPI_Aint) world_rank );
94     if (err) {
95         errs++;
96         printf( "Error with first put\n" );
97     }
98
99     err = MPI_Comm_set_attr( dup_comm_world, key_1, (void *) (MPI_Aint) (2*world_rank) );
100     if (err == MPI_SUCCESS) {
101         errs++;
102         printf( "delete function return code was MPI_SUCCESS in put\n" );
103     }
104
105     /* Because the attribute delete function should fail, the attribute
106        should *not be removed* */
107     err = MPI_Comm_delete_attr( dup_comm_world, key_1 );
108     if (err == MPI_SUCCESS) {
109         errs++;
110         printf( "delete function return code was MPI_SUCCESS in delete\n" );
111     }
112     
113     err = MPI_Comm_dup( dup_comm_world, &d2 );
114     if (err == MPI_SUCCESS) {
115         errs++;
116         printf( "copy function return code was MPI_SUCCESS in dup\n" );
117     }
118     if (err != MPI_ERR_OTHER) {
119         int lerrclass;
120         MPI_Error_class( err, &lerrclass );
121         if (lerrclass != MPI_ERR_OTHER) {
122             errs++;
123             printf( "dup did not return an error code of class ERR_OTHER; " );
124             printf( "err = %d, class = %d\n", err, lerrclass );
125         }
126     }
127 #ifndef USE_STRICT_MPI
128     /* Another interpretation is to leave d2 unchanged on error */
129     if (err && d2 != MPI_COMM_NULL) {
130         errs++;
131         printf( "dup did not return MPI_COMM_NULL on error\n" );
132     }
133 #endif
134
135     delete_flag = 1;
136     MPI_Comm_free( &dup_comm_world );
137
138     MPI_Comm_free_keyval( &key_1 );
139
140     return errs;
141 }
142