Hi,
I have a question about parallelization of nested loops inside which procedures in derived type data are used. A template of my code is formulated and shown below:
do k = bound%idx_min(3), bound%idx_max(3)
do j = bound%idx_min(2), bound%idx_max(2)
do i = bound%idx_min(1), bound%idx_max(1)
call find_bc_indicies_from_cell( [i,j,k], bound%face_label, &
bound%gc_stencil_size, &
low_idx, high_idx, dir )
call find_bc_normal_from_cell( [i,j,k], bound%face_label, gblock, &
normal )
call bound%fill_ghost_cells( &
normal, &
sblock%rho( low_idx(1):high_idx(1):dir(1), &
low_idx(2):high_idx(2):dir(2), &
low_idx(3):high_idx(3):dir(3) ), &
sblock%vel( :, low_idx(1):high_idx(1):dir(1), &
low_idx(2):high_idx(2):dir(2), &
low_idx(3):high_idx(3):dir(3) ), &
sblock%p( low_idx(1):high_idx(1):dir(1), &
low_idx(2):high_idx(2):dir(2), &
low_idx(3):high_idx(3):dir(3) ), &
sblock%temp( low_idx(1):high_idx(1):dir(1), &
low_idx(2):high_idx(2):dir(2), &
low_idx(3):high_idx(3):dir(3) ) )
end do
end do
end do
I want to parallelize this nested loop with three layers, however I found that I need to call bound%fill_ghost_cells but bound is an derived type data (declared as “class(bc_t), pointer :: bound”) and class bc_t is defined as:
type, abstract :: bc_t
! Is this boundary connected to another boundary
logical :: is_connected = .false.
logical :: overwrites_flux = .false.
! True = this BC calculates its own flux at boundary face
! False = this BC uses MUSCL to calculate flux at boundary face
integer :: block_id = -1 ! What parent block this is on
integer :: bc_label = -1 ! What bc type this is
integer :: face_label = -1 ! What face this is on
! Number of interior cells in the stencil to fill the GCs
integer :: gc_stencil_size = -1
! Indicies of the interior cells that are along this boundary
integer, dimension(3) :: idx_min = -1
integer, dimension(3) :: idx_max = -1
! Out direction of this face
integer, dimension(3) :: out_dir
! Information about neighbor
type(nbor_info_t) :: nbor
contains
private
! Common Procedures
procedure, public, pass :: init_bc
procedure, public, pass :: fill_nbor_info
procedure, public, pass :: is_xi_face
procedure, public, pass :: is_eta_face
procedure, public, pass :: is_zeta_face
procedure, public, pass :: is_min_face
procedure, public, pass :: find_nbor_idx
procedure, public, pass :: find_my_idx
procedure, public, nopass :: extrapolate_through_face_to_gc1
procedure, public, nopass :: extrapolate_state_to_gc
procedure, public, nopass :: gc_from_face_jacobians
! Deferred Procedures
procedure(fill_gc_i), public, deferred, pass :: fill_ghost_cells
procedure(gc_jacobians_i), public, deferred, pass :: ghost_cell_jacobians
! Procedures which are not implemented in general but are overwritten if
! this%overwrites_flux
procedure, public, pass :: boundary_flux
procedure, public, pass :: boundary_flux_jacobians
end type bc_t
type :: bc_holder_t
class(bc_t), allocatable :: bc
end type
Here you can see that fill_ghost_cells is a deferred procedure in bc_t. My concern is: if I directly parallize this nested loop, would there be an segmentation fault? And, does OpenACC support calling procedures inside a derived type data? If not, then how should I tackle with this situation? I am a beginner of OpenACC, and I would greatly appreciuate any help! Thanks a lot!