Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Change include order for smpi tests/examples to avoid conflicts
[simgrid.git] / teshsuite / smpi / mpich3-test / coll / red_scat_block2.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *  (C) 2010 by Argonne National Laboratory.
4  *      See COPYRIGHT in top-level directory.
5  */
6 /* 
7  * Test of reduce_scatter_block.
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 #if MTEST_HAVE_MIN_MPI_VERSION(2,2)
74     int      *sendbuf;
75     int      block_size;
76     int      *recvbuf;
77     int      i;
78     MPI_Op left_op, right_op, nc_sum_op;
79 #endif
80     int      size, rank;
81     MPI_Comm comm;
82
83     MTest_Init( &argc, &argv );
84     comm = MPI_COMM_WORLD;
85
86     MPI_Comm_size( comm, &size );
87     MPI_Comm_rank( comm, &rank );
88
89 #if MTEST_HAVE_MIN_MPI_VERSION(2,2)
90     /* MPI_Reduce_scatter block was added in MPI-2.2 */
91
92     MPI_Op_create(&left, 0/*non-commutative*/, &left_op);
93     MPI_Op_create(&right, 0/*non-commutative*/, &right_op);
94     MPI_Op_create(&nc_sum, 0/*non-commutative*/, &nc_sum_op);
95
96     for (block_size = 1; block_size < MAX_BLOCK_SIZE; block_size *= 2) {
97         sendbuf = (int *) malloc( block_size * size * sizeof(int) );
98         recvbuf = malloc( block_size * sizeof(int) );
99
100         for (i=0; i<(size*block_size); i++) 
101             sendbuf[i] = rank + i;
102         for (i=0; i<block_size; i++)
103             recvbuf[i] = 0xdeadbeef;
104
105         MPI_Reduce_scatter_block( sendbuf, recvbuf, block_size, MPI_INT, left_op, comm );
106         for (i = 0; i < block_size; ++i)
107             if (recvbuf[i] != (rank * block_size + i)) ++err;
108
109         MPI_Reduce_scatter_block( sendbuf, recvbuf, block_size, MPI_INT, right_op, comm );
110         for (i = 0; i < block_size; ++i)
111             if (recvbuf[i] != ((size - 1) + (rank * block_size) + i)) ++err;
112
113         MPI_Reduce_scatter_block( sendbuf, recvbuf, block_size, MPI_INT, nc_sum_op, comm );
114         for (i = 0; i < block_size; ++i) {
115             int x = rank * block_size + i;
116             if (recvbuf[i] != (size*x + (size-1)*size/2)) ++err;
117         }
118
119         free(recvbuf);
120         free(sendbuf);
121     }
122
123     MPI_Op_free(&left_op);
124     MPI_Op_free(&right_op);
125     MPI_Op_free(&nc_sum_op);
126 #endif 
127
128     MTest_Finalize( err );
129     MPI_Finalize( );
130
131     return err;
132 }