File: status-conversion.h

package info (click to toggle)
openmpi 5.0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 202,312 kB
  • sloc: ansic: 612,441; makefile: 42,495; sh: 11,230; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,154; python: 1,856; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (171 lines) | stat: -rw-r--r-- 5,493 bytes parent folder | download | duplicates (6)
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
/*
 * Copyright (c) 2012      Oracle and/or its affiliates.  All rights reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 */

#ifndef OMPI_FORTRAN_STATUS_CONVERSION_H
#define OMPI_FORTRAN_STATUS_CONVERSION_H

#include "ompi_config.h"
#include "mpi.h"

/*
 * A Fortran MPI_STATUS argument and a C MPI_Status argument can differ.
 * Therefore, the Fortran layer converts between Fortran and C statuses
 * using the MPI_Status_[f2c|c2f] functions:
 *
 *   void Fortran_api(... MPI_Fint *status ...)
 *   {
 *       int c_ierr;
 *       MPI_Status   c_status;
 *       MPI_Status_f2c(status, &c_status);
 *       c_ierr = C_api(... &c_status ...);
 *       MPI_Status_c2f(&c_status, status);
 *   }
 *
 * The macros we define below support a different approach that avoids
 * the overhead of conversion in cases where we can detect that the
 * Fortran status can be used directly:
 *
 *   void Fortran_api(... MPI_Fint *status ...)
 *   {
 *       int c_ierr;
 *       OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2)
 *       OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status)
 *       c_ierr = C_api(... c_status ...);
 *       OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
 *   }
 *
 * Issues around whether a Fortran status can be used directly by
 * OMPI C internals are discussed in trac tickets 2526 and 3218 as
 * well as ompi/mpi/c/status_c2f.c.  The issues include:
 *
 * - A Fortran status must be large enough to hold a C status.
 *   This requirement is always satisfied by the configure-time
 *   determination of the Fortran parameter MPI_STATUS_SIZE.
 *
 * - A Fortran INTEGER should be the same size as a C int so
 *   that components indicated by MPI_SOURCE, MPI_TAG, and
 *   MPI_ERROR can be addressed properly from either language.
 *
 * - A Fortran status must be aligned such that all C status
 *   struct components have proper alignment.  The Fortran
 *   status alignment is only guaranteed to be suitable for
 *   Fortran INTEGERs.  The C status requires alignment for a
 *   size_t component.  We utilize two tests:
 *
 *   - Check if Fortran INTEGER alignment matches size_t alignment.
 *     This check is not necessary, but it is sufficient and can be
 *     assessed at compile time.
 *
 *   - Check if the particular Fortran status pointer provided by
 *     the user has suitable alignment.  This check is both necessary
 *     and sufficient, but must be conducted at run time.
 *
 *   These alignment issues are taken into consideration only
 *   for 64-bit SPARC runs, which is where these issues have
 *   been visible.
 */


/*
 * First, we have two preliminary checks:
 * - OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
 *     is sufficient, but not necessary
 *     can be evaluated at compile time
 * - OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status)
 *     is sufficient and necessary
 *     must be evaluated at run time
 * If check #1 is false at compile time, then check #2 will always be false at run time.
 * The compile-time check is used to conditionalize compilation of references to c_status2.
 */


#if defined(__sparc) && SIZEOF_SIZE_T == 8
#define OMPI_FORTRAN_STATUS_NEED_CONVERSION_1 \
  ((OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT) || \
   (OMPI_ALIGNMENT_FORTRAN_INTEGER!=OPAL_ALIGNMENT_SIZE_T))
#else
#define OMPI_FORTRAN_STATUS_NEED_CONVERSION_1 \
   (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT)
#endif


#if defined(__sparc) && SIZEOF_SIZE_T == 8
#define OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) \
  ( \
    (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT) \
    || \
    ( \
      (OMPI_ALIGNMENT_FORTRAN_INTEGER!=OPAL_ALIGNMENT_SIZE_T) \
      && \
      (((ulong) (status)) & (OPAL_ALIGNMENT_SIZE_T-1)) \
    ) \
  )
#else
#define OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) \
   (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT)
#endif


/*
 * Now, the macros:
 * - OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2)
 * - OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status)
 * - OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
 */


#if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
#define OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2) MPI_Status *c_status, c_status2;
#else
#define OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2) MPI_Status *c_status;
#endif


#if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
#define OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status) \
  do { \
      if (OMPI_IS_FORTRAN_STATUS_IGNORE(status)) { \
          c_status = MPI_STATUS_IGNORE; \
      } else { \
          if ( OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) ) { \
              c_status = &c_status2; \
          } else { \
              c_status = (MPI_Status *) status; \
          } \
      } \
  } while (0);
#else
#define OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status) \
  do { \
      if (OMPI_IS_FORTRAN_STATUS_IGNORE(status)) { \
          c_status = MPI_STATUS_IGNORE; \
      } else { \
          c_status = (MPI_Status *) status; \
      } \
  } while (0);
#endif


#if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
#define OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr) \
  do { \
      if ( \
          OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) && \
          MPI_SUCCESS == c_ierr && \
          MPI_STATUS_IGNORE != c_status ) \
      { \
          MPI_Status_c2f(c_status, status); \
      } \
  } while (0);
#else
#define OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
#endif


#endif /* OMPI_FORTRAN_STATUS_CONVERSION_H */