module io_dist 1,8
use shr_kind_mod
, only : r8 => shr_kind_r8, r4 => shr_kind_r4
use decompmodule
, only : decomptype
use dynamics_vars
, only : T_FVDYCORE_GRID
use dyn_internal_state
, only : get_dyn_state_grid
use abortutils
, only : endrun
use cam_logfile
, only : iulog
#if ( defined SPMD )
use mod_comm
, only: mp_sendirr, mp_recvirr, mp_sendirr_r4, mp_recvirr_r4, &
mp_sendirr_i4, mp_recvirr_i4
use parutilitiesmodule
, only: parpatterntype
#endif
implicit none
private
save
public :: &
fv_scatter_r4,&
fv_gather_r4, &
fv_read_r4, &
fv_write_r4, &
fv_scatter_r8,&
fv_gather_r8, &
fv_read_r8, &
fv_write_r8, &
fv_scatter_i4,&
fv_gather_i4, &
fv_read_i4
!====================================================================================
CONTAINS
!====================================================================================
subroutine fv_scatter_r8(pattern_type, bufres, lenarr, arr),4
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
real(r8) bufres(*) ! Array to scatter
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
real(r8), intent(out) :: arr(*) ! Array to be gathered
#else
real(r8), intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r8' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
#else
arr(1:lenarr) = bufres(1:lenarr)
#endif
return
end subroutine fv_scatter_r8
!====================================================================================
subroutine fv_gather_r8( pattern_type, arr, lenarr, bufres),4
!-----------------------------------------------------------------------
! Wrapper routine to write restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer lenarr ! Global size of array
#if defined( SPMD )
real(r8) arr(*) ! Array to be gathered
#else
real(r8) arr(lenarr) ! Array (SMP-only)
#endif
real(r8), intent(out) :: bufres(*) ! Gathered array
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#if ( defined SPMD )
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#if ( defined SPMD )
!
! Should check if this is a "gather" pattern
!
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r8' )
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
CALL mp_recvirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
endif ! grid%iam .lt. grid%npes_xy
#else
bufres(1:lenarr) = arr(1:lenarr)
#endif
return
end subroutine fv_gather_r8
!====================================================================================
subroutine fv_read_r8(iu, pattern_type, arr, lenarr),6
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
integer, intent(in) :: iu ! Logical unit
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
real(r8), intent(out) :: arr(*) ! Array to be gathered
#else
real(r8), intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
real(r8), allocatable :: bufres(:)
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r8' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam == 0) then
allocate (bufres(lenarr))
read (iu,iostat=ioerr) bufres
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_R8 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
else
allocate (bufres(1))
endif
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
deallocate (bufres)
#else
read (iu,iostat=ioerr) arr
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_R8 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
#endif
return
end subroutine fv_read_r8
!====================================================================================
subroutine fv_write_r8(iu, pattern_type, arr, lenarr),6
!-----------------------------------------------------------------------
! Wrapper routine to write restart binary file
!-----------------------------------------------------------------------
integer, intent(in) :: iu ! Logical unit
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer, intent(in) :: lenarr ! Global length of array
#if defined( SPMD )
real(r8) arr(*) ! Array to be gathered
#else
real(r8) arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#if ( defined SPMD )
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
real(r8), allocatable :: bufres(:)
#endif
!-----------------------------------------------------------------------
#if ( defined SPMD )
!
! Should check if this is a "gather" pattern
!
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r8' )
if ( grid%iam == 0 ) then
allocate( bufres(lenarr) )
else
allocate( bufres(1) )
endif
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
CALL mp_recvirr
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
endif ! grid%iam .lt. grid%npes_xy
if (grid%iam == 0) then
write (iu,iostat=ioerr) bufres
if (ioerr /= 0 ) then
write(iulog,*) 'FV_WRITE_R8 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
('FV_WRITE_R8')
end if
endif
deallocate( bufres )
#else
write (iu,iostat=ioerr) arr
if (ioerr /= 0 ) then
write(iulog,*) 'fv_write_r8 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
('FV_WRITE_R8')
end if
#endif
return
end subroutine fv_write_r8
!====================================================================================
subroutine fv_scatter_r4(pattern_type, bufres, lenarr, arr),4
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
real(r4) bufres(*) ! Array to scatter
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
real(r4), intent(out) :: arr(*) ! Array to be gathered
#else
real(r4), intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r4' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
#else
arr(1:lenarr) = bufres(1:lenarr)
#endif
return
end subroutine fv_scatter_r4
!====================================================================================
subroutine fv_gather_r4(pattern_type, arr, lenarr, bufres),4
!-----------------------------------------------------------------------
! Wrapper routine to write restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer lenarr ! Global size of array
#if defined( SPMD )
real(r4) arr(*) ! Array to be gathered
#else
real(r4) arr(lenarr) ! Array (SMP-only)
#endif
real(r4), intent(out) :: bufres(*) ! Gathered array
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#if ( defined SPMD )
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#if ( defined SPMD )
!
! Should check if this is a "gather" pattern
!
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r4' )
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
CALL mp_recvirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
endif ! grid%iam .lt. grid%npes_xy
#else
bufres(1:lenarr) = arr(1:lenarr)
#endif
return
end subroutine fv_gather_r4
!====================================================================================
subroutine fv_read_r4(iu, pattern_type, arr, lenarr),6
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
integer, intent(in) :: iu ! Logical unit
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
real(r4), intent(out) :: arr(*) ! Array to be gathered
#else
real(r4), intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
real(r4), allocatable :: bufres(:)
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r4' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam == 0) then
allocate (bufres(lenarr))
read (iu,iostat=ioerr) bufres
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_R4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
else
allocate (bufres(1))
endif
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
deallocate (bufres)
#else
read (iu,iostat=ioerr) arr
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_R4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
#endif
return
end subroutine fv_read_r4
!====================================================================================
subroutine fv_write_r4(iu, pattern_type, arr, lenarr),6
!-----------------------------------------------------------------------
! Wrapper routine to write restart binary file
!-----------------------------------------------------------------------
integer, intent(in) :: iu ! Logical unit
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer, intent(in) :: lenarr ! Global length of array
#if defined( SPMD )
real(r4) arr(*) ! Array to be gathered
#else
real(r4) arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#if ( defined SPMD )
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
real(r4), allocatable :: bufres(:)
#endif
!-----------------------------------------------------------------------
#if ( defined SPMD )
!
! Should check if this is a "gather" pattern
!
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'r4' )
if ( grid%iam == 0 ) then
allocate( bufres(lenarr) )
else
allocate( bufres(1) )
endif
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
CALL mp_recvirr_r4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
endif ! grid%iam .lt. grid%npes_xy
if (grid%iam == 0) then
write (iu,iostat=ioerr) bufres
if (ioerr /= 0 ) then
write(iulog,*) 'FV_WRITE_R4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
('FV_WRITE_R4')
end if
endif
deallocate( bufres )
#else
write (iu,iostat=ioerr) arr
if (ioerr /= 0 ) then
write(iulog,*) 'fv_write_r4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
('FV_WRITE_R4')
end if
#endif
return
end subroutine fv_write_r4
!====================================================================================
subroutine fv_scatter_i4(pattern_type, bufres, lenarr, arr),4
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer bufres(*) ! Array to scatter
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
integer, intent(out) :: arr(*) ! Array to be gathered
#else
integer, intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'i4' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
#else
arr(1:lenarr) = bufres(1:lenarr)
#endif
return
end subroutine fv_scatter_i4
!====================================================================================
subroutine fv_gather_i4(pattern_type, arr, lenarr, bufres),4
!-----------------------------------------------------------------------
! Wrapper routine to write restart binary file
!-----------------------------------------------------------------------
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer lenarr ! Global size of array
#if defined( SPMD )
integer arr(*) ! Array to be gathered
#else
integer arr(lenarr) ! Array (SMP-only)
#endif
integer, intent(out) :: bufres(*) ! Gathered array
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#if ( defined SPMD )
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
#endif
!-----------------------------------------------------------------------
#if ( defined SPMD )
!
! Should check if this is a "gather" pattern
!
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'i4' )
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
CALL mp_recvirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, arr, bufres, &
modc=grid%modc_gather )
endif ! grid%iam .lt. grid%npes_xy
#else
bufres(1:lenarr) = arr(1:lenarr)
#endif
return
end subroutine fv_gather_i4
!====================================================================================
subroutine fv_read_i4(iu, pattern_type, arr, lenarr),6
!-----------------------------------------------------------------------
! Wrapper routine to read real variable from restart binary file
!-----------------------------------------------------------------------
integer, intent(in) :: iu ! Logical unit
character(len=*), intent(in) :: pattern_type ! Type of comm pattern
integer, intent(in) :: lenarr ! Global size of array
#if defined( SPMD )
integer, intent(out) :: arr(*) ! Array to be gathered
#else
integer, intent(out) :: arr(lenarr) ! Array (SMP-only)
#endif
!---------------------------Local variables-----------------------------
integer ioerr ! errorcode
#ifdef SPMD
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
type (parpatterntype):: pattern ! Pattern descriptor
integer, allocatable :: bufres(:)
#endif
!-----------------------------------------------------------------------
#ifdef SPMD
grid => get_dyn_state_grid
()
pattern = get_pattern
( grid, pattern_type, 'i4' )
!
! Should check if this is a "scatter" pattern
!
if (grid%iam == 0) then
allocate (bufres(lenarr))
read (iu,iostat=ioerr) bufres
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_I4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
else
allocate (bufres(1))
endif
if (grid%iam .lt. grid%npes_xy) then
CALL mp_sendirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
CALL mp_recvirr_i4
(pattern%Comm, pattern%SendDesc, pattern%RecvDesc, bufres, arr, &
modc=grid%modc_scatter )
endif ! grid%iam .lt. grid%npes_xy
deallocate (bufres)
#else
read (iu,iostat=ioerr) arr
if (ioerr /= 0 ) then
write(iulog,*) 'FV_READ_I4 ioerror ',ioerr,' on i/o unit = ',iu
call endrun
end if
#endif
return
end subroutine fv_read_i4
!====================================================================================
function get_decomp( grid, type ) 7,10
! this utility function probably belongs where the decomptype objects are stored
type (T_FVDYCORE_GRID), pointer :: grid ! grid information
character(len=*), intent(in) :: type
type (decomptype) :: get_decomp ! Decomposition descriptor
select case (type)
case ('2d')
get_decomp = grid%strip2d
case ('3dxzy')
get_decomp = grid%strip3dxzy
case ('3dxzyp')
get_decomp = grid%strip3dxzyp
case ('3dxyz')
get_decomp = grid%strip3dxyz
case default
write(iulog,*)'get_decomp: invalid number decomposition type=', type
call endrun
()
end select
end function get_decomp
!====================================================================================
#if defined( SPMD )
function get_pattern( grid, type, data_type ) 11,7
! this utility function probably belongs where the decomptype objects are stored
type (T_FVDYCORE_GRID) :: grid ! grid information
character(len=*), intent(in) :: type
character(len=*), intent(in) :: data_type
type (ParPatternType) :: get_pattern ! grid information
select case (type)
case ('s_2dxy')
select case (data_type)
case ('r8')
get_pattern = grid%s_2dxy_r8
case ('r4')
get_pattern = grid%s_2dxy_r4
case ('i4')
get_pattern = grid%s_2dxy_i4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case ('s_3dxyz')
select case (data_type)
case ('r8')
get_pattern = grid%s_3dxyz_r8
case ('r4')
get_pattern = grid%s_3dxyz_r4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case ('s_3dxyzp')
select case (data_type)
case ('r8')
get_pattern = grid%s_3dxyzp_r8
case ('r4')
get_pattern = grid%s_3dxyzp_r4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case ('g_2dxy')
select case (data_type)
case ('r8')
get_pattern = grid%g_2dxy_r8
case ('r4')
get_pattern = grid%g_2dxy_r4
case ('i4')
get_pattern = grid%g_2dxy_i4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case ('g_3dxyz')
select case (data_type)
case ('r8')
get_pattern = grid%g_3dxyz_r8
case ('r4')
get_pattern = grid%g_3dxyz_r4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case ('g_3dxyzp')
select case (data_type)
case ('r8')
get_pattern = grid%g_3dxyzp_r8
case ('r4')
get_pattern = grid%g_3dxyzp_r4
case default
write(iulog,*)'get_pattern: ', data_type, ' not supported in decomposition ', type
call endrun
()
end select
case default
write(iulog,*)'get_pattern: invalid number decomposition type=', type
call endrun
()
end select
end function get_pattern
#endif
end module io_dist