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