3 Exercise attribute routines.
4 This version checks for correct behavior of the copy and delete functions
5 on an attribute, particularly the correct behavior when the routine returns
13 int test_communicators ( void );
14 void abort_msg ( const char *, int );
15 int copybomb_fn ( MPI_Comm, int, void *, void *, void *, int * );
16 int deletebomb_fn ( MPI_Comm, int, void *, void * );
18 int main( int argc, char **argv )
20 MPI_Init( &argc, &argv );
28 * MPI 1.2 Clarification: Clarification of Error Behavior of
29 * Attribute Callback Functions
30 * Any return value other than MPI_SUCCESS is erroneous. The specific value
31 * returned to the user is undefined (other than it can't be MPI_SUCCESS).
32 * Proposals to specify particular values (e.g., user's value) failed.
34 /* Return an error as the value */
35 int copybomb_fn( MPI_Comm oldcomm, int keyval, void *extra_state,
36 void *attribute_val_in, void *attribute_val_out, int *flag)
38 /* Note that if (sizeof(int) < sizeof(void *), just setting the int
39 part of attribute_val_out may leave some dirty bits
45 /* Set delete flag to 1 to allow the attribute to be deleted */
46 static int delete_flag = 0;
47 int deletebomb_fn( MPI_Comm comm, int keyval, void *attribute_val,
50 if (delete_flag) return MPI_SUCCESS;
54 void abort_msg( const char *str, int code )
56 fprintf( stderr, "%s, err = %d\n", str, code );
57 MPI_Abort( MPI_COMM_WORLD, code );
60 int test_communicators( void )
62 MPI_Comm dup_comm_world, d2;
64 int world_size, key_1;
68 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
70 MPI_Comm_size( MPI_COMM_WORLD, &world_size );
71 if (world_rank == 0) {
72 printf( "*** Attribute copy/delete return codes ***\n" );
75 MPI_Comm_dup( MPI_COMM_WORLD, &dup_comm_world );
76 MPI_Barrier( dup_comm_world );
78 MPI_Errhandler_set( dup_comm_world, MPI_ERRORS_RETURN );
81 if ((err=MPI_Keyval_create( copybomb_fn, deletebomb_fn, &key_1, &value )))
82 abort_msg( "Keyval_create", err );
84 err = MPI_Attr_put( dup_comm_world, key_1, (void *)world_rank );
86 printf( "Error with first put\n" );
89 err = MPI_Attr_put( dup_comm_world, key_1, (void *)(2*world_rank) );
90 if (err == MPI_SUCCESS) {
91 printf( "delete function return code was MPI_SUCCESS in put\n" );
94 /* Because the attribute delete function should fail, the attribute
95 should *not be removed* */
96 err = MPI_Attr_delete( dup_comm_world, key_1 );
97 if (err == MPI_SUCCESS) {
98 printf( "delete function return code was MPI_SUCCESS in delete\n" );
101 err = MPI_Comm_dup( dup_comm_world, &d2 );
102 if (err == MPI_SUCCESS) {
103 printf( "copy function return code was MPI_SUCCESS in dup\n" );
105 if (err && d2 != MPI_COMM_NULL) {
106 printf( "dup did not return MPI_COMM_NULL on error\n" );
110 MPI_Comm_free( &dup_comm_world );