Skip to content

Commit ff4352c

Browse files
jtrongeggouaillardethppritcha
committed
Generate mpi_f08 bindings and add CFI support
This updates fortran/use-mpi-f08 to generate most of the Fortran bindings from a script and template files. It also adds support for Fortran TS 29113 when possible, allowing for better Fortran array handling that matches the standard. The C files were imported from PR #10302 and converted to templates to be fed into the binding script. Co-authored-by: Gilles Gouaillardet <[email protected]> Co-authored-by: Howard Pritchard <[email protected]> Signed-off-by: Jake Tronge <[email protected]>
1 parent 86be709 commit ff4352c

File tree

356 files changed

+12600
-9066
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

356 files changed

+12600
-9066
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ ompi/mpi/fortran/mpiext/mpi-ext-module.F90
201201
ompi/mpi/fortran/mpiext/mpi-f08-ext-module.F90
202202
ompi/mpi/fortran/mpiext-use-mpi/mpi-ext-module.F90
203203
ompi/mpi/fortran/mpiext-use-mpi-f08/mpi-f08-ext-module.F90
204+
ompi/mpi/fortran/use-mpi-f08/psizeof_f08.f90
204205

205206
ompi/mpi/fortran/mpif-h/sizeof_f.f90
206207
ompi/mpi/fortran/mpif-h/profile/p*.c

config/ompi_config_files.m4

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ AC_DEFUN([OMPI_CONFIG_FILES],[
3737
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-file-interfaces.h
3838
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-removed-interfaces.h
3939
ompi/mpi/fortran/use-mpi-f08/Makefile
40-
ompi/mpi/fortran/use-mpi-f08/profile/Makefile
4140
ompi/mpi/fortran/use-mpi-f08/base/Makefile
4241
ompi/mpi/fortran/use-mpi-f08/bindings/Makefile
4342
ompi/mpi/fortran/use-mpi-f08/mod/Makefile

ompi/mpi/bindings/ompi_bindings/fortran.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,9 @@ def print_c_source_header(out):
228228
out.dump('#include "ompi/file/file.h"')
229229
out.dump('#include "ompi/errhandler/errhandler.h"')
230230
out.dump('#include "ompi/datatype/ompi_datatype.h"')
231+
out.dump('#include "ompi/mca/coll/base/coll_base_util.h"')
231232
out.dump('#include "ts.h"')
232-
out.dump('#include "array.h"')
233+
out.dump('#include "bigcount.h"')
233234

234235

235236
def print_binding(prototype, lang, out, bigcount=False, template=None):

ompi/mpi/bindings/ompi_bindings/fortran_type.py

Lines changed: 288 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ def c_parameter(self):
176176
return f'OMPI_CFI_BUFFER *{self.name}'
177177

178178

179+
@FortranType.add('C_PTR_OUT')
180+
class CptrType(FortranType):
181+
def declare(self):
182+
return f'TYPE(C_PTR), INTENT(OUT) :: {self.name}'
183+
184+
def use(self):
185+
return [('ISO_C_BINDING', 'C_PTR')]
186+
187+
def c_parameter(self):
188+
return f'char *{self.name}'
189+
179190
@FortranType.add('COUNT')
180191
class CountType(FortranType):
181192
def declare(self):
@@ -191,6 +202,50 @@ def c_parameter(self):
191202
type_ = 'MPI_Count' if self.bigcount else 'MPI_Fint'
192203
return f'{type_} *{self.name}'
193204

205+
@FortranType.add('COUNT_INOUT')
206+
class CountTypeInOut(FortranType):
207+
"""COUNT type with INOUT INTENT"""
208+
def declare(self):
209+
if self.bigcount:
210+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(INOUT) :: {self.name}'
211+
else:
212+
return f'INTEGER, INTENT(INOUT) :: {self.name}'
213+
214+
def use(self):
215+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
216+
217+
def c_parameter(self):
218+
type_ = 'MPI_Count' if self.bigcount else 'MPI_Fint'
219+
return f'{type_} *{self.name}'
220+
221+
@FortranType.add('COUNT_OUT')
222+
class CountTypeInOut(FortranType):
223+
"""COUNT type with OUT INTENT"""
224+
def declare(self):
225+
if self.bigcount:
226+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(OUT) :: {self.name}'
227+
else:
228+
return f'INTEGER, INTENT(IN) :: {self.name}'
229+
230+
def use(self):
231+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
232+
233+
def c_parameter(self):
234+
type_ = 'MPI_Count' if self.bigcount else 'MPI_Fint'
235+
return f'{type_} *{self.name}'
236+
237+
238+
@FortranType.add('PARTITIONED_COUNT')
239+
class PartitionedCountType(FortranType):
240+
def declare(self):
241+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: {self.name}'
242+
243+
def use(self):
244+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
245+
246+
def c_parameter(self):
247+
return f'MPI_Count *{self.name}'
248+
194249

195250
@FortranType.add('DATATYPE')
196251
class DatatypeType(FortranType):
@@ -209,6 +264,24 @@ def use(self):
209264
def c_parameter(self):
210265
return f'MPI_Fint *{self.name}'
211266

267+
@FortranType.add('DATATYPE_OUT')
268+
class DatatypeTypeOut(FortranType):
269+
def declare(self):
270+
return f'TYPE(MPI_Datatype), INTENT(OUT) :: {self.name}'
271+
272+
def declare_cbinding_fortran(self):
273+
return f'INTEGER, INTENT(OUT) :: {self.name}'
274+
275+
def argument(self):
276+
return f'{self.name}%MPI_VAL'
277+
278+
def use(self):
279+
return [('mpi_f08_types', 'MPI_Datatype')]
280+
281+
def c_parameter(self):
282+
return f'MPI_Fint *{self.name}'
283+
284+
212285

213286
@FortranType.add('DATATYPE_ARRAY')
214287
class DatatypeArrayType(FortranType):
@@ -293,8 +366,20 @@ def c_parameter(self):
293366
return f'MPI_Fint *{self.name}'
294367

295368

296-
@FortranType.add('STATUS_OUT')
369+
@FortranType.add('STATUS')
297370
class StatusType(FortranType):
371+
def declare(self):
372+
return f'TYPE(MPI_Status) :: {self.name}'
373+
374+
def use(self):
375+
return [('mpi_f08_types', 'MPI_Status')]
376+
377+
def c_parameter(self):
378+
return f'MPI_Fint *{self.name}'
379+
380+
381+
@FortranType.add('STATUS_OUT')
382+
class StatusOutType(FortranType):
298383
def declare(self):
299384
return f'TYPE(MPI_Status), INTENT(OUT) :: {self.name}'
300385

@@ -382,9 +467,28 @@ def c_parameter(self):
382467
count_type = 'MPI_Count' if self.bigcount else 'MPI_Fint'
383468
return f'{count_type} *{self.name}'
384469

470+
@FortranType.add('AINT_COUNT_ARRAY')
471+
class CountArray(IntArray):
472+
"""Array of MPI_Count or int."""
473+
474+
def declare(self):
475+
kind = '(KIND=MPI_COUNT_KIND)' if self.bigcount else '(KIND=MPI_ADDRESS_KIND)'
476+
return f'INTEGER{kind}, INTENT(IN) :: {self.name}(*)'
477+
478+
def use(self):
479+
if self.bigcount:
480+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
481+
else:
482+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
483+
484+
def c_parameter(self):
485+
count_type = 'MPI_Count' if self.bigcount else 'MPI_Aint'
486+
return f'{count_type} *{self.name}'
487+
488+
385489

386490
@FortranType.add('AINT')
387-
class Disp(FortranType):
491+
class Aint(FortranType):
388492
"""MPI_Aint type."""
389493

390494
def declare(self):
@@ -397,6 +501,95 @@ def c_parameter(self):
397501
return f'MPI_Aint *{self.name}'
398502

399503

504+
@FortranType.add('AINT_OUT')
505+
class AintOut(FortranType):
506+
"""MPI_Aint out type."""
507+
508+
def declare(self):
509+
return f'INTEGER(MPI_ADDRESS_KIND), INTENT(OUT) :: {self.name}'
510+
511+
def use(self):
512+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
513+
514+
def c_parameter(self):
515+
return f'MPI_Aint *{self.name}'
516+
517+
518+
@FortranType.add('AINT_COUNT')
519+
class AintCountTypeIn(FortranType):
520+
"""AINT/COUNT type with ININTENT"""
521+
def declare(self):
522+
if self.bigcount:
523+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: {self.name}'
524+
else:
525+
return f'INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) :: {self.name}'
526+
527+
def use(self):
528+
if self.bigcount:
529+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
530+
else:
531+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
532+
533+
def c_parameter(self):
534+
type_ = 'MPI_Count' if self.bigcount else 'MPI_Aint'
535+
return f'{type_} *{self.name}'
536+
537+
538+
@FortranType.add('AINT_COUNT_INOUT')
539+
class AintCountTypeInOut(FortranType):
540+
"""AINT/COUNT type with INOUT INTENT"""
541+
def declare(self):
542+
if self.bigcount:
543+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(INOUT) :: {self.name}'
544+
else:
545+
return f'INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(INOUT) :: {self.name}'
546+
547+
def use(self):
548+
if self.bigcount:
549+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
550+
else:
551+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
552+
553+
def c_parameter(self):
554+
type_ = 'MPI_Count' if self.bigcount else 'MPI_Aint'
555+
return f'{type_} *{self.name}'
556+
557+
558+
@FortranType.add('AINT_COUNT_OUT')
559+
class AintCountTypeOut(FortranType):
560+
"""AINT/COUNT type with OUT INTENT"""
561+
def declare(self):
562+
if self.bigcount:
563+
return f'INTEGER(KIND=MPI_COUNT_KIND), INTENT(OUT) :: {self.name}'
564+
else:
565+
return f'INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(OUT) :: {self.name}'
566+
567+
def use(self):
568+
if self.bigcount:
569+
return [('mpi_f08_types', 'MPI_COUNT_KIND')]
570+
else:
571+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
572+
573+
def c_parameter(self):
574+
type_ = 'MPI_Count' if self.bigcount else 'MPI_Aint'
575+
return f'{type_} *{self.name}'
576+
577+
578+
@FortranType.add('AINT_ARRAY')
579+
class AintArrayType(FortranType):
580+
"""Array of MPI_Aint."""
581+
582+
def declare(self):
583+
# TODO: Should there be a separate ASYNC version here, when the OMPI_ASYNCHRONOUS attr is required?
584+
return f'INTEGER(KIND=MPI_ADDRESS_KIND), INTENT(IN) OMPI_ASYNCHRONOUS :: {self.name}(*)'
585+
586+
def use(self):
587+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
588+
589+
def c_parameter(self):
590+
return f'MPI_Aint *{self.name}'
591+
592+
400593
@FortranType.add('DISP')
401594
class Disp(FortranType):
402595
"""Displacecment type."""
@@ -414,6 +607,23 @@ def c_parameter(self):
414607
count_type = 'MPI_Aint' if self.bigcount else 'MPI_Fint'
415608
return f'{count_type} *{self.name}'
416609

610+
@FortranType.add('DISP_OUT')
611+
class DispOut(FortranType):
612+
"""Displacecment out type."""
613+
614+
def declare(self):
615+
kind = '(KIND=MPI_ADDRESS_KIND)' if self.bigcount else ''
616+
return f'INTEGER{kind}, INTENT(OUT) :: {self.name}'
617+
618+
def use(self):
619+
if self.bigcount:
620+
return [('mpi_f08_types', 'MPI_ADDRESS_KIND')]
621+
return []
622+
623+
def c_parameter(self):
624+
count_type = 'MPI_Aint' if self.bigcount else 'MPI_Fint'
625+
return f'{count_type} *{self.name}'
626+
417627

418628
@FortranType.add('DISP_ARRAY')
419629
class DispArray(IntArray):
@@ -460,6 +670,25 @@ def use(self):
460670
def c_parameter(self):
461671
return f'MPI_Fint *{self.name}'
462672

673+
@FortranType.add('WIN_OUT')
674+
class WinOut(FortranType):
675+
"""MPI_Win out type."""
676+
677+
def declare(self):
678+
return f'TYPE(MPI_Win), INTENT(OUT) :: {self.name}'
679+
680+
def declare_cbinding_fortran(self):
681+
return f'INTEGER, INTENT(OUT) :: {self.name}'
682+
683+
def argument(self):
684+
return f'{self.name}%MPI_VAL'
685+
686+
def use(self):
687+
return [('mpi_f08_types', 'MPI_Win')]
688+
689+
def c_parameter(self):
690+
return f'MPI_Fint *{self.name}'
691+
463692

464693
@FortranType.add('FILE')
465694
class File(FortranType):
@@ -473,3 +702,60 @@ def use(self):
473702

474703
def c_parameter(self):
475704
return f'MPI_Fint *{self.name}'
705+
706+
@FortranType.add('INFO')
707+
class Info(FortranType):
708+
"""MPI_Info type."""
709+
710+
def declare(self):
711+
return f'TYPE(MPI_Info), INTENT(IN) :: {self.name}'
712+
713+
def use(self):
714+
return [('mpi_f08_types', 'MPI_Info')]
715+
716+
def c_parameter(self):
717+
return f'MPI_Fint *{self.name}'
718+
719+
@FortranType.add('OFFSET')
720+
class Offset(FortranType):
721+
"""MPI_Offset type."""
722+
723+
def declare(self):
724+
return f'INTEGER(MPI_OFFSET_KIND), INTENT(IN) :: {self.name}'
725+
726+
def use(self):
727+
return [('mpi_f08_types', 'MPI_OFFSET_KIND')]
728+
729+
def c_parameter(self):
730+
return f'MPI_Offset *{self.name}'
731+
732+
733+
@FortranType.add('CHAR_ARRAY')
734+
class CharArray(FortranType):
735+
"""Fortran CHAR type."""
736+
737+
def declare(self):
738+
return f'CHARACTER(LEN=*), INTENT(IN) :: {self.name}'
739+
740+
def use(self):
741+
return [('iso_c_binding', 'c_char')]
742+
743+
def declare_cbinding_fortran(self):
744+
return f'CHARACTER(KIND=C_CHAR), INTENT(IN) :: {self.name}(*)'
745+
746+
def c_parameter(self):
747+
return f'char *{self.name}'
748+
749+
750+
@FortranType.add('MESSAGE_INOUT')
751+
class MessageInOut(FortranType):
752+
"""MPI_Message INOUT type."""
753+
754+
def declare(self):
755+
return f'TYPE(MPI_Message), INTENT(INOUT) :: {self.name}'
756+
757+
def use(self):
758+
return [('mpi_f08_types', 'MPI_Message')]
759+
760+
def c_parameter(self):
761+
return f'MPI_Fint *{self.name}'

ompi/mpi/bindings/ompi_bindings/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def load(fname, prefix=None, type_constructor=None):
113113
header.append(line)
114114

115115
if not prototype:
116-
raise RuntimeError('missing prototype')
116+
raise RuntimeError(f'missing prototype for {fname}')
117117
# Parse the prototype
118118
prototype = ''.join(prototype)
119119
prototype = prototype[len('PROTOTYPE'):]

0 commit comments

Comments
 (0)