Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add mpich3 test suite, to replace older one.
[simgrid.git] / teshsuite / smpi / mpich3-test / coll / redscat2.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2001 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 /* 
7  * Test of reduce scatter.
8  *
9  * Checks that non-commutative operations are not commuted and that
10  * all of the operations are performed.
11  *
12  * Can be called with any number of processors.
13  */
14
15 #include "mpi.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include "mpitest.h"
19
20 int err = 0;
21
22 /* left(x,y) ==> x */
23 void left(void *a, void *b, int *count, MPI_Datatype *type);
24 void left(void *a, void *b, int *count, MPI_Datatype *type)
25 {
26     int *in = a;
27     int *inout = b;
28     int i;
29
30     for (i = 0; i < *count; ++i)
31     {
32         if (in[i] > inout[i])
33             ++err;
34         inout[i] = in[i];
35     }
36 }
37
38 /* right(x,y) ==> y */
39 void right(void *a, void *b, int *count, MPI_Datatype *type);
40 void right(void *a, void *b, int *count, MPI_Datatype *type)
41 {
42     int *in = a;
43     int *inout = b;
44     int i;
45
46     for (i = 0; i < *count; ++i)
47     {
48         if (in[i] > inout[i])
49             ++err;
50         inout[i] = inout[i];
51     }
52 }
53
54 /* Just performs a simple sum but can be marked as non-commutative to
55    potentially tigger different logic in the implementation. */
56 void nc_sum(void *a, void *b, int *count, MPI_Datatype *type);
57 void nc_sum(void *a, void *b, int *count, MPI_Datatype *type)
58 {
59     int *in = a;
60     int *inout = b;
61     int i;
62
63     for (i = 0; i < *count; ++i)
64     {
65         inout[i] = in[i] + inout[i];
66     }
67 }
68
69 #define MAX_BLOCK_SIZE 256
70
71 int main( int argc, char **argv )
72 {
73     int      *sendbuf, *recvcounts;
74     int      block_size;
75     int      *recvbuf;
76     int      size, rank, i;
77     MPI_Comm comm;
78     MPI_Op left_op, right_op, nc_sum_op;
79
80     MTest_Init( &argc, &argv );
81     comm = MPI_COMM_WORLD;
82
83     MPI_Comm_size( comm, &size );
84     MPI_Comm_rank( comm, &rank );
85
86     MPI_Op_create(&left, 0/*non-commutative*/, &left_op);
87     MPI_Op_create(&right, 0/*non-commutative*/, &right_op);
88     MPI_Op_create(&nc_sum, 0/*non-commutative*/, &nc_sum_op);
89
90     for (block_size = 1; block_size < MAX_BLOCK_SIZE; block_size *= 2) {
91         sendbuf = (int *) malloc( block_size * size * sizeof(int) );
92         recvbuf = malloc( block_size * sizeof(int) );
93
94         for (i=0; i<(size*block_size); i++) 
95             sendbuf[i] = rank + i;
96         for (i=0; i<block_size; i++)
97             recvbuf[i] = 0xdeadbeef;
98         recvcounts = (int *)malloc( size * sizeof(int) );
99         for (i=0; i<size; i++) 
100             recvcounts[i] = block_size;
101
102         MPI_Reduce_scatter( sendbuf, recvbuf, recvcounts, MPI_INT, left_op, comm );
103         for (i = 0; i < block_size; ++i)
104             if (recvbuf[i] != (rank * block_size + i)) ++err;
105
106         MPI_Reduce_scatter( sendbuf, recvbuf, recvcounts, MPI_INT, right_op, comm );
107         for (i = 0; i < block_size; ++i)
108             if (recvbuf[i] != ((size - 1) + (rank * block_size) + i)) ++err;
109
110         MPI_Reduce_scatter( sendbuf, recvbuf, recvcounts, MPI_INT, nc_sum_op, comm );
111         for (i = 0; i < block_size; ++i) {
112             int x = rank * block_size + i;
113             if (recvbuf[i] != (size*x + (size-1)*size/2)) ++err;
114         }
115
116         free(recvbuf);
117         free(sendbuf);
118     }
119
120     MPI_Op_free(&left_op);
121     MPI_Op_free(&right_op);
122     MPI_Op_free(&nc_sum_op);
123
124     MTest_Finalize( err );
125     MPI_Finalize( );
126
127     return err;
128 }