Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add MPI_Comm_*keyval and MPI_Comm*attr functions
[simgrid.git] / teshsuite / smpi / mpich3-test / attr / attric.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2001 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 /*
8
9   Exercise communicator routines for intercommunicators
10
11   This C version derived from attrt, which in turn was
12   derived from a Fortran test program from ...
13
14  */
15 #include <stdio.h>
16 #include "mpi.h"
17 #include "mpitest.h"
18
19 /* #define DEBUG */
20 int test_communicators ( void );
21 int copy_fn ( MPI_Comm, int, void *, void *, void *, int * );
22 int delete_fn ( MPI_Comm, int, void *, void * );
23 #ifdef DEBUG
24 #define FFLUSH fflush(stdout);
25 #else
26 #define FFLUSH
27 #endif
28
29 int main( int argc, char **argv )
30 {
31     int errs = 0;
32     MTest_Init( &argc, &argv );
33     
34     errs = test_communicators();
35
36     MTest_Finalize( errs );
37     MPI_Finalize();
38     return 0;
39 }
40
41 int copy_fn( MPI_Comm oldcomm, int keyval, void *extra_state,
42              void *attribute_val_in, void *attribute_val_out, int *flag)
43 {
44     /* Note that if (sizeof(int) < sizeof(void *), just setting the int
45        part of attribute_val_out may leave some dirty bits
46     */
47     *(MPI_Aint *)attribute_val_out = (MPI_Aint)attribute_val_in;
48     *flag = 1;
49     return MPI_SUCCESS;
50 }
51
52 int delete_fn( MPI_Comm comm, int keyval, void *attribute_val, 
53                void *extra_state)
54 {
55     int world_rank;
56     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
57     if ((MPI_Aint)attribute_val != (MPI_Aint)world_rank) {
58         printf( "incorrect attribute value %d\n", *(int*)attribute_val );
59         MPI_Abort(MPI_COMM_WORLD, 1005 );
60         exit(1005);
61     }
62     return MPI_SUCCESS;
63 }
64
65 int test_communicators( void )
66 {
67     MPI_Comm dup_comm, comm;
68     void *vvalue;
69     int flag, world_rank, world_size, key_1, key_3;
70     int errs = 0;
71     MPI_Aint value;
72     int      isLeft;
73
74     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
75     MPI_Comm_size( MPI_COMM_WORLD, &world_size );
76 #ifdef DEBUG
77     if (world_rank == 0) {
78         printf( "*** Communicators ***\n" ); fflush(stdout);
79     }
80 #endif
81
82     while (MTestGetIntercomm( &comm, &isLeft, 2 )) {
83         MTestPrintfMsg(1, "start while loop, isLeft=%s\n", (isLeft ? "TRUE" : "FALSE"));
84
85         if (comm == MPI_COMM_NULL) {
86             MTestPrintfMsg(1, "got COMM_NULL, skipping\n");
87             continue;
88         }
89
90         /*
91           Check Comm_dup by adding attributes to comm & duplicating
92         */
93     
94         value = 9;
95         MPI_Keyval_create(copy_fn,     delete_fn,   &key_1, &value );
96         MTestPrintfMsg(1, "Keyval_create key=%#x value=%d\n", key_1, value);
97         value = 7;
98         MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN,
99                           &key_3, &value ); 
100         MTestPrintfMsg(1, "Keyval_create key=%#x value=%d\n", key_3, value);
101
102         /* This may generate a compilation warning; it is, however, an
103            easy way to cache a value instead of a pointer */
104         /* printf( "key1 = %x key3 = %x\n", key_1, key_3 ); */
105         MPI_Attr_put(comm, key_1, (void *) (MPI_Aint) world_rank );
106         MPI_Attr_put(comm, key_3, (void *)0 );
107         
108         MTestPrintfMsg(1, "Comm_dup\n" );
109         MPI_Comm_dup(comm, &dup_comm );
110
111         /* Note that if sizeof(int) < sizeof(void *), we can't use
112            (void **)&value to get the value we passed into Attr_put.  To avoid 
113            problems (e.g., alignment errors), we recover the value into 
114            a (void *) and cast to int. Note that this may generate warning
115            messages from the compiler.  */
116         MPI_Attr_get(dup_comm, key_1, (void **)&vvalue, &flag );
117         value = (MPI_Aint)vvalue;
118         
119         if (! flag) {
120             errs++;
121             printf( "dup_comm key_1 not found on %d\n", world_rank );
122             fflush( stdout );
123             MPI_Abort(MPI_COMM_WORLD, 3004 );
124             exit(3004);
125         }
126         
127         if (value != world_rank) {
128             errs++;
129             printf( "dup_comm key_1 value incorrect: %ld\n", (long)value );
130             fflush( stdout );
131             MPI_Abort(MPI_COMM_WORLD, 3005 );
132             exit(3005);
133         }
134
135         MPI_Attr_get(dup_comm, key_3, (void **)&vvalue, &flag );
136         value = (MPI_Aint)vvalue;
137         if (flag) {
138             errs++;
139             printf( "dup_comm key_3 found!\n" );
140             fflush( stdout );
141             MPI_Abort(MPI_COMM_WORLD, 3008 );
142             exit(3008);
143         }
144         MTestPrintfMsg(1, "Keyval_free key=%#x\n", key_1);
145         MPI_Keyval_free(&key_1 );
146         MTestPrintfMsg(1, "Keyval_free key=%#x\n", key_3);
147         MPI_Keyval_free(&key_3 );
148         /*
149           Free all communicators created
150         */
151         MTestPrintfMsg(1, "Comm_free comm\n");
152         MPI_Comm_free( &comm );
153         MTestPrintfMsg(1, "Comm_free dup_comm\n");
154         MPI_Comm_free( &dup_comm );
155     }
156
157     return errs;
158 }
159