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 / attrerrtype.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_attrs ( void );
20 void abort_msg ( const char *, int );
21 int copybomb_fn ( MPI_Datatype, int, void *, void *, void *, int * );
22 int deletebomb_fn ( MPI_Datatype, int, void *, void * );
23
24 int main( int argc, char **argv )
25 {
26     int errs;
27     MTest_Init( &argc, &argv );
28     errs = test_attrs();
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_Datatype oldtype, 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 static int deleteCalled = 0;
55
56 int deletebomb_fn( MPI_Datatype type, int keyval, void *attribute_val, 
57                    void *extra_state)
58 {
59     deleteCalled ++;
60     if (delete_flag) return MPI_SUCCESS;
61     return MPI_ERR_OTHER;
62 }
63
64 void abort_msg( const char *str, int code )
65 {
66     fprintf( stderr, "%s, err = %d\n", str, code );
67     MPI_Abort( MPI_COMM_WORLD, code );
68     exit(code);
69 }
70
71 int test_attrs( void )
72 {
73     MPI_Datatype dup_type, d2;
74     int world_rank, world_size, key_1;
75     int err, errs = 0;
76     MPI_Aint value;
77
78     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
79     MPI_Comm_size( MPI_COMM_WORLD, &world_size );
80 #ifdef DEBUG
81     if (world_rank == 0) {
82         printf( "*** Attribute copy/delete return codes ***\n" );
83     }
84 #endif
85
86     
87     MPI_Type_dup( MPI_DOUBLE, &dup_type );
88
89     MPI_Errhandler_set( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
90
91     value = - 11;
92     if ((err=MPI_Type_create_keyval( copybomb_fn, deletebomb_fn, &key_1, &value )))
93         abort_msg( "Keyval_create", err );
94
95     err = MPI_Type_set_attr( dup_type, key_1, (void *) (MPI_Aint) world_rank );
96     if (err) {
97         errs++;
98         printf( "Error with first put\n" );
99     }
100
101     err = MPI_Type_set_attr( dup_type, key_1, (void *) (MPI_Aint) (2*world_rank) );
102     if (err == MPI_SUCCESS) {
103         errs++;
104         printf( "delete function return code was MPI_SUCCESS in put\n" );
105     }
106
107     /* Because the attribute delete function should fail, the attribute
108        should *not be removed* */
109     err = MPI_Type_delete_attr( dup_type, key_1 );
110     if (err == MPI_SUCCESS) {
111         errs++;
112         printf( "delete function return code was MPI_SUCCESS in delete\n" );
113     }
114     
115     err = MPI_Type_dup( dup_type, &d2 );
116     if (err == MPI_SUCCESS) {
117         errs++;
118         printf( "copy function return code was MPI_SUCCESS in dup\n" );
119     }
120 #ifndef USE_STRICT_MPI
121     /* Another interpretation is to leave d2 unchanged on error */
122     if (err && d2 != MPI_DATATYPE_NULL) {
123         errs++;
124         printf( "dup did not return MPI_DATATYPE_NULL on error\n" );
125     }
126 #endif
127
128     delete_flag  = 1;
129     deleteCalled = 0;
130     if (d2 != MPI_DATATYPE_NULL) 
131         MPI_Type_free(&d2);
132     MPI_Type_free( &dup_type );
133     if (deleteCalled == 0) {
134         errs++;
135         printf( "Free of a datatype did not invoke the attribute delete routine\n" );
136     }
137     MPI_Type_free_keyval( &key_1 );
138
139     return errs;
140 }