root/ompi/mpi/fortran/mpif-h/status-conversion.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * Copyright (c) 2012      Oracle and/or its affiliates.  All rights reserved.
   3  * $COPYRIGHT$
   4  *
   5  * Additional copyrights may follow
   6  *
   7  * $HEADER$
   8  */
   9 
  10 #ifndef OMPI_FORTRAN_STATUS_CONVERSION_H
  11 #define OMPI_FORTRAN_STATUS_CONVERSION_H
  12 
  13 #include "ompi_config.h"
  14 #include "mpi.h"
  15 
  16 /*
  17  * A Fortran MPI_STATUS argument and a C MPI_Status argument can differ.
  18  * Therefore, the Fortran layer converts between Fortran and C statuses
  19  * using the MPI_Status_[f2c|c2f] functions:
  20  *
  21  *   void Fortran_api(... MPI_Fint *status ...)
  22  *   {
  23  *       int c_ierr;
  24  *       MPI_Status   c_status;
  25  *       MPI_Status_f2c(status, &c_status);
  26  *       c_ierr = C_api(... &c_status ...);
  27  *       MPI_Status_c2f(&c_status, status);
  28  *   }
  29  *
  30  * The macros we define below support a different approach that avoids
  31  * the overhead of conversion in cases where we can detect that the
  32  * Fortran status can be used directly:
  33  *
  34  *   void Fortran_api(... MPI_Fint *status ...)
  35  *   {
  36  *       int c_ierr;
  37  *       OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2)
  38  *       OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status)
  39  *       c_ierr = C_api(... c_status ...);
  40  *       OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
  41  *   }
  42  *
  43  * Issues around whether a Fortran status can be used directly by
  44  * OMPI C internals are discussed in trac tickets 2526 and 3218 as
  45  * well as ompi/mpi/c/status_c2f.c.  The issues include:
  46  *
  47  * - A Fortran status must be large enough to hold a C status.
  48  *   This requirement is always satisfied by the configure-time
  49  *   determination of the Fortran parameter MPI_STATUS_SIZE.
  50  *
  51  * - A Fortran INTEGER should be the same size as a C int so
  52  *   that components indicated by MPI_SOURCE, MPI_TAG, and
  53  *   MPI_ERROR can be addressed properly from either language.
  54  *
  55  * - A Fortran status must be aligned such that all C status
  56  *   struct components have proper alignment.  The Fortran
  57  *   status alignment is only guaranteed to be suitable for
  58  *   Fortran INTEGERs.  The C status requires alignment for a
  59  *   size_t component.  We utilize two tests:
  60  *
  61  *   - Check if Fortran INTEGER alignment matches size_t alignment.
  62  *     This check is not necessary, but it is sufficient and can be
  63  *     assessed at compile time.
  64  *
  65  *   - Check if the particular Fortran status pointer provided by
  66  *     the user has suitable alignment.  This check is both necessary
  67  *     and sufficient, but must be conducted at run time.
  68  *
  69  *   These alignment issues are taken into consideration only
  70  *   for 64-bit SPARC runs, which is where these issues have
  71  *   been visible.
  72  */
  73 
  74 
  75 /*
  76  * First, we have two preliminary checks:
  77  * - OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
  78  *     is sufficient, but not necessary
  79  *     can be evaluated at compile time
  80  * - OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status)
  81  *     is sufficient and necessary
  82  *     must be evaluated at run time
  83  * If check #1 is false at compile time, then check #2 will always be false at run time.
  84  * The compile-time check is used to conditionalize compilation of references to c_status2.
  85  */
  86 
  87 
  88 #if defined(__sparc) && SIZEOF_SIZE_T == 8
  89 #define OMPI_FORTRAN_STATUS_NEED_CONVERSION_1 \
  90   ((OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT) || \
  91    (OMPI_ALIGNMENT_FORTRAN_INTEGER!=OPAL_ALIGNMENT_SIZE_T))
  92 #else
  93 #define OMPI_FORTRAN_STATUS_NEED_CONVERSION_1 \
  94    (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT)
  95 #endif
  96 
  97 
  98 #if defined(__sparc) && SIZEOF_SIZE_T == 8
  99 #define OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) \
 100   ( \
 101     (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT) \
 102     || \
 103     ( \
 104       (OMPI_ALIGNMENT_FORTRAN_INTEGER!=OPAL_ALIGNMENT_SIZE_T) \
 105       && \
 106       (((ulong) (status)) & (OPAL_ALIGNMENT_SIZE_T-1)) \
 107     ) \
 108   )
 109 #else
 110 #define OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) \
 111    (OMPI_SIZEOF_FORTRAN_INTEGER!=SIZEOF_INT)
 112 #endif
 113 
 114 
 115 /*
 116  * Now, the macros:
 117  * - OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2)
 118  * - OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status)
 119  * - OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
 120  */
 121 
 122 
 123 #if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
 124 #define OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2) MPI_Status *c_status, c_status2;
 125 #else
 126 #define OMPI_FORTRAN_STATUS_DECLARATION(c_status,c_status2) MPI_Status *c_status;
 127 #endif
 128 
 129 
 130 #if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
 131 #define OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status) \
 132   do { \
 133       if (OMPI_IS_FORTRAN_STATUS_IGNORE(status)) { \
 134           c_status = MPI_STATUS_IGNORE; \
 135       } else { \
 136           if ( OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) ) { \
 137               c_status = &c_status2; \
 138           } else { \
 139               c_status = (MPI_Status *) status; \
 140           } \
 141       } \
 142   } while (0);
 143 #else
 144 #define OMPI_FORTRAN_STATUS_SET_POINTER(c_status,c_status2,status) \
 145   do { \
 146       if (OMPI_IS_FORTRAN_STATUS_IGNORE(status)) { \
 147           c_status = MPI_STATUS_IGNORE; \
 148       } else { \
 149           c_status = (MPI_Status *) status; \
 150       } \
 151   } while (0);
 152 #endif
 153 
 154 
 155 #if OMPI_FORTRAN_STATUS_NEED_CONVERSION_1
 156 #define OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr) \
 157   do { \
 158       if ( \
 159           OMPI_FORTRAN_STATUS_NEED_CONVERSION_2(status) && \
 160           MPI_SUCCESS == c_ierr && \
 161           MPI_STATUS_IGNORE != c_status ) \
 162       { \
 163           MPI_Status_c2f(c_status, status); \
 164       } \
 165   } while (0);
 166 #else
 167 #define OMPI_FORTRAN_STATUS_RETURN(c_status,c_status2,status,c_ierr)
 168 #endif
 169 
 170 
 171 #endif /* OMPI_FORTRAN_STATUS_CONVERSION_H */

/* [<][>][^][v][top][bottom][index][help] */