File: allred_derived.c

package info (click to toggle)
mpich 4.3.0%2Breally4.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 419,120 kB
  • sloc: ansic: 1,215,557; cpp: 74,755; javascript: 40,763; f90: 20,649; sh: 18,463; xml: 14,418; python: 14,397; perl: 13,772; makefile: 9,279; fortran: 8,063; java: 4,553; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (135 lines) | stat: -rw-r--r-- 3,408 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include "mpitest.h"
#include <assert.h>

/*
static char MTEST_Descrip[] = "Test MPI_Allreduce with commutative user-defined operations";
*/

#define MAX_BLOCKLEN 10000
#define IS_COMMUTATIVE 1

/* We make the error count global so that we can easily control the output
   of error information (in particular, limiting it after the first 10
   errors */
int errs = 0;

/* parameter for a vector type of MPI_INT */
int g_blocklen = 1;
int g_stride = 1;

void uop(void *, void *, int *, MPI_Datatype *);
void uop(void *cinPtr, void *coutPtr, int *count, MPI_Datatype * dtype)
{
    const int *cin = (const int *) cinPtr;
    int *cout = (int *) coutPtr;

    int k = 0;
    for (int i = 0; i < *count; i++) {
        for (int j = 0; j < g_blocklen; j++) {
            cout[k] += cin[k];
            k += g_stride;
        }
    }
}

static void init_buf(void *buf, int count, int rank)
{
    int *p = buf;

    int k = 0;
    for (int i = 0; i < count; i++) {
        for (int j = 0; j < g_blocklen; j++) {
            p[k] = rank + i + j;
            k += g_stride;
        }
    }
}

static int check_result(void *buf, int count, int size)
{
    int lerrs = 0;
    int *p = buf;

    int k = 0;
    for (int i = 0; i < count; i++) {
        for (int j = 0; j < g_blocklen; j++) {
            int exp = size * (size - 1) / 2 + (i + j) * size;
            if (p[k] != exp) {
                lerrs++;
                if (errs + lerrs < 10) {
                    printf("[%d - %d] expected %d, got %d, %s\n",
                           i, j, exp, p[k], MTestGetIntracommName());
                }
            }
            k += g_stride;
        }
    }
    return lerrs;
}

int main(int argc, char *argv[])
{
    MPI_Comm comm;
    void *buf, *bufout;
    MPI_Op op;
    MPI_Datatype datatype;

    MTest_Init(&argc, &argv);

    MPI_Op_create(uop, IS_COMMUTATIVE, &op);

    while (MTestGetIntracommGeneral(&comm, 2, 1)) {
        if (comm == MPI_COMM_NULL) {
            continue;
        }

        int rank, size;
        MPI_Comm_rank(comm, &rank);
        MPI_Comm_size(comm, &size);

        int count = 10;
        for (int n = 1; n < MAX_BLOCKLEN; n *= 2) {
            g_blocklen = n;
            int extent = g_blocklen * g_stride * sizeof(int);
            MPI_Type_vector(g_blocklen, 1, g_stride, MPI_INT, &datatype);
            MPI_Type_commit(&datatype);

            buf = (int *) malloc(extent * count);
            if (!buf) {
                MPI_Abort(MPI_COMM_WORLD, 1);
            }
            bufout = (int *) malloc(extent * count);
            if (!bufout) {
                MPI_Abort(MPI_COMM_WORLD, 1);
            }

            init_buf(buf, count, rank);
            MPI_Allreduce(buf, bufout, count, datatype, op, comm);
            errs += check_result(bufout, count, size);

            /* do it again using MPI_IN_PLACE */
            init_buf(bufout, count, rank);
            MPI_Allreduce(MPI_IN_PLACE, bufout, count, datatype, op, comm);
            errs += check_result(bufout, count, size);

            free(buf);
            free(bufout);
            MPI_Type_free(&datatype);
        }

        MTestFreeComm(&comm);
    }

    MPI_Op_free(&op);

    MTest_Finalize(errs);
    return MTestReturnValue(errs);
}