1****************
2Fortran bindings
3****************
4
5.. role:: f90(code)
6   :language: fortran
7   :class: highlight
8
9The Fortran bindings API consist entirely on subroutines calls. Always, the 1st argument is a Fortran type (struct) to an ADIOS2 component, while the last argument is an error integer flag, :f90:`integer ierr`. ``ierr==0`` means normal execution while any other value represents an error or a different state. ADIOS2 Fortran bindings provide a list of possible errors coming from the C++ standardized error exception library:
10
11.. code-block:: fortran
12
13    ! error possible values for ierr
14    integer, parameter :: adios2_error_none = 0
15    integer, parameter :: adios2_error_invalid_argument = 1,
16    integer, parameter :: adios2_error_system_error = 2,
17    integer, parameter :: adios2_error_runtime_error = 3,
18    integer, parameter :: adios2_error_exception = 4
19
20Click here for a `Fortran write and read example`_ to illustrate the use of the APIs calls before digging into the description of each subroutine. This test will compile under your build/bin/ directory.
21
22.. _`Fortran write and read example`: https://github.com/ornladios/ADIOS2/blob/master/testing/adios2/bindings/fortran/TestBPWriteReadHeatMap3D.f90
23
24The following subsections describe the overall component representation and the main subroutines versions in the Fortran bindings API.
25
26ADIOS2 typed handlers
27---------------------
28
29ADIOS2 Fortran bindings handlers are mapped 1-to-1 to the ADIOS components described in the :ref:`Components Overview` section. For convenience, each type handler contains descriptive components used for read-only inspection.
30
31.. code-block:: fortran
32
33   type(adios2_adios) :: adios
34   type(adios2_io) :: io
35   type(adios2_variable) :: variable
36   type(adios2_attribute) :: attribute
37   type(adios2_engine) :: engine
38
39   !Read-only components for inspection and ( = defaults)
40
41   type adios2_adios
42        logical :: valid = .false.
43    end type
44
45    type adios2_io
46        logical :: valid = .false.
47        character(len=15):: engine_type = 'BPFile'
48    end type
49
50    type adios2_variable
51        logical :: valid = .false.
52        character(len=4095):: name = ''
53        integer :: type = -1
54        integer :: ndims = -1
55    end type
56
57    type adios2_attribute
58        logical :: valid = .false.
59        character(len=4095):: name = ''
60        integer :: type = -1
61        integer :: length = 0
62    end type
63
64    type adios2_engine
65        logical :: valid = .false.
66        character(len=63):: name = ''
67        character(len=15):: type = ''
68        integer :: mode = adios2_mode_undefined
69    end type
70
71    type adios2_operator
72        logical :: valid = .false.
73        character(len=63):: name = ''
74        character(len=63):: type = ''
75    end type
76
77
78.. caution::
79
80   Use the type read-only components for information purposes only.
81   Changing their values directly, *e.g.* ``variable%name = new_name`` does not have any effect inside the adios2 library
82
83
84:ref:`ADIOS` subroutines
85------------------------
86
87* :f90:`subroutine adios2_init` starting point for the adios2 library
88
89   .. code-block:: fortran
90
91      ! MPI versions
92      ! Debug mode = ON (.true.) by default
93      subroutine adios2_init(adios, comm, ierr)
94      subroutine adios2_init(adios, config_file, comm, ierr)
95
96      subroutine adios2_init(adios, comm, adios2_debug_mode, ierr)
97      subroutine adios2_init(adios, config_file, comm, adios2_debug_mode, ierr)
98
99      ! Non-MPI serial versions
100      ! Debug mode = ON (.true.) by default
101      subroutine adios2_init(adios, ierr)
102      subroutine adios2_init(adios, config_file, ierr)
103
104      subroutine adios2_init(adios, adios2_debug_mode, ierr)
105      subroutine adios2_init(adios, config_file, adios2_debug_mode, ierr)
106
107      ! WHERE:
108
109      ! adios handler to allocate
110      type(adios2_adios), intent(out):: adios
111
112      ! MPI Communicator
113      integer, intent(in):: comm
114
115      ! Optional runtime configuration file (*.xml), see Runtime Configuration Files
116      character*(*), intent(in) :: config_file
117
118      ! .true. (adios2_debug_mode_on): enable extra user input checks-> recommended
119      ! .false. (adios2_debug_mode_of): disable extra user input checks
120      logical, intent(in):: adios2_debug_mode
121
122
123* :f90:`subroutine adios2_declare_io` spawn io components
124
125   .. code-block:: fortran
126
127      subroutine adios2_declare_io(io, adios, io_name, ierr)
128
129      ! WHERE:
130
131      ! io component that defines an IO tasks inside adios component
132      type(adios2_io), intent(out):: io
133
134      ! adios component from adios2_init spawning io tasks
135      type(adios2_adios), intent(in):: adios
136
137      ! unique name associated with this io component inside adios
138      character*(*), intent(in):: io_name
139
140* :f90:`subroutine adios2_at_io` retrieve an existing io component, useful when the original handler for adios2_declare_io goes out of scope
141
142   .. code-block:: fortran
143
144      subroutine adios2_at_io(io, adios, io_name, ierr)
145
146      ! WHERE:
147
148      ! io component that defines an IO tasks inside adios component
149      type(adios2_io), intent(out):: io
150
151      ! adios component from adios2_init that owns io tasks
152      type(adios2_adios), intent(in):: adios
153
154      ! unique name associated with an existing io component (created with adios2_declare_io)
155      character*(*), intent(in):: io_name
156
157
158* :f90:`subroutine adios2_flush_all` flush all current engines in all ios
159
160   .. code-block:: fortran
161
162      subroutine adios2_flush_all(adios, ierr)
163
164      ! WHERE:
165
166      ! adios component from adios2_init owning ios and engines
167      type(adios2_adios), intent(in):: adios
168
169* :f90:`subroutine adios2_finalize` final point for the adios component
170
171   .. code-block:: fortran
172
173      subroutine adios2_finalize(adios, ierr)
174
175      ! WHERE:
176
177      ! adios handler to be deallocated
178      type(adios2_adios), intent(in):: adios
179
180
181.. caution::
182
183   Make sure that for every call to ``adios2_init`` there is a call to ``adios2_finalize`` for the same adios handler. Not doing so will result in memory leaks.
184
185
186:ref:`IO` subroutines
187---------------------
188
189* :f90:`subroutine adios2_define_variable`
190
191   .. code-block:: fortran
192
193      ! Global array variables
194      subroutine adios2_define_variable(variable, io, variable_name, adios2_type, &
195                                        ndims, shape_dims, start_dims, count_dims, &
196                                        adios2_constant_dims, ierr)
197      ! Global single value variables
198      subroutine adios2_define_variable(variable, io, variable_name, adios2_type, ierr)
199
200      ! WHERE:
201
202      ! handler to newly defined variable
203      type(adios2_variable), intent(out):: variable
204
205      ! io component owning the variable
206      type(adios2_io), intent(in):: io
207
208      ! unique variable identifier within io
209      character*(*), intent(in):: variable_name
210
211      ! defines variable type from adios2 parameters, see next
212      integer, intent(in):: adios2_type
213
214      ! number of dimensions
215      integer, value, intent(in):: ndims
216
217      ! variable shape, global size, dimensions
218      ! to create local variables optional pass adios2_null_dims
219      integer(kind=8), dimension(:), intent(in):: shape_dims
220
221      ! variable start, local offset, dimensions
222      ! to create local variables optional pass adios2_null_dims
223      integer(kind=8), dimension(:), intent(in):: start_dims
224
225      ! variable count, local size, dimensions
226      integer(kind=8), dimension(:), intent(in):: count_dims
227
228      ! .true. : constant dimensions, shape, start and count won't change
229      !          (mesh sizes, number of nodes)
230      !          adios2_constant_dims = .true. use for code clarity
231      ! .false. : variable dimensions, shape, start and count could change
232      !           (number of particles)
233      !           adios2_variable_dims = .false. use for code clarity
234      logical, value, intent(in):: adios2_constant_dims
235
236
237* available :f90:`adios2_type` parameters in :f90:`subroutine adios2_define_variable`
238
239   .. code-block:: fortran
240
241      integer, parameter :: adios2_type_character = 0
242      integer, parameter :: adios2_type_real = 2
243      integer, parameter :: adios2_type_dp = 3
244      integer, parameter :: adios2_type_complex = 4
245      integer, parameter :: adios2_type_complex_dp = 5
246
247      integer, parameter :: adios2_type_integer1 = 6
248      integer, parameter :: adios2_type_integer2 = 7
249      integer, parameter :: adios2_type_integer4 = 8
250      integer, parameter :: adios2_type_integer8 = 9
251
252      integer, parameter :: adios2_type_string = 10
253      integer, parameter :: adios2_type_string_array = 11
254
255
256.. tip::
257
258   Always prefer using ``adios2_type_xxx`` parameters explicitly rather than raw numbers.
259   *e.g.* use ``adios2_type_dp`` instead of ``3``
260
261
262
263* :f90:`subroutine adios2_define_attribute`
264
265   .. code-block:: fortran
266
267      ! Single value attributes
268      subroutine adios2_define_attribute(attribute, io, attribute_name, data, ierr)
269
270      ! 1D array attributes
271      subroutine adios2_define_attribute(attribute, io, attribute_name, data, elements, ierr)
272
273      ! WHERE:
274
275      ! handler to newly defined attribute
276      type(adios2_attribute), intent(out):: attribute
277
278      ! io component owning the attribute
279      type(adios2_io), intent(in):: io
280
281      ! unique attribute identifier within io
282      character*(*), intent(in):: attribute_name
283
284      ! overloaded subroutine allows for multiple attribute data types
285      ! they can be single values or 1D arrays
286      Generic Fortran types, intent(in):: data
287      Generic Fortran types, dimension(:), intent(in):: data
288
289      ! number of elements if passing a 1D array in data argument
290      integer, intent(in):: elements
291
292
293* :f90:`subroutine adios2_set_engine` set engine type in code, see :ref:`Supported Engines` for a list of available engines
294
295   .. code-block:: fortran
296
297      subroutine adios2_set_engine(io, engine_type, ierr)
298
299      ! WHERE:
300
301      ! io component owning the attribute
302      type(adios2_io), intent(in):: io
303
304      ! engine_type: BPFile (default), HDF5, DataMan, SST, InSituMPI
305      character*(*), intent(in):: engine_type
306
307* :f90:`subroutine adios2_set_parameter` set IO key/value pair parameter in code, see :ref:`Supported Engines` for a list of available parameters for each engine type
308
309   .. code-block:: fortran
310
311      subroutine adios2_set_parameter(io, key, value, ierr)
312
313      ! WHERE:
314
315      ! io component owning the attribute
316      type(adios2_io), intent(in):: io
317
318      ! key in the key/value pair parameter
319      character*(*), intent(in):: key
320
321      ! value in the key/value pair parameter
322      character*(*), intent(in):: value
323
324
325* :f90:`subroutine adios2_inquire_variable` inquire for existing variable by its unique name
326
327   .. code-block:: fortran
328
329      subroutine adios2_inquire_variable(variable, io, name, ierr)
330
331      ! WHERE:
332
333      ! output variable handler:
334      ! variable%valid = .true. points to valid found variable
335      ! variable%valid = .false. variable not found
336      type(adios2_variable), intent(out) :: variable
337
338      ! io in which search for variable is performed
339      type(adios2_io), intent(in) :: io
340
341      ! unique key name to search for variable
342      character*(*), intent(in) :: name
343
344* :f90:`subroutine adios2_inquire_attribute` inquire for existing attribute by its unique name
345
346   .. code-block:: fortran
347
348      subroutine adios2_inquire_attribute(attribute, io, name, ierr)
349
350      ! WHERE:
351
352      ! output attribute handler:
353      ! attribute%valid = .true. points to valid found attribute
354      ! attribute%valid = .false. attribute not found
355      type(adios2_attribute), intent(out) :: attribute
356
357      ! io in which search for attribute is performed
358      type(adios2_io), intent(in) :: io
359
360      ! unique key name to search for attribute
361      character*(*), intent(in) :: name
362
363..  caution::
364
365   Use the ``adios2_remove_*`` subroutines with extreme CAUTION.
366   They create outdated dangling information in the ``adios2_type`` handlers.
367   If you don't need them, don't use them.
368
369
370* :f90:`subroutine adios2_remove_variable` remove existing variable by its unique name
371
372   .. code-block:: fortran
373
374      subroutine adios2_remove_variable(io, name, result, ierr)
375
376      ! WHERE:
377
378      ! io in which search and removal for variable is performed
379      type(adios2_io), intent(in) :: io
380
381      ! unique key name to search for variable
382      character*(*), intent(in) :: name
383
384      ! true: variable removed, false: variable not found, not removed
385      logical, intent(out) :: result
386
387
388* :f90:`subroutine adios2_remove_attribute` remove existing attribute by its unique name
389
390   .. code-block:: fortran
391
392      subroutine adios2_remove_attribute(io, name, result, ierr)
393
394      ! WHERE:
395
396      ! io in which search and removal for attribute is performed
397      type(adios2_io), intent(in) :: io
398
399      ! unique key name to search for attribute
400      character*(*), intent(in) :: name
401
402      ! true: attribute removed, false: attribute not found, not removed
403      logical, intent(out) :: result
404
405* :f90:`subroutine adios2_remove_all_variables` remove all existing variables
406
407   .. code-block:: fortran
408
409      subroutine adios2_remove_variable(io, ierr)
410
411      ! WHERE:
412
413      ! io in which search and removal for all variables is performed
414      type(adios2_io), intent(in) :: io
415
416
417* :f90:`subroutine adios2_remove_all_attributes` remove all existing attributes
418
419   .. code-block:: fortran
420
421      subroutine adios2_remove_all_attributes(io, ierr)
422
423      ! WHERE:
424
425      ! io in which search and removal for all attributes is performed
426      type(adios2_io), intent(in) :: io
427
428* :f90:`subroutine adios2_flush_all_engines` flushes all existing engines opened by this io
429
430   .. code-block:: fortran
431
432      subroutine adios2_flush_all_engines(io, ierr)
433
434      ! WHERE:
435
436      ! io in which search and flush for all engines is performed
437      type(adios2_io), intent(in) :: io
438
439* :f90:`subroutine adios2_open` opens an engine to executes IO tasks
440
441   .. code-block:: fortran
442
443      ! MPI version: duplicates communicator from adios2_init
444      ! Non-MPI serial version
445      subroutine adios2_open(engine, io, name, adios2_mode, ierr)
446
447      ! MPI version only to pass a communicator other than the one from adios_init
448      subroutine adios2_open(engine, io, name, adios2_mode, comm, ierr)
449
450      ! WHERE:
451
452      ! handler to newly opened adios2 engine
453      type(adios2_engine), intent(out) :: engine
454
455      ! io that spawns an engine based on its configuration
456      type(adios2_io), intent(in) :: io
457
458      ! unique engine identifier within io, file name for default BPFile engine
459      character*(*), intent(in) :: name
460
461      ! Optional MPI communicator, only in MPI library
462      integer, intent(in) :: comm
463
464      ! open mode parameter:
465      !                      adios2_mode_write,
466      !                      adios2_mode_append,
467      !                      adios2_mode_read,
468      integer, intent(in):: adios2_mode
469
470
471
472
473
474
475:ref:`Variable` subroutines
476---------------------------
477
478* :f90:`subroutine adios2_set_shape` set new ``shape_dims`` if dims are variable in ``adios2_define_variable``
479
480   .. code-block:: fortran
481
482      subroutine adios2_set_selection(variable, ndims, shape_dims, ierr)
483
484      ! WHERE
485
486      ! variable handler
487      type(adios2_variable), intent(in) :: variable
488
489      ! number of dimensions in shape_dims
490      integer, intent(in) :: ndims
491
492      ! new shape_dims
493      integer(kind=8), dimension(:), intent(in):: shape_dims
494
495
496
497* :f90:`subroutine adios2_set_selection` set new start_dims and count_dims
498
499   .. code-block:: fortran
500
501      subroutine adios2_set_selection(variable, ndims, start_dims, count_dims, ierr)
502
503      ! WHERE
504
505      ! variable handler
506      type(adios2_variable), intent(in) :: variable
507
508      ! number of dimensions in start_dims and count_dims
509      integer, intent(in) :: ndims
510
511      ! new start_dims
512      integer(kind=8), dimension(:), intent(in):: start_dims
513
514      ! new count_dims
515      integer(kind=8), dimension(:), intent(in):: count_dims
516
517* :f90:`subroutine adios2_set_steps_selection` set new step_start and step_count
518
519   .. code-block:: fortran
520
521      subroutine adios2_set_selection(variable, step_start, step_count, ierr)
522
523      ! WHERE
524
525      ! variable handler
526      type(adios2_variable), intent(in) :: variable
527
528      ! new step_start
529      integer(kind=8), intent(in):: step_start
530
531      ! new step_count (or number of steps to read from step_start)
532      integer(kind=8), intent(in):: step_count
533
534      ! error code
535      integer, intent(out) :: ierr
536
537* :f90:`subroutine adios2_attribute_data` Retrieve attribute data
538
539   .. code-block:: fortran
540
541      subroutine adios2_attribute_data(data, attribute, ierr)
542
543      ! WHERE
544
545      ! data handler
546      character*(*), intent(out):: data
547      real, intent(out):: data
548      real(kind=8), intent(out):: data
549      integer(kind=1), intent(out):: data
550      integer(kind=2), intent(out):: data
551      integer(kind=4), intent(out):: data
552      integer(kind=8), intent(out):: data
553      character*(*), dimension(:), intent(out):: data
554      real, dimension(:), intent(out):: data
555      real(kind=8), dimension(:), intent(out):: data
556      integer(kind=2), dimension(:), intent(out):: data
557      integer(kind=4), dimension(:), intent(out):: data
558      integer(kind=8), dimension(:), intent(out):: data
559
560
561      ! attribute
562      type(adios2_attribute), intent(in):: attribute
563
564      ! error code
565      integer, intent(out) :: ierr
566
567
568:ref:`Engine` subroutines
569-------------------------
570
571* :f90:`subroutine adios2_begin_step` moves to next step, starts at 0
572
573   .. code-block:: fortran
574
575      ! Full signature
576      subroutine adios2_begin_step(engine, adios2_step_mode, timeout_seconds, status, ierr)
577      ! Default Timeout = -1.    (block until step available)
578      subroutine adios2_begin_step(engine, adios2_step_mode, ierr)
579      ! Default step_mode for read and write
580      subroutine adios2_begin_step(engine, ierr)
581
582      ! WHERE
583
584      ! engine handler
585      type(adios2_engine), intent(in) :: engine
586
587      ! step_mode parameter:
588      !                      adios2_step_mode_read (read mode default)
589      !                      adios2_step_mode_append (write mode default)
590      integer, intent(in):: adios2_step_mode
591
592      ! optional
593      ! engine timeout (if supported), in seconds
594      real, intent(in):: timeout_seconds
595      ! status of the stream from adios2_step_status_* parameters
596      integer, intent(out):: status
597
598
599* :f90:`subroutine adios2_current_step` extracts current step
600
601   .. code-block:: fortran
602
603      ! Full signature
604      subroutine adios2_current_step(current_step, engine, ierr)
605
606      ! WHERE:
607      ! engine handler
608      type(adios2_engine), intent(in) :: engine
609
610      ! populated with current_step value
611      integer(kind=8), intent(out) :: current_step
612
613* :f90:`subroutine adios2_steps` Inspect total number of available steps,
614      use for file engines in read mode only
615
616   .. code-block:: fortran
617
618      ! Full signature
619      subroutine adios2_steps(steps, engine, ierr)
620
621      ! WHERE:
622      ! engine handler
623      type(adios2_engine), intent(in) :: engine
624
625      ! populated with steps value
626      integer(kind=8), intent(out) :: steps
627
628
629* :f90:`subroutine adios2_end_step` ends current step and default behavior is to execute transport IO (flush or read).
630
631   .. code-block:: fortran
632
633      ! Full signature
634      subroutine adios2_end_step(engine, ierr)
635
636      ! WHERE:
637      ! engine handler
638      type(adios2_engine), intent(in) :: engine
639
640* :f90:`subroutine adios2_put` put variable metadata and data into adios2 for IO operations. Default is deferred mode, optional sync mode, see :ref:`Put: modes and memory contracts`. Variable and data types must match.
641
642
643   .. code-block:: fortran
644
645      ! Full signature
646      subroutine adios2_put(engine, variable, data, adios2_mode, ierr)
647
648      ! Default adios2_mode_deferred
649      subroutine adios2_put(engine, variable, data, ierr)
650
651      ! WHERE:
652
653      ! engine handler
654      type(adios2_engine), intent(in) :: engine
655
656      ! variable handler containing metadata information
657      type(adios2_variable), intent(in) :: variable
658
659      ! Fortran bindings supports data types from adios2_type in variables,
660      ! up to 6 dimensions
661      ! Generic Fortran type from adios2_type
662      Generic Fortran types, intent(in):: data
663      Generic Fortran types, dimension(:), intent(in):: data
664      Generic Fortran types, dimension(:,:), intent(in):: data
665      Generic Fortran types, dimension(:,:,:), intent(in):: data
666      Generic Fortran types, dimension(:,:,:,:), intent(in):: data
667      Generic Fortran types, dimension(:,:,:,:,:), intent(in):: data
668      Generic Fortran types, dimension(:,:,:,:,:,:), intent(in):: data
669
670      ! mode:
671      ! adios2_mode_deferred: won't execute until adios2_end_step, adios2_perform_puts or adios2_close
672      ! adios2_mode_sync: special case, put data immediately, can be reused after this call
673      integer, intent(in):: adios2_mode
674
675
676* :f90:`subroutine adios2_perform_puts` executes deferred calls to adios2_put
677
678   .. code-block:: fortran
679
680      ! Full signature
681      subroutine adios2_perform_puts(engine, ierr)
682
683      ! WHERE:
684
685      ! engine handler
686      type(adios2_engine), intent(in) :: engine
687
688
689* :f90:`subroutine adios2_get` get variable data into adios2 for IO operations. Default is deferred mode, optional sync mode, see :ref:`Get: modes and memory contracts`. Variable and data types must match, variable can be obtained from ``adios2_inquire_variable``. Data must be pre-allocated.
690
691
692   .. code-block:: fortran
693
694      ! Full signature
695      subroutine adios2_get(engine, variable, data, adios2_mode, ierr)
696
697      ! Default adios2_mode_deferred
698      subroutine adios2_get(engine, variable, data, ierr)
699
700      ! WHERE:
701
702      ! engine handler
703      type(adios2_engine), intent(in) :: engine
704
705      ! variable handler containing metadata information
706      type(adios2_variable), intent(in) :: variable
707
708      ! Fortran bindings supports data types from adios2_type in variables,
709      ! up to 6 dimensions. Must be pre-allocated
710      ! Generic Fortran type from adios2_type
711      Generic Fortran types, intent(out):: data
712      Generic Fortran types, dimension(:), intent(out):: data
713      Generic Fortran types, dimension(:,:), intent(out):: data
714      Generic Fortran types, dimension(:,:,:), intent(out):: data
715      Generic Fortran types, dimension(:,:,:,:), intent(out):: data
716      Generic Fortran types, dimension(:,:,:,:,:), intent(out):: data
717      Generic Fortran types, dimension(:,:,:,:,:,:), intent(out):: data
718
719      ! mode:
720      ! adios2_mode_deferred: won't execute until adios2_end_step, adios2_perform_gets or adios2_close
721      ! adios2_mode_sync: special case, get data immediately, can be reused after this call
722      integer, intent(in):: adios2_mode
723
724
725* :f90:`subroutine adios2_perform_gets` executes deferred calls to ``adios2_get``
726
727   .. code-block:: fortran
728
729      ! Full signature
730      subroutine adios2_perform_gets(engine, ierr)
731
732      ! WHERE:
733
734      ! engine handler
735      type(adios2_engine), intent(in) :: engine
736
737
738* :f90:`subroutine adios2_close` closes engine, can't reuse unless is opened again
739
740   .. code-block:: fortran
741
742      ! Full signature
743      subroutine adios2_close(engine, ierr)
744
745      ! WHERE:
746
747      ! engine handler
748      type(adios2_engine), intent(in) :: engine
749
750
751