8   use mpi
, only : mpi_character, mpi_int, mpi_logical, mpi_real, mpi_double_precision, mpi_address_kind
    17      character(len=STRING_LENGTH) :: field_name
    18      integer :: dimensions, dim_sizes(4)
    22      character(len=STRING_LENGTH) :: definition_name, field_name
    23      integer :: field_type, data_type
    28      character(len=STRING_LENGTH) :: definition_name
    29      logical :: send_on_terminate
    30      integer :: number_fields, frequency
    60     integer :: populate_mpi_type_extents(5)
    63     integer(kind=MPI_ADDRESS_KIND) :: large_number_extents(5)
    67     call mpi_type_extent(mpi_character, large_number_extents(
string_data_type), ierr)
    68     call mpi_type_extent(mpi_real, large_number_extents(
float_data_type), ierr)
    69     call mpi_type_extent(mpi_double_precision, large_number_extents(
double_data_type), ierr)
    71     populate_mpi_type_extents=int(large_number_extents)
    76     integer :: new_type, ierr, block_counts(4), old_types(4), offsets(4)
    77     integer(MPI_ADDRESS_KIND) :: num_addr, base_addr
    81     call mpi_get_address(basic_type, base_addr, ierr)
    82     old_types(1) = mpi_character
    86     call mpi_get_address(basic_type%send_on_terminate, num_addr, ierr)
    87     old_types(2) = mpi_logical
    89     offsets(2)=int(num_addr-base_addr)
    91     call mpi_get_address(basic_type%number_fields, num_addr, ierr)
    92     old_types(3) = mpi_int
    94     offsets(3)=int(num_addr-base_addr)
    96     call mpi_get_address(basic_type%frequency, num_addr, ierr)
    97     old_types(4) = mpi_int
    99     offsets(4)=int(num_addr-base_addr)
   101     call mpi_type_struct(4, block_counts, offsets, old_types, new_type, ierr) 
   102     call mpi_type_commit(new_type, ierr)
   108     integer :: new_type, ierr, old_types(5), block_counts(5), offsets(5)
   109     integer(MPI_ADDRESS_KIND) :: num_addr, base_addr
   113     call mpi_get_address(basic_type, base_addr, ierr)    
   114     old_types(1) = mpi_character
   118     call mpi_get_address(basic_type%field_name, num_addr, ierr)    
   119     old_types(2) = mpi_character
   121     offsets(2)=int(num_addr-base_addr)
   123     call mpi_get_address(basic_type%field_type, num_addr, ierr)
   124     old_types(3) = mpi_int
   126     offsets(3)=int(num_addr-base_addr)
   128     call mpi_get_address(basic_type%data_type, num_addr, ierr)
   129     old_types(4) = mpi_int
   131     offsets(4)=int(num_addr-base_addr)
   133     call mpi_get_address(basic_type%optional, num_addr, ierr)
   134     old_types(5) = mpi_logical
   136     offsets(5)=int(num_addr-base_addr)
   138     call mpi_type_struct(5, block_counts, offsets, old_types, new_type, ierr) 
   139     call mpi_type_commit(new_type, ierr)
   147     integer :: new_type, ierr, block_counts(3), old_types(3), offsets(3)
   148     integer(kind=MPI_ADDRESS_KIND) :: num_addr, base_addr
   152     call mpi_get_address(basic_type, base_addr, ierr)
   153     old_types(1) = mpi_character
   157     call mpi_get_address(basic_type%dimensions, num_addr, ierr)
   158     old_types(2) = mpi_int
   160     offsets(2)=int(num_addr-base_addr)
   162     call mpi_get_address(basic_type%dim_sizes, num_addr, ierr)    
   163     old_types(3) = mpi_int
   165     offsets(3)=int(num_addr-base_addr)
   167     call mpi_type_struct(3, block_counts, offsets, old_types, new_type, ierr) 
   168     call mpi_type_commit(new_type, ierr)
   185        type_extents, prev_data_type, type_index, old_types, offsets, block_counts)
   186     integer, 
intent(in) :: field_start, field_end, field_array_sizes, data_type, type_index, prev_data_type, type_extents(5)
   187     integer, 
intent(inout) :: old_types(20), offsets(20), block_counts(20)
   189     block_counts(type_index)=(field_end-field_start) + 1 + field_array_sizes
   191     if (type_index == 1) 
then   194       offsets(type_index)=offsets(type_index-1)+type_extents(prev_data_type) * block_counts(type_index-1)
   203     integer, 
intent(in) :: type_code
   223   integer function pack_map_field(buffer, start_offset, map_to_pack)
   224     character, 
dimension(:), 
intent(inout) :: buffer
   225     integer, 
intent(in) :: start_offset
   228     integer :: i, target_end, current_offset
   229     character(len=STRING_LENGTH) :: temp_string
   230     character(len=STRING_LENGTH), 
pointer :: sized_raw_character
   231     class(*), 
pointer :: raw_data, raw_to_string
   235     current_offset=start_offset
   239       temp_string=specific_mapentry%key
   241       buffer(current_offset:target_end)=transfer(temp_string, buffer(current_offset:target_end))
   242       current_offset=target_end+1
   245       raw_to_string=>raw_data
   246       select type (raw_data)
   255       type is(
character(len=*))
   257         temp_string=sized_raw_character
   260       buffer(current_offset:target_end)=transfer(temp_string, buffer(current_offset:target_end))
   261       current_offset=target_end+1
   272   integer function pack_array_field(buffer, start_offset, int_array, real_array_1d, real_array_2d, real_array_3d, real_array_4d)
   273     character, 
dimension(:), 
intent(inout) :: buffer
   274     integer, 
intent(in) :: start_offset
   275     integer, 
dimension(:), 
intent(in), 
optional :: int_array
   276     real(kind=DEFAULT_PRECISION), 
dimension(:), 
intent(in), 
optional :: real_array_1d
   277     real(kind=DEFAULT_PRECISION), 
dimension(:,:), 
intent(in), 
optional :: real_array_2d
   278     real(kind=DEFAULT_PRECISION), 
dimension(:,:,:), 
intent(in), 
optional :: real_array_3d
   279     real(kind=DEFAULT_PRECISION), 
dimension(:,:,:,:), 
intent(in), 
optional :: real_array_4d
   281     integer :: target_end
   283     if (
present(int_array)) 
then   284       target_end=start_offset+kind(int_array)*
size(int_array)-1    
   285       buffer(start_offset:target_end) = transfer(int_array, buffer(start_offset:target_end))
   286     else if (
present(real_array_1d)) 
then   287       target_end=start_offset+kind(real_array_1d)*
size(real_array_1d)-1    
   288       buffer(start_offset:target_end) = transfer(real_array_1d, buffer(start_offset:target_end))
   289     else if (
present(real_array_2d)) 
then   290       target_end=start_offset+kind(real_array_2d)*
size(real_array_2d)-1    
   291       buffer(start_offset:target_end) = transfer(real_array_2d, buffer(start_offset:target_end))
   292     else if (
present(real_array_3d)) 
then   293       target_end=start_offset+kind(real_array_3d)*
size(real_array_3d)-1    
   294       buffer(start_offset:target_end) = transfer(real_array_3d, buffer(start_offset:target_end))
   295     else if (
present(real_array_4d)) 
then   296       target_end=start_offset+kind(real_array_4d)*
size(real_array_4d)-1    
   297       buffer(start_offset:target_end) = transfer(real_array_4d, buffer(start_offset:target_end))
   310   integer function pack_scalar_field(buffer, start_offset, int_value, real_value, single_real_value, double_real_value, &
   311        string_value, logical_value)
   312     character, 
dimension(:), 
intent(inout) :: buffer
   313     integer, 
intent(in) :: start_offset
   314     integer, 
intent(in), 
optional :: int_value
   315     real(kind=DEFAULT_PRECISION), 
intent(in), 
optional :: real_value
   316     real(kind=SINGLE_PRECISION), 
intent(in), 
optional :: single_real_value
   317     real(kind=DOUBLE_PRECISION), 
intent(in), 
optional :: double_real_value
   318     character(len=*), 
intent(in), 
optional :: string_value
   319     logical, 
intent(in), 
optional :: logical_value
   321     integer :: target_end
   322     character(len=STRING_LENGTH) :: string_to_insert
   324     if (
present(int_value)) 
then   325       target_end=start_offset+kind(int_value)-1
   326       buffer(start_offset:target_end) = transfer(int_value, buffer(start_offset:target_end))
   327     else if (
present(real_value)) 
then   328       target_end=start_offset+kind(real_value)-1
   329       buffer(start_offset:target_end) = transfer(real_value, buffer(start_offset:target_end))
   330     else if (
present(single_real_value)) 
then   331       target_end=start_offset+kind(single_real_value)-1
   332       buffer(start_offset:target_end) = transfer(single_real_value, buffer(start_offset:target_end))
   333     else if (
present(double_real_value)) 
then   334       target_end=start_offset+kind(double_real_value)-1
   335       buffer(start_offset:target_end) = transfer(double_real_value, buffer(start_offset:target_end))
   336     else if (
present(string_value)) 
then   338       string_to_insert=string_value
   339       buffer(start_offset:target_end) = transfer(string_to_insert, buffer(start_offset:target_end))
   340     else if (
present(logical_value)) 
then   341       target_end=start_offset+kind(logical_value)-1
   342       buffer(start_offset:target_end) = transfer(logical_value, buffer(start_offset:target_end))
   344       target_end=start_offset-1
   357     character(len=*), 
intent(in) :: name
   360     do i=1,
size(descriptions)
   361       if (descriptions(i)%field_name == name) 
then   362         if (
present(field_description)) field_description=descriptions(i)
 
Gets a specific generic element out of the list, stack, queue or map with the corresponding key...
 
integer, parameter, public float_data_type
 
integer function, public get_mpi_datatype_from_internal_representation(type_code)
Gets the MPI datatype from out internal representation of the field data type (as in the configuratio...
 
integer, parameter, public array_field_type
 
integer, parameter, public boolean_data_type
 
character(len=string_length), parameter, public local_end_points_key
 
integer, parameter, public register_command
 
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data. 
 
integer, parameter, public command_tag
 
Contains common definitions for the data and datatypes used by MONC. 
 
A hashmap structure, the same as a map but uses hashing for greatly improved performance when storing...
 
Conversion between common inbuilt FORTRAN data types. 
 
integer, parameter, public double_data_type
 
character(len=string_length), parameter, public local_sizes_key
 
Converts data types to strings. 
 
integer, parameter, public single_precision
Single precision (32 bit) kind. 
 
integer, parameter, public inter_io_communication
Field type identifiers. 
 
integer, parameter, public double_precision
Double precision (64 bit) kind. 
 
integer, parameter, public string_data_type
 
This defines some constants and procedures that are useful to the IO server and clients that call it...
 
integer, parameter, public integer_data_type
 
integer function, public pack_map_field(buffer, start_offset, map_to_pack)
Packs a map into the send buffer. 
 
Collection data structures. 
 
integer, parameter, public data_command_start
 
integer, parameter, public string_length
Default length of strings. 
 
integer function, dimension(5), public populate_mpi_type_extents()
Provides the type extents of the types that we are using in construction of the MPI data type...
 
logical function, public get_data_description_from_name(descriptions, name, field_description)
Look up the data description that corresponds to a specific field keyed by its name. 
 
integer function, public build_mpi_type_definition_description()
Builds the MPI data type for sending data descriptions to registree MONCs. 
 
subroutine, public append_mpi_datatype(field_start, field_end, field_array_sizes, data_type, type_extents, prev_data_type, type_index, old_types, offsets, block_counts)
Appends the MPI datatype details to the block counts, old types and offsets arrays. This will lump together multiple concurrent fields with the same type. 
 
integer function, public pack_array_field(buffer, start_offset, int_array, real_array_1d, real_array_2d, real_array_3d, real_array_4d)
Packs an array field into the sending buffer. 
 
character(len=string_length), parameter, public number_q_indicies_key
 
integer, parameter, public scalar_field_type
 
integer function, public build_mpi_type_data_sizing_description()
Builds the MPI type used for sending to the IO server a description of the data, namely the size of t...
 
integer function, public build_mpi_type_field_description()
Builds the MPI data type for sending field descriptions to registree MONCs. 
 
integer, parameter, public map_field_type
Field data type identifiers. 
 
integer, parameter, public data_tag
 
integer, parameter, public deregister_command
 
integer function, public pack_scalar_field(buffer, start_offset, int_value, real_value, single_real_value, double_real_value, string_value, logical_value)
Packs the data of a scalar field into a buffer. 
 
character(len=string_length), parameter, public local_start_points_key