172 строки
5.4 KiB
C
172 строки
5.4 KiB
C
|
/*
|
||
|
* 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 */
|