Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add new coll tests
[simgrid.git] / teshsuite / smpi / mpich3-test / coll / allred_derived.c
1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mpitest.h"
10 #include <assert.h>
11
12 /*
13 static char MTEST_Descrip[] = "Test MPI_Allreduce with commutative user-defined operations";
14 */
15
16 #define MAX_BLOCKLEN 10000
17 #define IS_COMMUTATIVE 1
18
19 /* We make the error count global so that we can easily control the output
20    of error information (in particular, limiting it after the first 10
21    errors */
22 int errs = 0;
23
24 /* parameter for a vector type of MPI_INT */
25 int g_blocklen = 1;
26 int g_stride = 1;
27
28 void uop(void *, void *, int *, MPI_Datatype *);
29 void uop(void *cinPtr, void *coutPtr, int *count, MPI_Datatype * dtype)
30 {
31     const int *cin = (const int *) cinPtr;
32     int *cout = (int *) coutPtr;
33
34     int k = 0;
35     for (int i = 0; i < *count; i++) {
36         for (int j = 0; j < g_blocklen; j++) {
37             cout[k] += cin[k];
38             k += g_stride;
39         }
40     }
41 }
42
43 static void init_buf(void *buf, int count, int rank)
44 {
45     int *p = buf;
46
47     int k = 0;
48     for (int i = 0; i < count; i++) {
49         for (int j = 0; j < g_blocklen; j++) {
50             p[k] = rank + i + j;
51             k += g_stride;
52         }
53     }
54 }
55
56 static int check_result(void *buf, int count, int size)
57 {
58     int lerrs = 0;
59     int *p = buf;
60
61     int k = 0;
62     for (int i = 0; i < count; i++) {
63         for (int j = 0; j < g_blocklen; j++) {
64             int exp = size * (size - 1) / 2 + (i + j) * size;
65             if (p[k] != exp) {
66                 lerrs++;
67                 if (errs + lerrs < 10) {
68                     printf("[%d - %d] expected %d, got %d, %s\n",
69                            i, j, exp, p[k], MTestGetIntracommName());
70                 }
71             }
72             k += g_stride;
73         }
74     }
75     return lerrs;
76 }
77
78 int main(int argc, char *argv[])
79 {
80     MPI_Comm comm;
81     void *buf, *bufout;
82     MPI_Op op;
83     MPI_Datatype datatype;
84
85     MTest_Init(&argc, &argv);
86
87     MPI_Op_create(uop, IS_COMMUTATIVE, &op);
88
89     while (MTestGetIntracommGeneral(&comm, 2, 1)) {
90         if (comm == MPI_COMM_NULL) {
91             continue;
92         }
93
94         int rank, size;
95         MPI_Comm_rank(comm, &rank);
96         MPI_Comm_size(comm, &size);
97
98         int count = 10;
99         for (int n = 1; n < MAX_BLOCKLEN; n *= 2) {
100             g_blocklen = n;
101             int extent = g_blocklen * g_stride * sizeof(int);
102             MPI_Type_vector(g_blocklen, 1, g_stride, MPI_INT, &datatype);
103             MPI_Type_commit(&datatype);
104
105             buf = (int *) malloc(extent * count);
106             if (!buf) {
107                 MPI_Abort(MPI_COMM_WORLD, 1);
108             }
109             bufout = (int *) malloc(extent * count);
110             if (!bufout) {
111                 MPI_Abort(MPI_COMM_WORLD, 1);
112             }
113
114             init_buf(buf, count, rank);
115             MPI_Allreduce(buf, bufout, count, datatype, op, comm);
116             errs += check_result(bufout, count, size);
117
118             /* do it again using MPI_IN_PLACE */
119             init_buf(bufout, count, rank);
120             MPI_Allreduce(MPI_IN_PLACE, bufout, count, datatype, op, comm);
121             errs += check_result(bufout, count, size);
122
123             free(buf);
124             free(bufout);
125             MPI_Type_free(&datatype);
126         }
127
128         MTestFreeComm(&comm);
129     }
130
131     MPI_Op_free(&op);
132
133     MTest_Finalize(errs);
134     return MTestReturnValue(errs);
135 }