File: c2f2c.c

package info (click to toggle)
mpich 4.3.0%2Breally4.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, 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 (257 lines) | stat: -rw-r--r-- 6,534 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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

/*
 * This file contains the C routines used in testing the c2f and f2c
 * handle conversion functions, except for MPI_File and MPI_Win (to
 * allow working with MPI implementations that do not include those
 * features).
 *
 * The tests follow this pattern:
 *
 *  Fortran main program
 *     calls c routine with each handle type, with a prepared
 *     and valid handle (often requires constructing an object)
 *
 *     C routine uses xxx_f2c routine to get C handle, checks some
 *     properties (i.e., size and rank of communicator, contents of datatype)
 *
 *     Then the Fortran main program calls a C routine that provides
 *     a handle, and the Fortran program performs similar checks.
 *
 * We also assume that a C int is a Fortran integer.  If this is not the
 * case, these tests must be modified.
 */

/* style: allow:fprintf:10 sig:0 */
#include <stdio.h>
#include "mpi.h"
#include "../../include/mpitestconf.h"
#include <string.h>

/*
   Name mapping.  All routines are created with names that are lower case
   with a single trailing underscore.  This matches many compilers.
   We use #define to change the name for Fortran compilers that do
   not use the lowercase/underscore pattern
*/

#ifdef F77_NAME_UPPER
#define c2fcomm_ C2FCOMM
#define c2fgroup_ C2FGROUP
#define c2ftype_ C2FTYPE
#define c2finfo_ C2FINFO
#define c2frequest_ C2FREQUEST
#define c2fop_ C2FOP
#define c2ferrhandler_ C2FERRHANDLER

#define f2ccomm_ F2CCOMM
#define f2cgroup_ F2CGROUP
#define f2ctype_ F2CTYPE
#define f2cinfo_ F2CINFO
#define f2crequest_ F2CREQUEST
#define f2cop_ F2COP
#define f2cerrhandler_ F2CERRHANDLER

#elif defined(F77_NAME_LOWER) || defined(F77_NAME_MIXED)
/* Mixed is ok because we use lowercase in all uses */
#define c2fcomm_ c2fcomm
#define c2fgroup_ c2fgroup
#define c2ftype_ c2ftype
#define c2finfo_ c2finfo
#define c2frequest_ c2frequest
#define c2fop_ c2fop
#define c2ferrhandler_ c2ferrhandler

#define f2ccomm_ f2ccomm
#define f2cgroup_ f2cgroup
#define f2ctype_ f2ctype
#define f2cinfo_ f2cinfo
#define f2crequest_ f2crequest
#define f2cop_ f2cop
#define f2cerrhandler_ f2cerrhandler

#elif defined(F77_NAME_LOWER_2USCORE) || defined(F77_NAME_LOWER_USCORE) || \
      defined(F77_NAME_MIXED_USCORE)
/* Else leave name alone (routines have no underscore, so both
   of these map to a lowercase, single underscore) */
#else
#error 'Unrecognized Fortran name mapping'
#endif

/* Prototypes to keep compilers happy */
MPI_Fint c2fcomm_(MPI_Fint *);
MPI_Fint c2fgroup_(MPI_Fint *);
MPI_Fint c2finfo_(MPI_Fint *);
MPI_Fint c2frequest_(MPI_Fint *);
MPI_Fint c2ftype_(MPI_Fint *);
MPI_Fint c2fop_(MPI_Fint *);
MPI_Fint c2ferrhandler_(MPI_Fint *);

void f2ccomm_(MPI_Fint *);
void f2cgroup_(MPI_Fint *);
void f2cinfo_(MPI_Fint *);
void f2crequest_(MPI_Fint *);
void f2ctype_(MPI_Fint *);
void f2cop_(MPI_Fint *);
void f2cerrhandler_(MPI_Fint *);


MPI_Fint c2fcomm_(MPI_Fint * comm)
{
    MPI_Comm cComm = MPI_Comm_f2c(*comm);
    int cSize, wSize, cRank, wRank;

    MPI_Comm_size(MPI_COMM_WORLD, &wSize);
    MPI_Comm_rank(MPI_COMM_WORLD, &wRank);
    MPI_Comm_size(cComm, &cSize);
    MPI_Comm_rank(cComm, &cRank);

    if (wSize != cSize || wRank != cRank) {
        fprintf(stderr, "Comm: Did not get expected size,rank (got %d,%d)", cSize, cRank);
        return 1;
    }
    return 0;
}

MPI_Fint c2fgroup_(MPI_Fint * group)
{
    MPI_Group cGroup = MPI_Group_f2c(*group);
    int cSize, wSize, cRank, wRank;

    /* We pass in the group of comm world */
    MPI_Comm_size(MPI_COMM_WORLD, &wSize);
    MPI_Comm_rank(MPI_COMM_WORLD, &wRank);
    MPI_Group_size(cGroup, &cSize);
    MPI_Group_rank(cGroup, &cRank);

    if (wSize != cSize || wRank != cRank) {
        fprintf(stderr, "Group: Did not get expected size,rank (got %d,%d)", cSize, cRank);
        return 1;
    }
    return 0;
}

MPI_Fint c2ftype_(MPI_Fint * type)
{
    MPI_Datatype dtype = MPI_Type_f2c(*type);

    if (dtype != MPI_INTEGER) {
        fprintf(stderr, "Type: Did not get expected type\n");
        return 1;
    }
    return 0;
}

MPI_Fint c2finfo_(MPI_Fint * info)
{
    MPI_Info cInfo = MPI_Info_f2c(*info);
    int flag;
    char value[100];
    MPI_Fint errs = 0;

    MPI_Info_get(cInfo, (char *) "host", sizeof(value), value, &flag);
    if (!flag || strcmp(value, "myname") != 0) {
        fprintf(stderr, "Info: Wrong value or no value for host\n");
        errs++;
    }
    MPI_Info_get(cInfo, (char *) "wdir", sizeof(value), value, &flag);
    if (!flag || strcmp(value, "/rdir/foo") != 0) {
        fprintf(stderr, "Info: Wrong value of no value for wdir\n");
        errs++;
    }

    return errs;
}

MPI_Fint c2frequest_(MPI_Fint * request)
{
    MPI_Request req = MPI_Request_f2c(*request);
    MPI_Status status;
    int flag;
    MPI_Test(&req, &flag, &status);
    if (flag) {
        MPI_Test_cancelled(&status, &flag);
        if (!flag) {
            fprintf(stderr, "Request: Wrong value for flag\n");
            return 1;
        }
    }
    *request = MPI_Request_c2f(req);
    return 0;
}

MPI_Fint c2fop_(MPI_Fint * op)
{
    MPI_Op cOp = MPI_Op_f2c(*op);

    if (cOp != MPI_SUM) {
        fprintf(stderr, "Op: did not get sum\n");
        return 1;
    }
    return 0;
}

MPI_Fint c2ferrhandler_(MPI_Fint * errh)
{
    MPI_Errhandler errhand = MPI_Errhandler_f2c(*errh);

    if (errhand != MPI_ERRORS_RETURN) {
        fprintf(stderr, "Errhandler: did not get errors return\n");
        return 1;
    }

    return 0;
}

/*
 * The following routines provide handles to the calling Fortran program
 */
void f2ccomm_(MPI_Fint * comm)
{
    *comm = MPI_Comm_c2f(MPI_COMM_WORLD);
}

void f2cgroup_(MPI_Fint * group)
{
    MPI_Group wgroup;
    MPI_Comm_group(MPI_COMM_WORLD, &wgroup);
    *group = MPI_Group_c2f(wgroup);
}

void f2ctype_(MPI_Fint * type)
{
    *type = MPI_Type_c2f(MPI_INTEGER);
}

void f2cinfo_(MPI_Fint * info)
{
    MPI_Info cinfo;

    MPI_Info_create(&cinfo);
    MPI_Info_set(cinfo, (char *) "host", (char *) "myname");
    MPI_Info_set(cinfo, (char *) "wdir", (char *) "/rdir/foo");

    *info = MPI_Info_c2f(cinfo);
}

void f2crequest_(MPI_Fint * req)
{
    MPI_Request cReq;

    MPI_Irecv(NULL, 0, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &cReq);
    MPI_Cancel(&cReq);
    *req = MPI_Request_c2f(cReq);
}

void f2cop_(MPI_Fint * op)
{
    *op = MPI_Op_c2f(MPI_SUM);
}

void f2cerrhandler_(MPI_Fint * errh)
{
    *errh = MPI_Errhandler_c2f(MPI_ERRORS_RETURN);
}