Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
This used to work by accident
[simgrid.git] / teshsuite / smpi / mpich-test / coll / scantst.c
1 #include "mpi.h"
2 #include <stdio.h>
3 #include "test.h"
4
5 MPI_Comm GetNextComm( void );
6 void addem ( int *, int *, int *, MPI_Datatype * );
7 void assoc ( int *, int *, int *, MPI_Datatype * );
8
9 void addem( int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
10 {
11   int i;
12   for ( i=0; i<*len; i++ ) 
13     inoutvec[i] += invec[i];
14 }
15
16 #define BAD_ANSWER 100000
17
18 /*
19     The operation is inoutvec[i] = invec[i] op inoutvec[i] 
20     (see 4.9.4).  The order is important.
21
22     Note that the computation is in process rank (in the communicator)
23     order, independant of the root.
24  */
25 void assoc( int *invec, int *inoutvec, int *len, MPI_Datatype *dtype)
26 {
27   int i;
28   for ( i=0; i<*len; i++ )  {
29     if (inoutvec[i] <= invec[i] ) {
30       int rank;
31       MPI_Comm_rank( MPI_COMM_WORLD, &rank );
32       fprintf( stderr, "[%d] inout[0] = %d, in[0] = %d\n", 
33               rank, inoutvec[0], invec[0] );
34       inoutvec[i] = BAD_ANSWER;
35       }
36     else 
37       inoutvec[i] = invec[i];
38   }
39 }
40
41 MPI_Comm GetNextComm( void )
42 {
43     MPI_Comm comm = MPI_COMM_NULL;
44     static int idx = 0;
45     int size, rank;
46     MPI_Comm_size( MPI_COMM_WORLD, &size );
47     MPI_Comm_rank( MPI_COMM_WORLD, &rank );
48
49     switch (idx) {
50     case 0: 
51         MPI_Comm_dup( MPI_COMM_WORLD, &comm );
52         break;
53     case 1:
54         /* invert the rank order */
55         MPI_Comm_split( MPI_COMM_WORLD, 0, size - rank, &comm );
56         break;
57     case 2:
58         /* Divide into subsets */
59         MPI_Comm_split( MPI_COMM_WORLD, rank < (size/2), rank, &comm );
60         break;
61     case 3:
62         /* Another division */
63         MPI_Comm_split( MPI_COMM_WORLD, rank < (size/3), size-rank, &comm );
64         break;
65     case 4:
66         /* odd and even */
67         MPI_Comm_split( MPI_COMM_WORLD, (rank % 2) == 0, rank, &comm );
68         break;
69     case 5:
70         /* Last case: startover */
71         idx = -1;
72         break;
73     }
74     idx++;
75     return comm;
76 }
77
78 int main( int argc, char **argv )
79 {
80     int              rank, size, i;
81     int              data;
82     int              errors=0;
83     int              result = -100;
84     int              correct_result;
85     MPI_Op           op_assoc, op_addem;
86     MPI_Comm         comm;
87
88     MPI_Init( &argc, &argv );
89     MPI_Op_create( (MPI_User_function *)assoc, 0, &op_assoc );
90     MPI_Op_create( (MPI_User_function *)addem, 1, &op_addem );
91
92     /* Run this for a variety of communicator sizes */
93     while ((comm = GetNextComm()) != MPI_COMM_NULL) {
94         MPI_Comm_rank( comm, &rank );
95         MPI_Comm_size( comm, &size );
96
97         data = rank;
98         
99         correct_result = 0;
100         for (i=0;i<=rank;i++)
101             correct_result += i;
102
103         MPI_Scan ( &data, &result, 1, MPI_INT, MPI_SUM, comm );
104         if (result != correct_result) {
105             fprintf( stderr, "[%d] Error suming ints with scan\n", rank );
106             errors++;
107         }
108
109         MPI_Scan ( &data, &result, 1, MPI_INT, MPI_SUM, comm );
110         if (result != correct_result) {
111             fprintf( stderr, "[%d] Error summing ints with scan (2)\n", rank );
112             errors++;
113         }
114
115         data = rank;
116         result = -100;
117         MPI_Scan ( &data, &result, 1, MPI_INT, op_addem, comm );
118         if (result != correct_result) {
119             fprintf( stderr, "[%d] Error summing ints with scan (userop)\n", 
120                      rank );
121             errors++;
122         }
123
124         MPI_Scan ( &data, &result, 1, MPI_INT, op_addem, comm );
125         if (result != correct_result) {
126             fprintf( stderr, "[%d] Error summing ints with scan (userop2)\n", 
127                      rank );
128             errors++;
129         }
130 /*      result = -100;*/
131 /*      data = rank;*/
132 /*      MPI_Scan ( &data, &result, 1, MPI_INT, op_assoc, comm );*/
133 /*      if (result == BAD_ANSWER) {*/
134 /*          fprintf( stderr, "[%d] Error scanning with non-commutative op\n",*/
135 /*                   rank );*/
136 /*          errors++;*/
137 /*      }*/
138         MPI_Comm_free( &comm );
139     }
140
141     MPI_Op_free( &op_assoc );
142     MPI_Op_free( &op_addem );
143
144     if (errors) {
145         MPI_Comm_rank( MPI_COMM_WORLD, &rank );
146         printf( "[%d] done with ERRORS(%d)!\n", rank, errors );
147     }
148
149     Test_Waitforall( );
150     MPI_Finalize();
151     return errors;
152 }