OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

constants.h
1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2005 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
13 * $COPYRIGHT$
14 *
15 * Additional copyrights may follow
16 *
17 * $HEADER$
18 */
19
20 #ifndef OMPI_F77_CONSTANTS_H
21 #define OMPI_F77_CONSTANTS_H
22
23 #include "ompi_config.h"
24
25 /*
26 * Several variables are used to link against MPI F77 constants which
27 * correspond to addresses, e.g. MPI_BOTTOM, and are implemented via
28 * common blocks.
29 *
30 * We use common blocks so that in the C wrapper functions, we can
31 * compare the address that comes in against known addresses (e.g., if
32 * the "status" argument in MPI_RECV is the address of the common
33 * block for the fortran equivalent of MPI_STATUS_IGNORE, then we know
34 * to pass the C MPI_STATUS_IGNORE to the C MPI_Recv function). As
35 * such, we never look at the *value* of these variables (indeed,
36 * they're never actually initialized), but instead only ever look at
37 * the *address* of these variables.
38 *
39 * As such, it is not strictly necessary that the size and type of our
40 * C variables matches that of the common Fortran block variables.
41 * However, good programming form says that we should match, so we do.
42 *
43 * Note, however, that the alignments of the Fortran common block and
44 * the C variable may not match (e.g., Intel 9.0 compilers on 64 bit
45 * platforms will put the alignment of a double on 4 bytes, but put
46 * the alignment of all common blocks on 16 bytes). This only matters
47 * (to some compilers!), however, if you initialize the C variable in
48 * the global scope. If the C global instantiation is not
49 * initialized, the compiler/linker seems to "figure it all out" and
50 * make the alignments match.
51 *
52 * Since we made the fundamental decision to support all 4 common
53 * fortran compiler symbol conventions within the same library for
54 * those compilers who support weak symbols, we need to have 4 symbols
55 * for each of the fortran address constants. As described above, we
56 * have to have known *pointer* values for the fortran addresses
57 * (e.g., MPI_STATUS_IGNORE). So when the fortran wrapper for
58 * MPI_RECV gets (MPI_Fint *status), it can check (status ==
59 * some_sentinel_value) to know that it got the Fortran equivalent of
60 * MPI_STATUS_IGNORE and therefore pass the C MPI_STATUS_IGNORE to the
61 * C MPI_Recv.
62 *
63 * We do this by having a "common" block in mpif.h:
64 *
65 * INTEGER MPI_STATUS_IGNORE(MPI_STATUS_SIZE)
66 * common /mpi_fortran_status_ignore/ MPI_STATUS_IGNORE
67 *
68 * This makes the fortran variable MPI_STATUS_IGNORE effectively be an
69 * alias for the C variable "mpi_fortran_status_ignore" -- but the C
70 * symbol name is according to the fortran compiler's naming symbol
71 * convention bais. So it could be MPI_FORTRAN_STATUS_IGNORE,
72 * mpi_fortran_status_ignore, mpi_fortran_status_ignore_, or
73 * mpi_fortran_status_ignore__.
74 *
75 * Hence, we have to have *4* C symbols for this, and them compare for
76 * all of them in the fortran MPI_RECV wrapper. :-( I can't think of
77 * any better way to do this.
78 *
79 * I'm putting these 4 comparisons in macros (on systems where we
80 * don't support the 4 symbols -- e.g., OSX, where we don't have weak
81 * symbols -- it'll only be one comparison), so if anyone things of
82 * something better than this, you should only need to modify this
83 * file.
84 */
85
86 #define DECL(type, upper_case, lower_case, single_u, double_u) \
87 OMPI_DECLSPEC extern type upper_case; \
88 OMPI_DECLSPEC extern type lower_case; \
89 OMPI_DECLSPEC extern type single_u; \
90 OMPI_DECLSPEC extern type double_u
91
92 /* Note that the rationale for the types of each of these variables is
93 discussed in ompi/include/mpif-common.h. Do not change the types
94 without also changing ompi/runtime/ompi_mpi_init.c and
95 ompi/include/mpif-common.h. */
96
97 DECL(int, MPI_FORTRAN_BOTTOM, mpi_fortran_bottom,
98 mpi_fortran_bottom_, mpi_fortran_bottom__);
99 DECL(int, MPI_FORTRAN_IN_PLACE, mpi_fortran_in_place,
100 mpi_fortran_in_place_, mpi_fortran_in_place__);
101 DECL(char *, MPI_FORTRAN_ARGV_NULL, mpi_fortran_argv_null,
102 mpi_fortran_argv_null_, mpi_fortran_argv_null__);
103 DECL(double, MPI_FORTRAN_ARGVS_NULL, mpi_fortran_argvs_null,
104 mpi_fortran_argvs_null_, mpi_fortran_argvs_null__);
105 DECL(int *, MPI_FORTRAN_ERRCODES_IGNORE, mpi_fortran_errcodes_ignore,
106 mpi_fortran_errcodes_ignore_, mpi_fortran_errcodes_ignore__);
107 DECL(int *, MPI_FORTRAN_STATUS_IGNORE, mpi_fortran_status_ignore,
108 mpi_fortran_status_ignore_, mpi_fortran_status_ignore__);
109 DECL(double, MPI_FORTRAN_STATUSES_IGNORE, mpi_fortran_statuses_ignore,
110 mpi_fortran_statuses_ignore_, mpi_fortran_statuses_ignore__);
111
112 /*
113 * Create macros to do the checking. Only check for all 4 if we have
114 * weak symbols. Otherwise, just check for the one relevant symbol.
115 */
116 #if OPAL_HAVE_WEAK_SYMBOLS
117 #define OMPI_IS_FORTRAN_BOTTOM(addr) \
118 (addr == (void*) &MPI_FORTRAN_BOTTOM || \
119 addr == (void*) &mpi_fortran_bottom || \
120 addr == (void*) &mpi_fortran_bottom_ || \
121 addr == (void*) &mpi_fortran_bottom__)
122 #define OMPI_IS_FORTRAN_IN_PLACE(addr) \
123 (addr == (void*) &MPI_FORTRAN_IN_PLACE || \
124 addr == (void*) &mpi_fortran_in_place || \
125 addr == (void*) &mpi_fortran_in_place_ || \
126 addr == (void*) &mpi_fortran_in_place__)
127 #define OMPI_IS_FORTRAN_ARGV_NULL(addr) \
128 (addr == (void*) &MPI_FORTRAN_ARGV_NULL || \
129 addr == (void*) &mpi_fortran_argv_null || \
130 addr == (void*) &mpi_fortran_argv_null_ || \
131 addr == (void*) &mpi_fortran_argv_null__)
132 #define OMPI_IS_FORTRAN_ARGVS_NULL(addr) \
133 (addr == (void*) &MPI_FORTRAN_ARGVS_NULL || \
134 addr == (void*) &mpi_fortran_argvs_null || \
135 addr == (void*) &mpi_fortran_argvs_null_ || \
136 addr == (void*) &mpi_fortran_argvs_null__)
137 #define OMPI_IS_FORTRAN_ERRCODES_IGNORE(addr) \
138 (addr == (void*) &MPI_FORTRAN_ERRCODES_IGNORE || \
139 addr == (void*) &mpi_fortran_errcodes_ignore || \
140 addr == (void*) &mpi_fortran_errcodes_ignore_ || \
141 addr == (void*) &mpi_fortran_errcodes_ignore__)
142 #define OMPI_IS_FORTRAN_STATUS_IGNORE(addr) \
143 (addr == (void*) &MPI_FORTRAN_STATUS_IGNORE || \
144 addr == (void*) &mpi_fortran_status_ignore || \
145 addr == (void*) &mpi_fortran_status_ignore_ || \
146 addr == (void*) &mpi_fortran_status_ignore__)
147 #define OMPI_IS_FORTRAN_STATUSES_IGNORE(addr) \
148 (addr == (void*) &MPI_FORTRAN_STATUSES_IGNORE || \
149 addr == (void*) &mpi_fortran_statuses_ignore || \
150 addr == (void*) &mpi_fortran_statuses_ignore_ || \
151 addr == (void*) &mpi_fortran_statuses_ignore__)
152
153 #elif OMPI_F77_CAPS
154 #define OMPI_IS_FORTRAN_BOTTOM(addr) \
155 (addr == (void*) &MPI_FORTRAN_BOTTOM)
156 #define OMPI_IS_FORTRAN_IN_PLACE(addr) \
157 (addr == (void*) &MPI_FORTRAN_IN_PLACE)
158 #define OMPI_IS_FORTRAN_ARGV_NULL(addr) \
159 (addr == (void*) &MPI_FORTRAN_ARGV_NULL)
160 #define OMPI_IS_FORTRAN_ARGVS_NULL(addr) \
161 (addr == (void*) &MPI_FORTRAN_ARGVS_NULL)
162 #define OMPI_IS_FORTRAN_ERRCODES_IGNORE(addr) \
163 (addr == (void*) &MPI_FORTRAN_ERRCODES_IGNORE)
164 #define OMPI_IS_FORTRAN_STATUS_IGNORE(addr) \
165 (addr == (void*) &MPI_FORTRAN_STATUS_IGNORE)
166 #define OMPI_IS_FORTRAN_STATUSES_IGNORE(addr) \
167 (addr == (void*) &MPI_FORTRAN_STATUSES_IGNORE)
168
169 #elif OMPI_F77_PLAIN
170 #define OMPI_IS_FORTRAN_BOTTOM(addr) \
171 (addr == (void*) &mpi_fortran_bottom)
172 #define OMPI_IS_FORTRAN_IN_PLACE(addr) \
173 (addr == (void*) &mpi_fortran_in_place)
174 #define OMPI_IS_FORTRAN_ARGV_NULL(addr) \
175 (addr == (void*) &mpi_fortran_argv_null)
176 #define OMPI_IS_FORTRAN_ARGVS_NULL(addr) \
177 (addr == (void*) &mpi_fortran_argvs_null)
178 #define OMPI_IS_FORTRAN_ERRCODES_IGNORE(addr) \
179 (addr == (void*) &mpi_fortran_errcodes_ignore)
180 #define OMPI_IS_FORTRAN_STATUS_IGNORE(addr) \
181 (addr == (void*) &mpi_fortran_status_ignore)
182 #define OMPI_IS_FORTRAN_STATUSES_IGNORE(addr) \
183 (addr == (void*) &mpi_fortran_statuses_ignore)
184
185 #elif OMPI_F77_SINGLE_UNDERSCORE
186 #define OMPI_IS_FORTRAN_BOTTOM(addr) \
187 (addr == (void*) &mpi_fortran_bottom_)
188 #define OMPI_IS_FORTRAN_IN_PLACE(addr) \
189 (addr == (void*) &mpi_fortran_in_place_)
190 #define OMPI_IS_FORTRAN_ARGV_NULL(addr) \
191 (addr == (void*) &mpi_fortran_argv_null_)
192 #define OMPI_IS_FORTRAN_ARGVS_NULL(addr) \
193 (addr == (void*) &mpi_fortran_argvs_null_)
194 #define OMPI_IS_FORTRAN_ERRCODES_IGNORE(addr) \
195 (addr == (void*) &mpi_fortran_errcodes_ignore_)
196 #define OMPI_IS_FORTRAN_STATUS_IGNORE(addr) \
197 (addr == (void*) &mpi_fortran_status_ignore_)
198 #define OMPI_IS_FORTRAN_STATUSES_IGNORE(addr) \
199 (addr == (void*) &mpi_fortran_statuses_ignore_)
200
201 #else
202 #define OMPI_IS_FORTRAN_BOTTOM(addr) \
203 (addr == (void*) &mpi_fortran_bottom__)
204 #define OMPI_IS_FORTRAN_IN_PLACE(addr) \
205 (addr == (void*) &mpi_fortran_in_place__)
206 #define OMPI_IS_FORTRAN_ARGV_NULL(addr) \
207 (addr == (void*) &mpi_fortran_argv_null__)
208 #define OMPI_IS_FORTRAN_ARGVS_NULL(addr) \
209 (addr == (void*) &mpi_fortran_argvs_null__)
210 #define OMPI_IS_FORTRAN_ERRCODES_IGNORE(addr) \
211 (addr == (void*) &mpi_fortran_errcodes_ignore__)
212 #define OMPI_IS_FORTRAN_STATUS_IGNORE(addr) \
213 (addr == (void*) &mpi_fortran_status_ignore__)
214 #define OMPI_IS_FORTRAN_STATUSES_IGNORE(addr) \
215 (addr == (void*) &mpi_fortran_statuses_ignore__)
216
217 #endif /* weak / specific symbol type */
218
219 /* Convert between Fortran and C MPI_BOTTOM */
220 #define OMPI_F2C_BOTTOM(addr) (OMPI_IS_FORTRAN_BOTTOM(addr) ? MPI_BOTTOM : (addr))
221 #define OMPI_F2C_IN_PLACE(addr) (OMPI_IS_FORTRAN_IN_PLACE(addr) ? MPI_IN_PLACE : (addr))
222
223 #endif /* OMPI_F77_CONSTANTS_H */