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