Skip to content

Commit

Permalink
fortran/use-mpi-f08: add support for Fortran 2018 ISO_Fortran_binding.h
Browse files Browse the repository at this point in the history
Signed-off-by: Gilles Gouaillardet <[email protected]>
  • Loading branch information
ggouaillardet authored and jtronge committed Jul 30, 2024
1 parent 2935f92 commit 79c6e22
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 18 deletions.
2 changes: 2 additions & 0 deletions config/ompi_config_files.m4
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ AC_DEFUN([OMPI_CONFIG_FILES],[
ompi/mpi/fortran/use-mpi-f08/Makefile
ompi/mpi/fortran/use-mpi-f08/base/Makefile
ompi/mpi/fortran/use-mpi-f08/bindings/Makefile
ompi/mpi/fortran/use-mpi-f08/ts/Makefile
ompi/mpi/fortran/use-mpi-f08/mod/Makefile
ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-interfaces.h
ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-rename.h
ompi/mpi/fortran/mpiext-use-mpi/Makefile
ompi/mpi/fortran/mpiext-use-mpi-f08/Makefile
ompi/mpi/bindings/ompi_bindings/compiler.py
Expand Down
19 changes: 6 additions & 13 deletions config/ompi_setup_mpi_fortran.m4
Original file line number Diff line number Diff line change
Expand Up @@ -460,16 +460,9 @@ end program]])],

# We need to have ignore TKR or the ISO Fortran bindings functionality to build the mpi_f08
# module
AS_IF([test $OMPI_TRY_FORTRAN_BINDINGS -ge $OMPI_FORTRAN_USEMPIF08_BINDINGS],
[AS_IF([test $OMPI_FORTRAN_HAVE_IGNORE_TKR -eq 1],
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS
OMPI_FORTRAN_F08_PREDECL=$OMPI_FORTRAN_IGNORE_TKR_PREDECL
OMPI_FORTRAN_F08_TYPE=$OMPI_FORTRAN_IGNORE_TKR_TYPE
])
AS_IF([test $OMPI_FORTRAN_HAVE_TS -eq 1],
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS
OMPI_MPI_SUBARRAYS_SUPPORTED=.true.
OMPI_MPI_ASYNC_PROTECTS_NONBLOCKING=.true.])])
AS_IF([test $OMPI_TRY_FORTRAN_BINDINGS -ge $OMPI_FORTRAN_USEMPIF08_BINDINGS && \
test $OMPI_FORTRAN_HAVE_IGNORE_TKR -eq 1],
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS])

# The overall "_BIND_C" variable will be set to 1 if we have all
# the necessary forms of BIND(C)
Expand Down Expand Up @@ -667,7 +660,7 @@ end type test_mpi_handle],
AS_IF([test $OMPI_MIN_REQUIRED_FORTRAN_BINDINGS -gt $OMPI_BUILD_FORTRAN_BINDINGS],
[AC_MSG_ERROR([Cannot build requested Fortran bindings, aborting])])

dnl AC_CONFIG_FILES([ompi/mpi/fortran/use-mpi-f08/bindings/mpi-f-interfaces-bind.h])
AC_CONFIG_FILES([ompi/mpi/fortran/use-mpi-f08/bindings/mpi-f-interfaces-bind.h])

# -------------------
# mpif.h final setup
Expand Down Expand Up @@ -899,11 +892,11 @@ end type test_mpi_handle],

AS_IF([test $OMPI_FORTRAN_HAVE_TS -eq 1],
[OMPI_F08_IGNORE_TKR_TYPE="type(*), dimension(..)"
OMPI_F08_IGNORE_TKR_PREDECL="no attribute required for"
OMPI_F08_IGNORE_TKR_PREDECL="! no attribute required for"
OMPI_F08_BINDINGS_EXTENSION="ts"
OMPI_F08_BINDINGS_TS_SUFFIX="ts"],
[OMPI_F08_IGNORE_TKR_TYPE=$OMPI_FORTRAN_IGNORE_TKR_TYPE
OMPI_F08_IGNORE_TKR_PREDECL=${OMPI_FORTRAN_IGNORE_TKR_PREDECL:1}
OMPI_F08_IGNORE_TKR_PREDECL=$OMPI_FORTRAN_IGNORE_TKR_PREDECL
OMPI_F08_BINDINGS_EXTENSION="f"
OMPI_F08_BINDINGS_TS_SUFFIX=""])
AC_SUBST(OMPI_F08_BINDINGS_EXTENSION)
Expand Down
2 changes: 2 additions & 0 deletions ompi/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ SUBDIRS = \
mpi/fortran/use-mpi-f08/base \
mpi/fortran/use-mpi-f08/mod \
mpi/fortran/use-mpi-f08/bindings \
mpi/fortran/use-mpi-f08/ts \
$(OMPI_MPIEXT_USEMPIF08_DIRS) \
mpi/fortran/use-mpi-f08 \
mpi/fortran/mpiext-use-mpi-f08 \
Expand Down Expand Up @@ -120,6 +121,7 @@ DIST_SUBDIRS = \
mpi/fortran/use-mpi-f08/base \
mpi/fortran/use-mpi-f08/mod \
mpi/fortran/use-mpi-f08/bindings \
mpi/fortran/use-mpi-f08/ts \
mpi/fortran/mpiext-use-mpi-f08 \
mpi/java \
$(OMPI_MPIEXT_ALL_SUBDIRS) \
Expand Down
17 changes: 15 additions & 2 deletions ompi/mpi/fortran/configure-fortran-output.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,23 @@
! Line 2 of the ignore TKR syntax
#define OMPI_FORTRAN_IGNORE_TKR_TYPE @OMPI_FORTRAN_IGNORE_TKR_TYPE@
! f08 TKR syntax (w/o TS 29113)
#define OMPI_F08_IGNORE_TKR_PREDECL @OMPI_F08_IGNORE_TKR_PREDECL@
! The Fortran ISO C type type(*), dimension(..) is not (yet) supported by all compilers.
! If it is supported, OMPI_F08_IGNORE_TKR_TYPE will be type(*), dimension(..).
! Otherwise, it will be the same value as OMPI_FORTRAN_IGNORE_TKR_TYPE.
#define OMPI_F08_IGNORE_TKR_TYPE @OMPI_F08_IGNORE_TKR_TYPE@
! If the Fortran compiler supports type(*), dimension(..), this macro will be "_desc"
! so that the F08 descriptor-enabled Open MPI Fortran back-end functions are invoked.
! Otherwise, it will be "_f" so that the non-F08-descriptor Open MPI Fortran back-end functions are invoked.
#define OMPI_F08_BINDINGS_EXTENSION @OMPI_F08_BINDINGS_EXTENSION@
! If the Fortran compiler supports type(*), dimension(..), this macro will be empty
! (i.e., we do not want to ignore the TKR of the buf parameter).
! Otherwise, it will be set to !GCC$ ATTRIBUTES NO_ARG_CHECK :: buf so that the GCC compiler
! (and related compilers, such as the Intel compiler) will ignore the TKR of the buf dummy argument.
#define OMPI_F08_GCC_ATTRIBUTES(buf) @OMPI_F08_GCC_ATTRIBUTES@
#define OMPI_FORTRAN_BUILD_SIZEOF @OMPI_FORTRAN_BUILD_SIZEOF@
! Integers
Expand Down
11 changes: 9 additions & 2 deletions ompi/mpi/fortran/use-mpi-f08/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ AM_CPPFLAGS =
# MPI bindings.
if OMPI_BUILD_FORTRAN_USEMPIF08_BINDINGS

AM_FCFLAGS = -I$(top_srcdir)/ompi/mpi/fortran/use-mpi-f08/mod \
-I$(top_builddir)/ompi/include \
AM_FCFLAGS = -I$(top_builddir)/ompi/include \
-I$(top_srcdir)/ompi/include \
$(OMPI_FC_MODULE_FLAG)$(top_builddir)/ompi/mpi/fortran/use-mpi \
$(OMPI_FC_MODULE_FLAG)$(top_builddir)/ompi/$(OMPI_FORTRAN_USEMPI_DIR) \
Expand Down Expand Up @@ -541,6 +540,14 @@ lib@OMPI_LIBMPI_NAME@_usempif08_la_DEPENDENCIES = \
lib@OMPI_LIBMPI_NAME@_usempif08_profile.la
lib@OMPI_LIBMPI_NAME@_usempif08_la_LDFLAGS = -version-info $(libmpi_usempif08_so_version)

if OMPI_FORTRAN_HAVE_TS
lib@OMPI_LIBMPI_NAME@_usempif08_la_LIBADD += \
ts/libusempif08_ts.la

lib@OMPI_LIBMPI_NAME@_usempif08_la_DEPENDENCIES += \
ts/libusempif08_ts.la
endif

#
# Automake doesn't do Fortran dependency analysis, so must list them
# manually here. Bummer!
Expand Down
1 change: 0 additions & 1 deletion ompi/mpi/fortran/use-mpi-f08/ts/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@ void ompi_ssend_init_ts(CFI_cdesc_t* x, MPI_Fint *count, MPI_Fint *datatype,

void ompi_get_address_ts(CFI_cdesc_t *x, MPI_Aint *address, MPI_Fint *ierr);

<<<<<<< HEAD
void ompi_pack_ts(CFI_cdesc_t* x1, MPI_Fint *incount, MPI_Fint *datatype,
CFI_cdesc_t* x2, MPI_Fint *outsize, MPI_Fint *position,
MPI_Fint *comm, MPI_Fint *ierr);
Expand Down
94 changes: 94 additions & 0 deletions ompi/mpi/fortran/use-mpi-f08/ts/ts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2014 Argonne National Laboratory.
* Copyright (c) 2019 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/

#include "ts.h"

#include <assert.h>

int ompi_ts_create_datatype(CFI_cdesc_t *cdesc, int oldcount, MPI_Datatype oldtype, MPI_Datatype *newtype)
{
const int MAX_RANK = 15; /* Fortran 2008 specifies a maximum rank of 15 */
MPI_Datatype types[MAX_RANK + 1]; /* Use a fixed size array to avoid malloc. + 1 for oldtype */
int mpi_errno = MPI_SUCCESS;
int accum_elems = 1;
int accum_sm = cdesc->elem_len;
int done = 0; /* Have we created a datatype for oldcount of oldtype? */
int last; /* Index of the last successfully created datatype in types[] */
int extent;
int i, j;

#ifdef OPAL_ENABLE_DEBUG
{
size_t size;
assert(cdesc->rank <= MAX_RANK);
ompi_datatype_type_size(oldtype, &size);
/* When cdesc->elem_len != size, things suddenly become complicated. Generally, it is hard to create
* a composite datatype based on two datatypes. Currently we don't support it and doubt it is usefull.
*/
assert(cdesc->elem_len == size);
}
#endif

types[0] = oldtype;
i = 0;
done = 0;
while (i < cdesc->rank && !done) {
if (oldcount % accum_elems) {
/* oldcount should be a multiple of accum_elems, otherwise we might need an
* MPI indexed datatype to describle the irregular region, which is not supported yet.
*/
mpi_errno = MPI_ERR_INTERN;
last = i;
goto fn_exit;
}

extent = oldcount / accum_elems;
if (extent > cdesc->dim[i].extent) {
extent = cdesc->dim[i].extent;
} else {
/* Up to now, we have accumlated enough elements */
done = 1;
}

if (cdesc->dim[i].sm == accum_sm) {
mpi_errno = PMPI_Type_contiguous(extent, types[i], &types[i+1]);
} else {
mpi_errno = PMPI_Type_create_hvector(extent, 1, cdesc->dim[i].sm, types[i], &types[i+1]);
}
if (mpi_errno != MPI_SUCCESS) {
last = i;
goto fn_exit;
}

accum_sm = cdesc->dim[i].sm * cdesc->dim[i].extent;
accum_elems *= cdesc->dim[i].extent;
i++;
}

if (done) {
*newtype = types[i];
MPI_Type_commit(newtype);
last = i - 1; /* To avoid freeing newtype */
} else {
/* If # of elements given by "oldcount oldtype" is bigger than
* what cdesc describles, then we will reach here.
*/
last = i;
mpi_errno = MPI_ERR_ARG;
goto fn_exit;
}

fn_exit:
for (j = 1; j <= last; j++)
PMPI_Type_free(&types[j]);
return mpi_errno;
}
48 changes: 48 additions & 0 deletions ompi/mpi/fortran/use-mpi-f08/ts/ts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2014 Argonne National Laboratory.
* Copyright (c) 2019 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/

#include "ompi_config.h"

#include <ISO_Fortran_binding.h>

#include "ompi/datatype/ompi_datatype.h"
#include "ompi/mpi/fortran/base/fint_2_int.h"

extern int ompi_ts_create_datatype(CFI_cdesc_t *cdesc, int oldcount, MPI_Datatype oldtype, MPI_Datatype *newtype);

#define OMPI_CFI_2_C(x, count, type, datatype, rc) \
do { \
datatype = type; \
if (x->rank != 0 && !CFI_is_contiguous(x)) { \
rc = ompi_ts_create_datatype(x, count, type, &datatype); \
if (MPI_SUCCESS != rc) { \
return; \
} else { \
count = 1; \
} \
} else { \
rc = MPI_SUCCESS; \
} \
} while (0)

#define OMPI_CFI_IS_CONTIGUOUS(x) \
(0 == x->rank || CFI_is_contiguous(x))

#define OMPI_CFI_CHECK_CONTIGUOUS(x, rc) \
do { \
if (OMPI_CFI_IS_CONTIGUOUS(x)) { \
rc = MPI_SUCCESS; \
} else { \
rc = MPI_ERR_INTERN; \
} \
} while (0)

0 comments on commit 79c6e22

Please sign in to comment.