File: attric.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 (151 lines) | stat: -rw-r--r-- 4,521 bytes parent folder | download | duplicates (4)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/*

  Exercise communicator routines for intercommunicators

  This C version derived from attrt, which in turn was
  derived from a Fortran test program from ...

 */
#include <stdio.h>
#include "mpi.h"
#include "mpitest.h"

/* #define DEBUG */
int test_communicators(void);
int copy_fn(MPI_Comm, int, void *, void *, void *, int *);
int delete_fn(MPI_Comm, int, void *, void *);
#ifdef DEBUG
#define FFLUSH fflush(stdout);
#else
#define FFLUSH
#endif

int main(int argc, char **argv)
{
    int errs = 0;
    MTest_Init(&argc, &argv);

    errs = test_communicators();

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

int copy_fn(MPI_Comm oldcomm, int keyval, void *extra_state,
            void *attribute_val_in, void *attribute_val_out, int *flag)
{
    /* Note that if (sizeof(int) < sizeof(void *), just setting the int
     * part of attribute_val_out may leave some dirty bits
     */
    *(MPI_Aint *) attribute_val_out = (MPI_Aint) attribute_val_in;
    *flag = 1;
    return MPI_SUCCESS;
}

int delete_fn(MPI_Comm comm, int keyval, void *attribute_val, void *extra_state)
{
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    if ((MPI_Aint) attribute_val != (MPI_Aint) world_rank) {
        printf("incorrect attribute value %d\n", *(int *) attribute_val);
        MPI_Abort(MPI_COMM_WORLD, 1005);
    }
    return MPI_SUCCESS;
}

int test_communicators(void)
{
    MPI_Comm dup_comm, comm;
    void *vvalue;
    int flag, world_rank, world_size, key_1, key_3;
    int errs = 0;
    MPI_Aint value;
    int isLeft;

    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
#ifdef DEBUG
    if (world_rank == 0) {
        printf("*** Communicators ***\n");
        fflush(stdout);
    }
#endif

    while (MTestGetIntercomm(&comm, &isLeft, 2)) {
        MTestPrintfMsg(1, "start while loop, isLeft=%s\n", (isLeft ? "TRUE" : "FALSE"));

        if (comm == MPI_COMM_NULL) {
            MTestPrintfMsg(1, "got COMM_NULL, skipping\n");
            continue;
        }

        /*
         * Check Comm_dup by adding attributes to comm & duplicating
         */

        value = 9;
        MPI_Keyval_create(copy_fn, delete_fn, &key_1, &value);
        MTestPrintfMsg(1, "Keyval_create key=%#x value=%d\n", key_1, value);
        value = 7;
        MPI_Keyval_create(MPI_NULL_COPY_FN, MPI_NULL_DELETE_FN, &key_3, &value);
        MTestPrintfMsg(1, "Keyval_create key=%#x value=%d\n", key_3, value);

        /* This may generate a compilation warning; it is, however, an
         * easy way to cache a value instead of a pointer */
        /* printf("key1 = %x key3 = %x\n", key_1, key_3); */
        MPI_Attr_put(comm, key_1, (void *) (MPI_Aint) world_rank);
        MPI_Attr_put(comm, key_3, (void *) 0);

        MTestPrintfMsg(1, "Comm_dup\n");
        MPI_Comm_dup(comm, &dup_comm);

        /* Note that if sizeof(int) < sizeof(void *), we can't use
         * (void **)&value to get the value we passed into Attr_put.  To avoid
         * problems (e.g., alignment errors), we recover the value into
         * a (void *) and cast to int. Note that this may generate warning
         * messages from the compiler.  */
        MPI_Attr_get(dup_comm, key_1, (void **) &vvalue, &flag);
        value = (MPI_Aint) vvalue;

        if (!flag) {
            errs++;
            printf("dup_comm key_1 not found on %d\n", world_rank);
            fflush(stdout);
            MPI_Abort(MPI_COMM_WORLD, 3004);
        }

        if (value != world_rank) {
            errs++;
            printf("dup_comm key_1 value incorrect: %ld\n", (long) value);
            fflush(stdout);
            MPI_Abort(MPI_COMM_WORLD, 3005);
        }

        MPI_Attr_get(dup_comm, key_3, (void **) &vvalue, &flag);
        value = (MPI_Aint) vvalue;
        if (flag) {
            errs++;
            printf("dup_comm key_3 found!\n");
            fflush(stdout);
            MPI_Abort(MPI_COMM_WORLD, 3008);
        }
        MTestPrintfMsg(1, "Keyval_free key=%#x\n", key_1);
        MPI_Keyval_free(&key_1);
        MTestPrintfMsg(1, "Keyval_free key=%#x\n", key_3);
        MPI_Keyval_free(&key_3);
        /*
         * Free all communicators created
         */
        MTestPrintfMsg(1, "Comm_free comm\n");
        MPI_Comm_free(&comm);
        MTestPrintfMsg(1, "Comm_free dup_comm\n");
        MPI_Comm_free(&dup_comm);
    }

    return errs;
}