Skip to content

Commit 79c6e22

Browse files
ggouaillardetjtronge
authored andcommitted
fortran/use-mpi-f08: add support for Fortran 2018 ISO_Fortran_binding.h
Signed-off-by: Gilles Gouaillardet <gilles@rist.or.jp>
1 parent 2935f92 commit 79c6e22

File tree

8 files changed

+176
-18
lines changed

8 files changed

+176
-18
lines changed

config/ompi_config_files.m4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ AC_DEFUN([OMPI_CONFIG_FILES],[
4242
ompi/mpi/fortran/use-mpi-f08/Makefile
4343
ompi/mpi/fortran/use-mpi-f08/base/Makefile
4444
ompi/mpi/fortran/use-mpi-f08/bindings/Makefile
45+
ompi/mpi/fortran/use-mpi-f08/ts/Makefile
4546
ompi/mpi/fortran/use-mpi-f08/mod/Makefile
4647
ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-interfaces.h
48+
ompi/mpi/fortran/use-mpi-f08/mod/mpi-f08-rename.h
4749
ompi/mpi/fortran/mpiext-use-mpi/Makefile
4850
ompi/mpi/fortran/mpiext-use-mpi-f08/Makefile
4951
ompi/mpi/bindings/ompi_bindings/compiler.py

config/ompi_setup_mpi_fortran.m4

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -460,16 +460,9 @@ end program]])],
460460

461461
# We need to have ignore TKR or the ISO Fortran bindings functionality to build the mpi_f08
462462
# module
463-
AS_IF([test $OMPI_TRY_FORTRAN_BINDINGS -ge $OMPI_FORTRAN_USEMPIF08_BINDINGS],
464-
[AS_IF([test $OMPI_FORTRAN_HAVE_IGNORE_TKR -eq 1],
465-
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS
466-
OMPI_FORTRAN_F08_PREDECL=$OMPI_FORTRAN_IGNORE_TKR_PREDECL
467-
OMPI_FORTRAN_F08_TYPE=$OMPI_FORTRAN_IGNORE_TKR_TYPE
468-
])
469-
AS_IF([test $OMPI_FORTRAN_HAVE_TS -eq 1],
470-
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS
471-
OMPI_MPI_SUBARRAYS_SUPPORTED=.true.
472-
OMPI_MPI_ASYNC_PROTECTS_NONBLOCKING=.true.])])
463+
AS_IF([test $OMPI_TRY_FORTRAN_BINDINGS -ge $OMPI_FORTRAN_USEMPIF08_BINDINGS && \
464+
test $OMPI_FORTRAN_HAVE_IGNORE_TKR -eq 1],
465+
[OMPI_BUILD_FORTRAN_BINDINGS=$OMPI_FORTRAN_USEMPIF08_BINDINGS])
473466

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

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

672665
# -------------------
673666
# mpif.h final setup
@@ -899,11 +892,11 @@ end type test_mpi_handle],
899892

900893
AS_IF([test $OMPI_FORTRAN_HAVE_TS -eq 1],
901894
[OMPI_F08_IGNORE_TKR_TYPE="type(*), dimension(..)"
902-
OMPI_F08_IGNORE_TKR_PREDECL="no attribute required for"
895+
OMPI_F08_IGNORE_TKR_PREDECL="! no attribute required for"
903896
OMPI_F08_BINDINGS_EXTENSION="ts"
904897
OMPI_F08_BINDINGS_TS_SUFFIX="ts"],
905898
[OMPI_F08_IGNORE_TKR_TYPE=$OMPI_FORTRAN_IGNORE_TKR_TYPE
906-
OMPI_F08_IGNORE_TKR_PREDECL=${OMPI_FORTRAN_IGNORE_TKR_PREDECL:1}
899+
OMPI_F08_IGNORE_TKR_PREDECL=$OMPI_FORTRAN_IGNORE_TKR_PREDECL
907900
OMPI_F08_BINDINGS_EXTENSION="f"
908901
OMPI_F08_BINDINGS_TS_SUFFIX=""])
909902
AC_SUBST(OMPI_F08_BINDINGS_EXTENSION)

ompi/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ SUBDIRS = \
8888
mpi/fortran/use-mpi-f08/base \
8989
mpi/fortran/use-mpi-f08/mod \
9090
mpi/fortran/use-mpi-f08/bindings \
91+
mpi/fortran/use-mpi-f08/ts \
9192
$(OMPI_MPIEXT_USEMPIF08_DIRS) \
9293
mpi/fortran/use-mpi-f08 \
9394
mpi/fortran/mpiext-use-mpi-f08 \
@@ -120,6 +121,7 @@ DIST_SUBDIRS = \
120121
mpi/fortran/use-mpi-f08/base \
121122
mpi/fortran/use-mpi-f08/mod \
122123
mpi/fortran/use-mpi-f08/bindings \
124+
mpi/fortran/use-mpi-f08/ts \
123125
mpi/fortran/mpiext-use-mpi-f08 \
124126
mpi/java \
125127
$(OMPI_MPIEXT_ALL_SUBDIRS) \

ompi/mpi/fortran/configure-fortran-output.h.in

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,23 @@
4343
! Line 2 of the ignore TKR syntax
4444
#define OMPI_FORTRAN_IGNORE_TKR_TYPE @OMPI_FORTRAN_IGNORE_TKR_TYPE@
4545
46-
! f08 TKR syntax (w/o TS 29113)
47-
#define OMPI_F08_IGNORE_TKR_PREDECL @OMPI_F08_IGNORE_TKR_PREDECL@
46+
! The Fortran ISO C type type(*), dimension(..) is not (yet) supported by all compilers.
47+
! If it is supported, OMPI_F08_IGNORE_TKR_TYPE will be type(*), dimension(..).
48+
! Otherwise, it will be the same value as OMPI_FORTRAN_IGNORE_TKR_TYPE.
4849
#define OMPI_F08_IGNORE_TKR_TYPE @OMPI_F08_IGNORE_TKR_TYPE@
4950
51+
! If the Fortran compiler supports type(*), dimension(..), this macro will be "_desc"
52+
! so that the F08 descriptor-enabled Open MPI Fortran back-end functions are invoked.
53+
! Otherwise, it will be "_f" so that the non-F08-descriptor Open MPI Fortran back-end functions are invoked.
54+
#define OMPI_F08_BINDINGS_EXTENSION @OMPI_F08_BINDINGS_EXTENSION@
55+
56+
! If the Fortran compiler supports type(*), dimension(..), this macro will be empty
57+
! (i.e., we do not want to ignore the TKR of the buf parameter).
58+
! Otherwise, it will be set to !GCC$ ATTRIBUTES NO_ARG_CHECK :: buf so that the GCC compiler
59+
! (and related compilers, such as the Intel compiler) will ignore the TKR of the buf dummy argument.
60+
61+
#define OMPI_F08_GCC_ATTRIBUTES(buf) @OMPI_F08_GCC_ATTRIBUTES@
62+
5063
#define OMPI_FORTRAN_BUILD_SIZEOF @OMPI_FORTRAN_BUILD_SIZEOF@
5164
! Integers
5265

ompi/mpi/fortran/use-mpi-f08/Makefile.am

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ AM_CPPFLAGS =
3636
# MPI bindings.
3737
if OMPI_BUILD_FORTRAN_USEMPIF08_BINDINGS
3838

39-
AM_FCFLAGS = -I$(top_srcdir)/ompi/mpi/fortran/use-mpi-f08/mod \
40-
-I$(top_builddir)/ompi/include \
39+
AM_FCFLAGS = -I$(top_builddir)/ompi/include \
4140
-I$(top_srcdir)/ompi/include \
4241
$(OMPI_FC_MODULE_FLAG)$(top_builddir)/ompi/mpi/fortran/use-mpi \
4342
$(OMPI_FC_MODULE_FLAG)$(top_builddir)/ompi/$(OMPI_FORTRAN_USEMPI_DIR) \
@@ -541,6 +540,14 @@ lib@OMPI_LIBMPI_NAME@_usempif08_la_DEPENDENCIES = \
541540
lib@OMPI_LIBMPI_NAME@_usempif08_profile.la
542541
lib@OMPI_LIBMPI_NAME@_usempif08_la_LDFLAGS = -version-info $(libmpi_usempif08_so_version)
543542

543+
if OMPI_FORTRAN_HAVE_TS
544+
lib@OMPI_LIBMPI_NAME@_usempif08_la_LIBADD += \
545+
ts/libusempif08_ts.la
546+
547+
lib@OMPI_LIBMPI_NAME@_usempif08_la_DEPENDENCIES += \
548+
ts/libusempif08_ts.la
549+
endif
550+
544551
#
545552
# Automake doesn't do Fortran dependency analysis, so must list them
546553
# manually here. Bummer!

ompi/mpi/fortran/use-mpi-f08/ts/bindings.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ void ompi_ssend_init_ts(CFI_cdesc_t* x, MPI_Fint *count, MPI_Fint *datatype,
103103

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

106-
<<<<<<< HEAD
107106
void ompi_pack_ts(CFI_cdesc_t* x1, MPI_Fint *incount, MPI_Fint *datatype,
108107
CFI_cdesc_t* x2, MPI_Fint *outsize, MPI_Fint *position,
109108
MPI_Fint *comm, MPI_Fint *ierr);

ompi/mpi/fortran/use-mpi-f08/ts/ts.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; -*- */
2+
/*
3+
* Copyright (c) 2014 Argonne National Laboratory.
4+
* Copyright (c) 2019 Research Organization for Information Science
5+
* and Technology (RIST). All rights reserved.
6+
* $COPYRIGHT$
7+
*
8+
* Additional copyrights may follow
9+
*
10+
* $HEADER$
11+
*/
12+
13+
#include "ts.h"
14+
15+
#include <assert.h>
16+
17+
int ompi_ts_create_datatype(CFI_cdesc_t *cdesc, int oldcount, MPI_Datatype oldtype, MPI_Datatype *newtype)
18+
{
19+
const int MAX_RANK = 15; /* Fortran 2008 specifies a maximum rank of 15 */
20+
MPI_Datatype types[MAX_RANK + 1]; /* Use a fixed size array to avoid malloc. + 1 for oldtype */
21+
int mpi_errno = MPI_SUCCESS;
22+
int accum_elems = 1;
23+
int accum_sm = cdesc->elem_len;
24+
int done = 0; /* Have we created a datatype for oldcount of oldtype? */
25+
int last; /* Index of the last successfully created datatype in types[] */
26+
int extent;
27+
int i, j;
28+
29+
#ifdef OPAL_ENABLE_DEBUG
30+
{
31+
size_t size;
32+
assert(cdesc->rank <= MAX_RANK);
33+
ompi_datatype_type_size(oldtype, &size);
34+
/* When cdesc->elem_len != size, things suddenly become complicated. Generally, it is hard to create
35+
* a composite datatype based on two datatypes. Currently we don't support it and doubt it is usefull.
36+
*/
37+
assert(cdesc->elem_len == size);
38+
}
39+
#endif
40+
41+
types[0] = oldtype;
42+
i = 0;
43+
done = 0;
44+
while (i < cdesc->rank && !done) {
45+
if (oldcount % accum_elems) {
46+
/* oldcount should be a multiple of accum_elems, otherwise we might need an
47+
* MPI indexed datatype to describle the irregular region, which is not supported yet.
48+
*/
49+
mpi_errno = MPI_ERR_INTERN;
50+
last = i;
51+
goto fn_exit;
52+
}
53+
54+
extent = oldcount / accum_elems;
55+
if (extent > cdesc->dim[i].extent) {
56+
extent = cdesc->dim[i].extent;
57+
} else {
58+
/* Up to now, we have accumlated enough elements */
59+
done = 1;
60+
}
61+
62+
if (cdesc->dim[i].sm == accum_sm) {
63+
mpi_errno = PMPI_Type_contiguous(extent, types[i], &types[i+1]);
64+
} else {
65+
mpi_errno = PMPI_Type_create_hvector(extent, 1, cdesc->dim[i].sm, types[i], &types[i+1]);
66+
}
67+
if (mpi_errno != MPI_SUCCESS) {
68+
last = i;
69+
goto fn_exit;
70+
}
71+
72+
accum_sm = cdesc->dim[i].sm * cdesc->dim[i].extent;
73+
accum_elems *= cdesc->dim[i].extent;
74+
i++;
75+
}
76+
77+
if (done) {
78+
*newtype = types[i];
79+
MPI_Type_commit(newtype);
80+
last = i - 1; /* To avoid freeing newtype */
81+
} else {
82+
/* If # of elements given by "oldcount oldtype" is bigger than
83+
* what cdesc describles, then we will reach here.
84+
*/
85+
last = i;
86+
mpi_errno = MPI_ERR_ARG;
87+
goto fn_exit;
88+
}
89+
90+
fn_exit:
91+
for (j = 1; j <= last; j++)
92+
PMPI_Type_free(&types[j]);
93+
return mpi_errno;
94+
}

ompi/mpi/fortran/use-mpi-f08/ts/ts.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; -*- */
2+
/*
3+
* Copyright (c) 2014 Argonne National Laboratory.
4+
* Copyright (c) 2019 Research Organization for Information Science
5+
* and Technology (RIST). All rights reserved.
6+
* $COPYRIGHT$
7+
*
8+
* Additional copyrights may follow
9+
*
10+
* $HEADER$
11+
*/
12+
13+
#include "ompi_config.h"
14+
15+
#include <ISO_Fortran_binding.h>
16+
17+
#include "ompi/datatype/ompi_datatype.h"
18+
#include "ompi/mpi/fortran/base/fint_2_int.h"
19+
20+
extern int ompi_ts_create_datatype(CFI_cdesc_t *cdesc, int oldcount, MPI_Datatype oldtype, MPI_Datatype *newtype);
21+
22+
#define OMPI_CFI_2_C(x, count, type, datatype, rc) \
23+
do { \
24+
datatype = type; \
25+
if (x->rank != 0 && !CFI_is_contiguous(x)) { \
26+
rc = ompi_ts_create_datatype(x, count, type, &datatype); \
27+
if (MPI_SUCCESS != rc) { \
28+
return; \
29+
} else { \
30+
count = 1; \
31+
} \
32+
} else { \
33+
rc = MPI_SUCCESS; \
34+
} \
35+
} while (0)
36+
37+
#define OMPI_CFI_IS_CONTIGUOUS(x) \
38+
(0 == x->rank || CFI_is_contiguous(x))
39+
40+
#define OMPI_CFI_CHECK_CONTIGUOUS(x, rc) \
41+
do { \
42+
if (OMPI_CFI_IS_CONTIGUOUS(x)) { \
43+
rc = MPI_SUCCESS; \
44+
} else { \
45+
rc = MPI_ERR_INTERN; \
46+
} \
47+
} while (0)
48+

0 commit comments

Comments
 (0)