3 use iso_c_binding
, only: c_int, c_char, c_null_char, c_size_t, c_ptrdiff_t, c_ptr, c_loc, c_sizeof, c_long
5 use netcdf
, only : nf90_char, nf90_byte, nf90_int, nf90_def_var, nf90_put_var, nf90_def_dim
13 use mpi
, only : mpi_in_place, mpi_int, mpi_long_long_int, mpi_sum, mpi_status_ignore, mpi_wait
27 use iso_c_binding
, only: c_int, c_size_t, c_char
29 integer(kind=c_int),
value :: ncid
30 character(kind=c_char),
intent(in) :: name(*)
31 integer(kind=c_size_t),
value :: nlen
32 integer(kind=c_int),
intent(inout) :: idp
33 integer(kind=c_int) :: nc_def_dim
38 use iso_c_binding
, only: c_int, c_ptr, c_char
40 integer(kind=c_int),
value :: ncid, varid
41 type(c_ptr),
value :: startp, countp, stridep
42 character(kind=c_char),
intent(in) :: op(*)
43 integer(kind=c_int) :: nc_put_vars_text
48 use iso_c_binding
, only: c_int, c_ptr, c_long
50 integer(kind=c_int),
value :: ncid, varid
51 type(c_ptr),
value :: indexp
52 integer(kind=c_long),
intent(in) :: op
53 integer(kind=c_int) :: nc_put_var1_long
57 function nc_def_var(ncid, name, xtype, ndims, dimidsp, varidp) bind(C)
58 use iso_c_binding
, only: c_int, c_char
60 integer(kind=c_int),
value :: ncid
61 character(kind=c_char),
intent(in) :: name(*)
62 integer(kind=c_int),
value :: xtype
63 integer(kind=c_int),
value :: ndims
64 integer(kind=c_int),
intent(in) :: dimidsp(*)
65 integer(kind=c_int),
intent(out) :: varidp
66 integer(kind=c_int) :: nc_def_var
75 character,
dimension(:),
allocatable,
intent(inout) :: byte_data
79 integer,
intent(in) :: timestep
102 prepare_to_serialise_writer_field_manager_state_arg, is_write_field_manager_up_to_date_arg)
107 integer(kind=c_size_t) :: size_t_test
113 if (c_sizeof(size_t_test) .lt. 8)
then 115 "Your system's size_t is not 64 bit, this will limit the size of IO server state storage to 4GB")
123 integer,
intent(in) :: timestep
135 type(
writer_type),
volatile,
dimension(:),
intent(inout) :: writer_entries
136 type(
hashmap_type),
volatile,
intent(inout) :: time_points
138 integer :: i, current_data_point, number_writer_entries_included, ierr, current_index
139 character,
dimension(:),
allocatable :: dvt_byte_data, temp
141 number_writer_entries_included=0
142 do i=1,
size(writer_entries)
143 if (writer_entries(i)%include_in_io_state_write) number_writer_entries_included=number_writer_entries_included+1
151 do i=1,
size(writer_entries)
152 if (writer_entries(i)%include_in_io_state_write)
then 154 current_index=current_index+1
179 real(kind=DEFAULT_PRECISION) :: r_value
190 character,
dimension(:),
allocatable,
intent(inout) :: byte_data
192 integer :: key, current_data_point
195 real(kind=DEFAULT_PRECISION) :: r_value
205 current_data_point=
pack_scalar_field(byte_data, current_data_point, double_real_value=r_value)
215 type(
writer_type),
volatile,
dimension(:),
intent(inout) :: writer_entries
216 type(
hashmap_type),
volatile,
intent(inout) :: time_points
219 integer :: ncdf_dimid, ncdf_varid, current_index, i
220 character,
dimension(:),
allocatable :: byte
226 size(io_configuration%text_configuration), ncdf_dimid))
227 call c_put_integer(netcdf_file%dimension_to_id,
"io_configuration_dim", ncdf_dimid)
229 call check_netcdf_status(nf90_def_var(netcdf_file%ncid,
"io_configuration", nf90_char, ncdf_dimid, ncdf_varid))
230 call c_put_integer(netcdf_file%variable_to_id,
"io_configuration", ncdf_varid)
232 call check_netcdf_status(nf90_def_dim(netcdf_file%ncid,
"entries_directory_dim", io_configuration%number_of_io_servers, &
235 call c_put_integer(netcdf_file%dimension_to_id,
"entries_directory_dim", ncdf_dimid)
240 do i=1,
size(writer_entries)
241 if (writer_entries(i)%include_in_io_state_write)
then 244 current_index=current_index+1
263 subroutine define_state_storage(netcdf_file, entries_directory_dim_id, base_key, expected_global_entries)
265 integer,
intent(in) :: entries_directory_dim_id
266 integer(kind=8),
intent(in) :: expected_global_entries
267 character(len=*),
intent(in) :: base_key
269 integer :: ncdf_varid
270 integer :: ncdf_dimid
271 integer(kind=c_int) :: cncid, cdimid, cvarid, cxtype, cnvdims
272 integer(kind=c_int) :: cvdims(1)
274 cncid = netcdf_file%ncid
276 cvdims(1)=entries_directory_dim_id-1
281 cnvdims, cvdims, cvarid))
284 call c_put_integer(netcdf_file%variable_to_id, trim(base_key)//
"_directory", ncdf_varid)
287 int(expected_global_entries, c_size_t), cdimid))
289 call c_put_integer(netcdf_file%dimension_to_id, trim(base_key)//
"_dim", ncdf_dimid)
290 call check_netcdf_status(nf90_def_var(netcdf_file%ncid, trim(base_key), nf90_char, ncdf_dimid, ncdf_varid))
291 call c_put_integer(netcdf_file%variable_to_id, trim(base_key), ncdf_varid)
304 type(
writer_type),
volatile,
dimension(:),
intent(inout) :: writer_entries
305 type(
hashmap_type),
volatile,
intent(inout) :: time_points
308 integer :: field_id, var_id, current_index, i
309 character,
dimension(:),
allocatable :: serialised_bytes
311 field_id=
c_get_integer(netcdf_file%variable_to_id,
"io_configuration")
313 if (io_configuration%my_io_rank == 0)
then 315 call check_netcdf_status(nf90_put_var(netcdf_file%ncid, field_id, io_configuration%text_configuration, &
316 count=(/
size(io_configuration%text_configuration)/)))
322 do i=1,
size(writer_entries)
323 if (writer_entries(i)%include_in_io_state_write)
then 327 "serialised_writer_entry_"//trim(
conv_to_string(i)), serialised_bytes)
328 deallocate(serialised_bytes)
329 current_index=current_index+1
336 "serialised_timeaveraged_manipulation", serialised_bytes)
337 deallocate(serialised_bytes)
342 "serialised_instantaneous_manipulation", serialised_bytes)
343 deallocate(serialised_bytes)
348 "serialised_writer_manager", serialised_bytes)
349 deallocate(serialised_bytes)
354 "serialised_timepoints", serialised_bytes)
355 deallocate(serialised_bytes)
367 subroutine write_state_storage(netcdf_file, writer_entry_start_point, my_io_rank, base_key, raw_byte_code)
369 integer,
intent(in) :: my_io_rank
370 integer(kind=8),
intent(in) :: writer_entry_start_point
371 character(len=*),
intent(in) :: base_key
372 character,
dimension(:),
intent(in) :: raw_byte_code
374 integer(kind=c_int) :: cncid, cvarid, cndims, cstat1, cstatus
375 integer(kind=c_size_t),
target :: cstart(1), ccounts(1)
376 integer(kind=c_ptrdiff_t),
target :: cstrides(1)
377 integer(kind=c_long) :: c_writer_corrected_start_point
378 type(c_ptr) :: cstartptr, ccountsptr, cstridesptr
380 cncid=netcdf_file%ncid
382 cvarid=
c_get_integer(netcdf_file%variable_to_id, trim(base_key)//
"_directory")-1
383 c_writer_corrected_start_point=(writer_entry_start_point-
size(raw_byte_code))+1
385 ccounts(1)=
size(raw_byte_code)
388 cstartptr=c_loc(cstart)
389 ccountsptr=c_loc(ccounts)
390 cstridesptr=c_loc(cstrides)
394 cvarid=
c_get_integer(netcdf_file%variable_to_id, trim(base_key))-1
395 cstart(1)=c_writer_corrected_start_point-1
ISO C binding interface for NetCDF put long scalar, needed to support putting longs into file...
Performs time averaged, time manipulation and only returns a value if the output frequency determines...
integer(kind=8), dimension(:), allocatable global_writer_entry_byte_size
subroutine, public set_serialise_write_field_manager_state(serialise_writer_field_manager_state_arg, prepare_to_serialise_writer_field_manager_state_arg, is_write_field_manager_up_to_date_arg)
Sets the procedure to call for serialises the field manager state, this is handled in this manner due...
character, dimension(:), allocatable serialised_writer_field_manager_state
logical function, public is_io_server_state_writer_ready(timestep)
Determines whether the IO server state writer is ready (i.e. state is at a specific level for the tim...
Puts an integer key-value pair into the map.
Overall IO configuration.
integer(kind=8), dimension(:), allocatable local_writer_entry_byte_size
integer, parameter, public log_error
Only log ERROR messages.
Performs instantaneous time manipulation and only returns a value if the output frequency determines ...
character, dimension(:), allocatable serialised_instantaneous_manipulation_state
integer(kind=8) function, public prepare_to_serialise_writer_type(writer_to_serialise)
Prepares to serialise the writer type by issuing locks and determining the size of serialised bytes n...
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
ISO C binding interface for NetCDF dimension definition, needed to support 64 bit lengths...
Abstraction layer around MPI, this issues and marshals the lower level communication details...
ISO C binding interface for NetCDF put variable text, needed to support 64 bit starts, counts and strides.
Contains common definitions for the data and datatypes used by MONC.
subroutine, public log_master_log(level, message)
Will log just from the master process.
A hashmap structure, the same as a map but uses hashing for greatly improved performance when storing...
Gets a specific integer element out of the list, stack, queue or map with the corresponding key...
Conversion between common inbuilt FORTRAN data types.
subroutine, public wait_for_mpi_request(request, status)
Waits for a specific MPI request to complete, either by managing thread safety and interleaving or ju...
Converts data types to strings.
integer global_writer_entry_byte_size_request
procedure(write_field_manager_determine_if_up_to_date), pointer is_write_field_manager_up_to_date
subroutine, public log_log(level, message, str)
Logs a message at the specified level. If the level is above the current level then the message is ig...
Writer types which are shared across writing functionality. Also includes serialisation functionality...
subroutine, public check_netcdf_status(status, found_flag)
Will check a NetCDF status and write to log_log error any decoded statuses. Can be used to decode whe...
subroutine, public write_io_server_state(io_configuration, writer_entries, time_points, netcdf_file)
Packags up and writes the actual IO server state into the NetCDF file. The act of serialisation will ...
This defines some constants and procedures that are useful to the IO server and clients that call it...
subroutine serialise_writer_entries_time_points(time_points, byte_data)
Serialises the writer entry time points which are held in a hashmap.
integer(kind=8), dimension(:), allocatable my_writer_entry_start_point
integer(kind=8) function, public prepare_to_serialise_instantaneous_state()
Prepares to serialise the instantaneous state, both determines the byte storage size and issues any l...
procedure(writer_field_manager_serialise_state), pointer serialise_writer_field_manager_state
Returns the number of elements in the collection.
integer(kind=8) function prepare_to_serialise_writer_entries_time_points(time_points)
Prepares to serialise the writer entry time points.
character, dimension(:), allocatable serialised_writer_entries_time_points
procedure(writer_field_manager_prepare_to_serialise_state), pointer prepare_to_serialise_writer_field_manager_state
subroutine, public unlock_mpi()
If we are explicitly managing MPI thread safety (SERIALIZED mode) then unlocks MPI.
Collection data structures.
integer, parameter, public log_warn
Log WARNING and ERROR messages.
subroutine, public serialise_time_averaged_state(byte_data)
Serialises the state of this manipulator so that it can be restarted later on. Releases any locks iss...
subroutine, public lock_mpi()
If we are explicitly managing MPI thread safety (SERIALIZED mode) then locks MPI. ...
character, dimension(:), allocatable serialised_timeaveraged_manipulation_state
subroutine, public serialise_instantaneous_state(byte_data)
Will serialise the state of this manipulator so that it can be later restarted. Any locks issued duri...
subroutine define_state_storage(netcdf_file, entries_directory_dim_id, base_key, expected_global_entries)
Defines some state storate for a specific facet of the IO server. This creates the directory (locatio...
subroutine, public serialise_writer_type(writer_to_serialise, byte_data)
Serialises a specific writer type into byte data (for storage or transmission.) Releases any locks is...
integer my_writer_entry_start_request
subroutine, public define_io_server_state_contributions(io_configuration, writer_entries, time_points, netcdf_file)
Defines the dimensions and variables in a NetCDF file that consitute the IO server current state...
subroutine prepare_io_server_state_storage(io_configuration, writer_entries, time_points)
Will determine the size of the package for different facets of the IO server state and kick off non-b...
NetCDF misc functionality which can be shared between modules that work with NetCDF files...
integer(kind=8) function, public prepare_to_serialise_time_averaged_state()
Prepares to serialise the time averaged state values. Both determines the storage size required and a...
Converts data types to integers.
subroutine write_state_storage(netcdf_file, writer_entry_start_point, my_io_rank, base_key, raw_byte_code)
Writes out the state for a specific facet into the NetCDF file. Note that this uses the ISO C binding...
Gets a specific double precision real element out of the list, stack, queue or map with the correspon...
Parses the XML configuration file to produce the io configuration description which contains the data...
ISO C binding interface for NetCDF define variable, needed to support defining a long scalar variable...
The IO server state module which will write out the current state of the IO server to a NetCDF file...
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, dimension(:), allocatable serialised_writer_entries