File: attricx.cxx

package info (click to toggle)
mpich 4.0.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 423,384 kB
  • sloc: ansic: 1,088,434; cpp: 71,364; javascript: 40,763; f90: 22,829; sh: 17,463; perl: 14,773; xml: 14,418; python: 10,265; makefile: 9,246; fortran: 8,008; java: 4,355; asm: 324; ruby: 176; lisp: 19; php: 8; sed: 4
file content (181 lines) | stat: -rw-r--r-- 5,056 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/*

  Exercise communicator routines for intercommunicators

  This C++ version derived from the C version, attric
 */
#include "mpi.h"
#include "mpitestconf.h"
#ifdef HAVE_IOSTREAM
// Not all C++ compilers have iostream instead of iostream.h
#include <iostream>
#ifdef HAVE_NAMESPACE_STD
// Those that do often need the std namespace; otherwise, a bare "cout"
// is likely to fail to compile
using namespace std;
#endif
#else
#include <iostream.h>
#endif
#include <stdio.h>
#include "mpitestcxx.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif

/* #define DEBUG */
static int verbose = 0;
int test_communicators(void);
int copy_fn(const MPI::Comm &, int, void *, void *, void *, bool &);
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();

    errs = test_communicators();

    MTest_Finalize(errs);
    return 0;
}

int copy_fn(const MPI::Comm & oldcomm, int keyval, void *extra_state,
            void *attribute_val_in, void *attribute_val_out, bool & 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;
    world_rank = MPI::COMM_WORLD.Get_rank();
    if ((MPI::Aint) attribute_val != (MPI::Aint) world_rank) {
        cout << "incorrect attribute value %d\n" << *(int *) attribute_val << "\n";
        MPI::COMM_WORLD.Abort(1005);
    }
    return MPI_SUCCESS;
}

int test_communicators(void)
{
    MPI::Intercomm dup_comm, comm;
    void *vvalue;
    int flag, world_rank, world_size, key_1, key_3;
    int errs = 0;
    MPI::Aint value;
    int isLeft;

    world_rank = MPI::COMM_WORLD.Get_rank();
    world_size = MPI::COMM_WORLD.Get_size();
#ifdef DEBUG
    if (world_rank == 0) {
        cout << "*** Communicators ***\n";
    }
#endif

    while (MTestGetIntercomm(comm, isLeft, 2)) {
        if (verbose) {
            cout << "start while loop, isLeft=" << isLeft << "\n";
        }

        if (comm == MPI::COMM_NULL) {
            if (verbose) {
                cout << "got COMM_NULL, skipping\n";
            }
            continue;
        }

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

        value = 9;
        key_1 = MPI::Comm::Create_keyval(copy_fn, delete_fn, &value);
        if (verbose) {
            cout << "Keyval_create key=" << key_1 << " value=" << value << "\n";
        }
        value = 7;
        key_3 = MPI::Comm::Create_keyval(MPI::Comm::NULL_COPY_FN,
                                         MPI::Comm::NULL_DELETE_FN, &value);
        if (verbose) {
            cout << "Keyval_create key=" << key_3 << " value=" << value << "\n";
        }

        /* 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); */
        comm.Set_attr(key_1, (void *) (MPI::Aint) world_rank);
        comm.Set_attr(key_3, (void *) 0);

        if (verbose) {
            cout << "Comm_dup\n";
        }
        dup_comm = comm.Dup();

        /* 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.  */
        flag = dup_comm.Get_attr(key_1, (void **) &vvalue);
        value = (MPI::Aint) vvalue;

        if (!flag) {
            errs++;
            cout << "dup_comm key_1 not found on " << world_rank << "\n";
            MPI::COMM_WORLD.Abort(3004);
        }

        if (value != world_rank) {
            errs++;
            cout << "dup_comm key_1 value incorrect: " << (long) value << "\n";
            MPI::COMM_WORLD.Abort(3005);
        }

        flag = dup_comm.Get_attr(key_3, (void **) &vvalue);
        value = (MPI::Aint) vvalue;
        if (flag) {
            errs++;
            cout << "dup_comm key_3 found!\n";
            MPI::COMM_WORLD.Abort(3008);
        }
        if (verbose) {
            cout << "Keyval_free key=" << key_1 << "\n";
        }
        MPI::Comm::Free_keyval(key_1);
        if (verbose) {
            cout << "Keyval_free key=" << key_3 << "\n";
        }
        MPI::Comm::Free_keyval(key_3);
        /*
         * Free all communicators created
         */
        if (verbose) {
            cout << "Comm_free comm\n";
        }
        comm.Free();
        if (verbose) {
            cout << "Comm_free dup_comm\n";
        }
        dup_comm.Free();
    }

    return errs;
}