MONC
|
Provides the mechanism for halo swapping. This module contains the functionality required to determine what messages get sent where, pack data up en mass, send and receive from neighbouring processes and unpack into the appropriate data locations. There is also some functionality to help local copying of data to corresponding locations. The idea is that the caller will determine the policy (i.e. exactly what fields are to be communicated) through procedure arguments and this mechanism can be used again and again. It implements bulk sending of all field data in one large message to reduce communication overhead. More...
Data Types | |
interface | copy_corners_to_halo_buffer_proc_interface |
interface | copy_fields_to_halo_buffer_proc_interface |
interface | copy_halo_buffer_to_corner_proc_interface |
interface | copy_halo_buffer_to_field_proc_interface |
interface | get_fields_per_halo_cell_proc_interface |
Procedure interfaces used to determine the policy (i.e. the fields) of halo swapping and. More... | |
interface | perform_local_data_copy_proc_interface |
Functions/Subroutines | |
subroutine, public | blocking_halo_swap (current_state, halo_swap_state, copy_to_halo_buffer, perform_local_data_copy, copy_from_halo_buffer, copy_corners_to_halo_buffer, copy_from_halo_buffer_to_corner, source_data) |
Performs the entire halo swap operation, this is simply a wrapper around the nonblocking initiate and complete procedures and saves the programmer from calling these directly if they do not wish to interleave any computation. More... | |
subroutine, public | complete_nonblocking_halo_swap (current_state, halo_swap_state, perform_local_data_copy, copy_from_halo_buffer, copy_from_halo_buffer_to_corner, source_data) |
This completes a nonblocking halo swap and it is only during this call that the data fields themselves are modified. This will perform local data copying, wait for all outstanding receives to complete, copy the received buffer data into the data and then wait for all outstanding sends to complete. More... | |
subroutine, public | initiate_nonblocking_halo_swap (current_state, halo_swap_state, copy_to_halo_buffer, copy_corners_to_halo_buffer, source_data) |
Initiates a non blocking halo swap, this registers the receive requests, copies data into the send buffer and then registers send requests for these. As far as this call is concerned, the data is immutable - no modifications will take place to it until the matching completion call is made. More... | |
subroutine, public | init_halo_communication (current_state, get_fields_per_halo_cell, halo_state, halo_depth, involve_corners) |
Initialises a halo swapping state, by determining the neighbours, size of data in each swap and allocating the required memory - which are communication buffers and request handles. All this information is placed into the returned state. More... | |
subroutine, public | finalise_halo_communication (halo_swap_state) |
Finalises the halo swap represented by the state by freeing up all the allocated memory. More... | |
subroutine, public | copy_buffer_to_corner (local_grid, halo_buffer, field_data, corner_loc, x_target_index, y_target_index, halo_page) |
Copies the received buffer for a specific field to the corresponding corner of that field. More... | |
subroutine, public | copy_buffer_to_field (local_grid, halo_buffer, field_data, dim, target_index, halo_page) |
Copies the received buffer for a specific field to the corresponding halo data of that prognostic field. More... | |
subroutine, public | copy_field_to_buffer (local_grid, halo_buffer, field_data, dim, source_index, halo_page) |
Copies prognostic field data to send buffer for specific field, dimension, halo cell. More... | |
subroutine, public | copy_corner_to_buffer (local_grid, halo_buffer, field_data, corner_loc, x_source_index, y_source_index, halo_page) |
Copies prognostic field corner data to send buffer for specific field. More... | |
subroutine, public | perform_local_data_copy_for_field (field_data, local_grid, my_rank, halo_depth, involve_corners) |
Will perform a a local copy for the halo data of a field. More... | |
integer function | get_number_communication_requests (halo_swap_neighbours, number_distinct_neighbours) |
Determines the overall number of communication requests, which is made up of normal halo swaps and potentially corner swaps too if that is enabled. More... | |
subroutine | determine_recv_and_send_sizes (local_grid, halo_swap_neighbours, number_distinct_neighbours, involve_corners) |
Determines the amount (in elements) of data that each neighbour will be sent and I will receive from in a halo swap. More... | |
integer function | determine_halo_corner_size (local_grid) |
Determine the halo corner size in elements. More... | |
integer function | determine_halo_corner_element_sizes (local_grid, pid) |
For a specific process id this determines the number of halo swap corner elements to involve in a communication. More... | |
integer function | get_number_of_processes_involved_in_communication (local_grid, my_rank, include_corners) |
Deduces the number of distinct neighbours that will be involved in a halo swap. This information is used to then allocate the appropriate amount of memory to store the neighbour halo swapping data structure. More... | |
type(neighbour_description_type) function, dimension(number_distinct_neighbours) | populate_halo_swap_neighbours (local_grid, my_rank, number_distinct_neighbours, involve_corners) |
Will populate the halo swap neighbour data strutures with appropriate neighbour pid and dimension numbers. More... | |
subroutine | deduce_halo_pages_per_neighbour (current_state, halo_swap_neighbours, number_distinct_neighbours, get_fields_per_halo_cell, fields_per_cell, halo_depth) |
Deduces the number of halo pages per neighbour halo swap and places this information in the appropriate data structures. We call a "page" of data the contiguous data of a field that we are going to send, such as halo 1 of w, halo 1 of zw and halo 2 of w (assuming these go to the same neighbour as 1) More... | |
subroutine | deduce_halo_corners_per_neighbour (current_state, halo_swap_neighbours, number_distinct_neighbours, fields_per_cell) |
Determines the number of halo corners to swap between specific neighours, this is similar to deducing the number of halo pages per neighbour, only it is for corners. More... | |
subroutine | allocate_halo_buffers_for_each_neighbour (local_grid, number_distinct_neighbours, halo_swap_neighbours) |
Allocates the locally stored halo buffers (send and receive) for each neighbouring process. More... | |
subroutine | generate_recv_field_buffer_matches (current_state, halo_depth, cell_match) |
Precalculates the received buffer to field halo cell matches for each dimension and called from the initialisation stage. More... | |
subroutine | recv_all_halos (current_state, halo_swap_state) |
Registers receive requests for all prognostic fields from the appropriate neighbouring processes (that we have already deduced in the initialisation stage.) More... | |
subroutine | send_all_halos (current_state, halo_swap_state, copy_fields_to_halo_buffer, copy_corner_fields_to_halo_buffer, source_data) |
Copies all applicable bits of the prognostics into a send buffer for each neighbour and then issues asynchronous sends of this data. More... | |
subroutine | copy_buffer_data_for_prognostics (current_state, halo_swap_state, copy_halo_buffer_to_field, copy_halo_buffer_to_corner, source_data) |
Copies the received data (held in buffers) from neighbours into the correct halo location in the prognostic fields. More... | |
subroutine | perform_local_data_copy_for_corners (my_rank, local_grid, field_data) |
Performs a local data copy for corners when the neighbour is local (me) More... | |
subroutine | perform_local_data_copy_for_dimension (dim, my_rank, halo_depth, local_grid, field_data) |
Performs a local data copy for a specific dimension of a prognostic field. More... | |
logical function, dimension(3) | retrieve_same_neighbour_information (local_grid) |
Retrieves whether we have the same neighbours for L and R halo swaps in each dimension. More... | |
logical function | has_pid_already_been_seen (temp_neighbour_pids, pid) |
Returns whether or not a specific process id has already been "seen" by searching a list of already seen process ids. More... | |
integer function | get_pid_neighbour_location (halo_swap_neighbours, pid, number_distinct_neighbours) |
Given the process id of a neighbour this determines the location in the data structure of corresponding data for that. Note that this is an O(n) operation so ideally call once and reuse the results. If no process id is found then returns -1. More... | |
integer function, public | get_single_field_per_halo_cell (current_state) |
A very common function, which returns a single field per halo cell which is used to halo swap just one field. More... | |
Provides the mechanism for halo swapping. This module contains the functionality required to determine what messages get sent where, pack data up en mass, send and receive from neighbouring processes and unpack into the appropriate data locations. There is also some functionality to help local copying of data to corresponding locations. The idea is that the caller will determine the policy (i.e. exactly what fields are to be communicated) through procedure arguments and this mechanism can be used again and again. It implements bulk sending of all field data in one large message to reduce communication overhead.
|
private |
Allocates the locally stored halo buffers (send and receive) for each neighbouring process.
local_grid | Description of the local grid |
halo_swap_neighbours | My neighbouring PIDs |
number_distinct_neighbours | The number of distinct neighbours that I have |
Definition at line 755 of file halocommunication.F90.
subroutine, public halo_communication_mod::blocking_halo_swap | ( | type(model_state_type), intent(inout) | current_state, |
type(halo_communication_type), intent(inout) | halo_swap_state, | ||
procedure(copy_fields_to_halo_buffer_proc_interface) | copy_to_halo_buffer, | ||
procedure(perform_local_data_copy_proc_interface) | perform_local_data_copy, | ||
procedure(copy_halo_buffer_to_field_proc_interface) | copy_from_halo_buffer, | ||
procedure(copy_corners_to_halo_buffer_proc_interface), optional | copy_corners_to_halo_buffer, | ||
procedure(copy_halo_buffer_to_corner_proc_interface), optional | copy_from_halo_buffer_to_corner, | ||
type(field_data_wrapper_type), dimension(:), intent(in), optional | source_data | ||
) |
Performs the entire halo swap operation, this is simply a wrapper around the nonblocking initiate and complete procedures and saves the programmer from calling these directly if they do not wish to interleave any computation.
current_state | The current model state |
halo_swap_state | The halo swapping state |
copy_to_halo_buffer | Procedure pointer which is called to copy the data into the halo send buffer |
perform_local_data_copy | Procedure pointer which performs local data copying (where the neighbour is the local process) |
copy_from_halo_buffer | Procedure pointer which copies received data from the halo buffer into the field |
copy_corners_to_halo_buffer | Optional procedure pointer which copies data in corners to the halo send buffer |
copy_from_halo_buffer_to_corner | Optional procedure pointer which copies received data into halo corners |
source_data | Optional source data which is read from into send buffers and written into by receieve buffers |
Definition at line 109 of file halocommunication.F90.
subroutine, public halo_communication_mod::complete_nonblocking_halo_swap | ( | type(model_state_type), intent(inout) | current_state, |
type(halo_communication_type), intent(inout) | halo_swap_state, | ||
procedure(perform_local_data_copy_proc_interface) | perform_local_data_copy, | ||
procedure(copy_halo_buffer_to_field_proc_interface) | copy_from_halo_buffer, | ||
procedure(copy_halo_buffer_to_corner_proc_interface), optional | copy_from_halo_buffer_to_corner, | ||
type(field_data_wrapper_type), dimension(:), intent(in), optional | source_data | ||
) |
This completes a nonblocking halo swap and it is only during this call that the data fields themselves are modified. This will perform local data copying, wait for all outstanding receives to complete, copy the received buffer data into the data and then wait for all outstanding sends to complete.
current_state | The current model state |
halo_swap_state | The halo swapping state |
perform_local_data_copy | Procedure pointer which performs local data copying (where the neighbour is the local process) |
copy_from_halo_buffer | Procedure pointer which copies received data from the halo buffer into the field |
copy_from_halo_buffer_to_corner | Optional procedure pointer which copies halo data into field corners |
source_data | Optional source data which is read from into send buffers and written into by receieve buffers |
Definition at line 179 of file halocommunication.F90.
|
private |
Copies the received data (held in buffers) from neighbours into the correct halo location in the prognostic fields.
current_state | The current model state |
halo_swap_state | The halo swapping state |
copy_halo_buffer_to_field | Procedure pointer which copies the halo buffer into the data field |
copy_halo_buffer_to_corner | Optional procedure pointer to copy halo buffer into field corners |
source_data | Optional source data which is read from into send buffers and written into by receieve buffers |
Definition at line 969 of file halocommunication.F90.
subroutine, public halo_communication_mod::copy_buffer_to_corner | ( | type(local_grid_type), intent(inout) | local_grid, |
real(kind=default_precision), dimension(:,:,:), intent(inout) | halo_buffer, | ||
real(kind=default_precision), dimension(:,:,:), intent(inout) | field_data, | ||
integer, intent(in) | corner_loc, | ||
integer, intent(in) | x_target_index, | ||
integer, intent(in) | y_target_index, | ||
integer, intent(in) | halo_page | ||
) |
Copies the received buffer for a specific field to the corresponding corner of that field.
local_grid | Description of the local grid |
halo_buffer | Raw halo buffer data |
field_data | Raw prognostic field data |
corner_loc | Location of the corner |
x_target_index | The X target index that we copy into |
y_target_index | The Y target index that we copy into |
halo_page | The halo page to read from |
Definition at line 366 of file halocommunication.F90.
subroutine, public halo_communication_mod::copy_buffer_to_field | ( | type(local_grid_type), intent(inout) | local_grid, |
real(kind=default_precision), dimension(:,:,:), intent(inout) | halo_buffer, | ||
real(kind=default_precision), dimension(:,:,:), intent(inout) | field_data, | ||
integer, intent(in) | dim, | ||
integer, intent(in) | target_index, | ||
integer, intent(in) | halo_page | ||
) |
Copies the received buffer for a specific field to the corresponding halo data of that prognostic field.
local_grid | Description of the local grid |
halo_buffer | Raw halo buffer data |
field_data | Raw prognostic field data |
dim | The dimension to copy into |
target_index | The target index in the dimension that we copy into |
halo_page | The halo page to read from |
Definition at line 399 of file halocommunication.F90.
subroutine, public halo_communication_mod::copy_corner_to_buffer | ( | type(local_grid_type), intent(inout) | local_grid, |
real(kind=default_precision), dimension(:,:,:), intent(inout) | halo_buffer, | ||
real(kind=default_precision), dimension(:,:,:), intent(inout) | field_data, | ||
integer, intent(in) | corner_loc, | ||
integer, intent(in) | x_source_index, | ||
integer, intent(in) | y_source_index, | ||
integer, intent(in) | halo_page | ||
) |
Copies prognostic field corner data to send buffer for specific field.
local_grid | Description of the local grid |
halo_buffer | Raw halo_buffer data that is written to |
field_data | Raw prognostic field data that is read from |
corner_loc | Location of the corner |
x_source_index | The X index in the read dimension |
y_source_index | The Y index in the read dimension |
halo_page | The halo buffer page to write to |
Definition at line 459 of file halocommunication.F90.
subroutine, public halo_communication_mod::copy_field_to_buffer | ( | type(local_grid_type), intent(inout) | local_grid, |
real(kind=default_precision), dimension(:,:,:), intent(inout) | halo_buffer, | ||
real(kind=default_precision), dimension(:,:,:), intent(inout) | field_data, | ||
integer, intent(in) | dim, | ||
integer, intent(in) | source_index, | ||
integer, intent(in) | halo_page | ||
) |
Copies prognostic field data to send buffer for specific field, dimension, halo cell.
local_grid | Description of the local grid |
halo_buffer | Raw halo_buffer data that is written to |
field_data | Raw prognostic field data that is read from |
dim | Dimension that we are reading from |
source_index | The index in the read dimension |
halo_page | The halo buffer page to write to |
Definition at line 431 of file halocommunication.F90.
|
private |
Determines the number of halo corners to swap between specific neighours, this is similar to deducing the number of halo pages per neighbour, only it is for corners.
current_state | The current model state |
halo_swap_neighbours | Description of neighbouring halo swap state |
number_distinct_neighbours | The number of distinct neighbours that I swap with |
fields_per_cell | The number of fields per cell is written into here |
Definition at line 730 of file halocommunication.F90.
|
private |
Deduces the number of halo pages per neighbour halo swap and places this information in the appropriate data structures. We call a "page" of data the contiguous data of a field that we are going to send, such as halo 1 of w, halo 1 of zw and halo 2 of w (assuming these go to the same neighbour as 1)
current_state | The current model state |
halo_swap_neighbours | My neighbouring PIDs |
number_distinct_neighbours | The number of distinct neighbours that I have |
get_fields_per_halo_cell | Procedure pointer to get the number of fields per halo cell |
fields_per_cell | The number of fields per cell is written into here |
Definition at line 696 of file halocommunication.F90.
|
private |
For a specific process id this determines the number of halo swap corner elements to involve in a communication.
local_grid | The local grid |
pid | The process id that this calculation is based upon @reterns The number of elements involved in a specific corner halo swap |
Definition at line 575 of file halocommunication.F90.
|
private |
Determine the halo corner size in elements.
local_grid | The local grid |
pid | The process id that this calculation is based upon @reterns The number of elements involved in a specific corner halo swap |
Definition at line 563 of file halocommunication.F90.
|
private |
Determines the amount (in elements) of data that each neighbour will be sent and I will receive from in a halo swap.
local_grid | The local grid |
halo_swap_neighbours | Structure describing state of halo swap neighbours |
number_distinct_neighbours | The number of distinct neighbours I swap with |
involve_corners | Whether or not to involve corners in a halo swap |
Definition at line 527 of file halocommunication.F90.
subroutine, public halo_communication_mod::finalise_halo_communication | ( | type(halo_communication_type), intent(inout) | halo_swap_state | ) |
Finalises the halo swap represented by the state by freeing up all the allocated memory.
halo_swap_state | State of the specific halo swap |
Definition at line 339 of file halocommunication.F90.
|
private |
Precalculates the received buffer to field halo cell matches for each dimension and called from the initialisation stage.
current_state | The current model state |
halo_depth | The halo depth |
cell_match | The matching cells are written into here |
Definition at line 789 of file halocommunication.F90.
|
private |
Determines the overall number of communication requests, which is made up of normal halo swaps and potentially corner swaps too if that is enabled.
halo_swap_neighbours | Neighbouring halo swap state |
number_distinct_neighbours | The number of distinct neighours that I will swap with |
Definition at line 505 of file halocommunication.F90.
|
private |
Deduces the number of distinct neighbours that will be involved in a halo swap. This information is used to then allocate the appropriate amount of memory to store the neighbour halo swapping data structure.
local_grid | Description of the local grid |
my_rank | My global PID |
include_corners | Whether to include corners or not |
Definition at line 601 of file halocommunication.F90.
|
private |
Given the process id of a neighbour this determines the location in the data structure of corresponding data for that. Note that this is an O(n) operation so ideally call once and reuse the results. If no process id is found then returns -1.
halo_swap_neighbours | PIDs of the neighbouring processes to me |
pid | The process id to find |
number_distinct_neighbours | The number of distinct neighbours I have |
Definition at line 1209 of file halocommunication.F90.
integer function, public halo_communication_mod::get_single_field_per_halo_cell | ( | type(model_state_type), intent(inout) | current_state | ) |
A very common function, which returns a single field per halo cell which is used to halo swap just one field.
current_state | The current model state |
Definition at line 1229 of file halocommunication.F90.
|
private |
Returns whether or not a specific process id has already been "seen" by searching a list of already seen process ids.
temp_neighbour_pids | The process Ids already seen |
pid | The PID to search for |
Definition at line 1187 of file halocommunication.F90.
subroutine, public halo_communication_mod::init_halo_communication | ( | type(model_state_type), intent(inout) | current_state, |
procedure(get_fields_per_halo_cell_proc_interface) | get_fields_per_halo_cell, | ||
type(halo_communication_type), intent(out) | halo_state, | ||
integer, intent(in) | halo_depth, | ||
logical, intent(in) | involve_corners | ||
) |
Initialises a halo swapping state, by determining the neighbours, size of data in each swap and allocating the required memory - which are communication buffers and request handles. All this information is placed into the returned state.
current_state | The current model state |
get_fields_per_halo_cell | Procedure pointer to the procedure which determines how many fields per halo cell there are |
involve_corners | Whether this involves corners or not |
Definition at line 293 of file halocommunication.F90.
subroutine, public halo_communication_mod::initiate_nonblocking_halo_swap | ( | type(model_state_type), intent(inout) | current_state, |
type(halo_communication_type), intent(inout) | halo_swap_state, | ||
procedure(copy_fields_to_halo_buffer_proc_interface) | copy_to_halo_buffer, | ||
procedure(copy_corners_to_halo_buffer_proc_interface), optional | copy_corners_to_halo_buffer, | ||
type(field_data_wrapper_type), dimension(:), intent(in), optional | source_data | ||
) |
Initiates a non blocking halo swap, this registers the receive requests, copies data into the send buffer and then registers send requests for these. As far as this call is concerned, the data is immutable - no modifications will take place to it until the matching completion call is made.
current_state | The current model state |
halo_swap_state | The halo swapping state |
copy_to_halo_buffer | Procedure pointer which is called to copy the data into the halo send buffer |
copy_corners_to_halo_buffer | Optional procedure pointer which copies field corners into halo buffer |
source_data | Optional source data which is read from into send buffers and written into by receieve buffers |
Definition at line 243 of file halocommunication.F90.
|
private |
Performs a local data copy for corners when the neighbour is local (me)
my_rank | My global rank |
local_grid | The local grid |
field_data | The field data top copy into |
Definition at line 1041 of file halocommunication.F90.
|
private |
Performs a local data copy for a specific dimension of a prognostic field.
dim | The dimension |
my_rank | My process Id |
local_grid | The local grid description |
field_data | The field data that we are going to copy from and to |
Definition at line 1104 of file halocommunication.F90.
subroutine, public halo_communication_mod::perform_local_data_copy_for_field | ( | real(kind=default_precision), dimension(:,:,:), intent(inout) | field_data, |
type(local_grid_type), intent(inout) | local_grid, | ||
integer, intent(in) | my_rank, | ||
integer, intent(in) | halo_depth, | ||
logical, intent(in) | involve_corners | ||
) |
Will perform a a local copy for the halo data of a field.
field_data | The field data to perform the copy for |
local_grid | Local grid information |
my_rank | My process id |
Definition at line 481 of file halocommunication.F90.
|
private |
Will populate the halo swap neighbour data strutures with appropriate neighbour pid and dimension numbers.
local_grid | Description of the local grid |
my_rank | My global PID |
number_distinct_neighbours | The number of distinct neighbours that I have |
include_corners | Whether to include corners or not |
Definition at line 646 of file halocommunication.F90.
|
private |
Registers receive requests for all prognostic fields from the appropriate neighbouring processes (that we have already deduced in the initialisation stage.)
current_state | The current model state |
halo_swap_state | The halo swap state |
Definition at line 821 of file halocommunication.F90.
|
private |
Retrieves whether we have the same neighbours for L and R halo swaps in each dimension.
This is because if we do then the data storage needs to be reversed - i.e. the first two messages sent to this process are Left and the second two are Right, but due to wrapping around, the L messages need to be put on the right halo and R messages on the left halo
neighbours | The neighbouring processes in each dimension |
Definition at line 1159 of file halocommunication.F90.
|
private |
Copies all applicable bits of the prognostics into a send buffer for each neighbour and then issues asynchronous sends of this data.
current_state | The current model state |
halo_swap_state | The halo swap state |
copy_fields_to_halo_buffer | Procedure pointer to copy the data from the fields into the send buffer |
copy_corner_fields_to_halo_buffer | Optional procedure pointer to copy corner fields into halo send buffer |
source_data | Optional field data that can be copied from (passed to the user procedure) |
Definition at line 858 of file halocommunication.F90.