Commit 5c2fa93f authored by Romain Pennel's avatar Romain Pennel Committed by Thomas Dubos
Browse files

Backport from devel : introduce grid_type in TYPE(layout) and use it for...

Backport from devel : introduce grid_type in TYPE(layout) and use it for allocation and halo exchange
parent 1e6269a4
Pipeline #136182 failed with stages
in 11 minutes and 53 seconds
!=================== Original source is in jsrc/ =================
MODULE field_mod
USE genmod
USE prec, ONLY : rstd
USE layout_mod
IMPLICIT NONE
......@@ -35,27 +37,33 @@ MODULE field_mod
MODULE PROCEDURE getval_{{tn}}{{rk}}d
{%- endfor %} {%- endfor %}
END INTERFACE
! This module is PUBLIC, we do not want to propagate symbols from modules usedd at module level
PRIVATE :: allocate_field_, deallocate_field_
CONTAINS
!====================================== allocate_field ===================================
!====================================== PUBLIC : allocate_field ===================================
SUBROUTINE allocate_field_glo(field,field_type,data_type,dim3,dim4,name)
SUBROUTINE allocate_field_glo(field, field_type, data_type, dim3, dim4, name)
USE layout_mod, ONLY : layout => layout_glo
TYPE(t_field),POINTER :: field(:)
INTEGER,INTENT(IN) :: field_type
INTEGER,INTENT(IN) :: data_type
INTEGER,OPTIONAL :: dim3,dim4
IMPLICIT NONE
TYPE(t_field), POINTER :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
INTEGER :: ndom, ind
INTEGER :: ndom
LOGICAL, ALLOCATABLE :: assigned_dom(:)
ndom = SIZE(layout,1)
ALLOCATE(field(ndom))
DO ind=1,ndom
CALL allocate_field_(layout(ind,field_type), field(ind), field_type, data_type, dim3, dim4, name)
ENDDO
ALLOCATE(assigned_dom(ndom))
! ONLY the master thread is allowed to call this routine
ALLOCATE(field(ndom))
assigned_dom(:) = .TRUE.
CALL allocate_field_(layout(:,field_type), assigned_dom, field, field_type, data_type, dim3, dim4, name)
DEALLOCATE(assigned_dom)
END SUBROUTINE allocate_field_glo
......@@ -66,28 +74,23 @@ CONTAINS
TYPE(t_field), POINTER :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ndom, ind
INTEGER :: ndom
ndom = SIZE(layout,1)
!$OMP BARRIER
!$OMP MASTER
!$OMP BARRIER
!$OMP MASTER
ALLOCATE(field(ndom))
!$OMP END MASTER
!$OMP BARRIER
DO ind=1,ndom
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
CALL allocate_field_(layout(ind,field_type), field(ind), field_type, data_type, dim3, dim4, name, ondevice)
END DO
!$OMP BARRIER
!$OMP END MASTER
!$OMP BARRIER
CALL allocate_field_(layout(:,field_type), assigned_domain, field, field_type, data_type, dim3, dim4, name, ondevice)
!$OMP BARRIER
END SUBROUTINE allocate_field
SUBROUTINE allocate_fields(nfield,field,field_type,data_type,dim3,dim4,name, ondevice)
SUBROUTINE allocate_fields(nfield, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : layout
USE domain_mod, ONLY : assigned_domain
USE omp_para, ONLY : is_omp_level_master
......@@ -95,111 +98,127 @@ CONTAINS
TYPE(t_field), POINTER :: field(:,:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ndom, i, ind
INTEGER :: i, ndom
ndom = SIZE(layout,1)
!$OMP BARRIER
!$OMP MASTER
!$OMP BARRIER
!$OMP MASTER
ALLOCATE(field(ndom,nfield))
!$OMP END MASTER
!$OMP BARRIER
DO ind=1,ndom
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
DO i=1,nfield
CALL allocate_field_(layout(ind,field_type), field(ind,i),field_type, data_type, dim3, dim4, name, ondevice)
END DO
!$OMP END MASTER
!$OMP BARRIER
DO i=1,nfield
CALL allocate_field_(layout(:,field_type), assigned_domain, field(:,i), field_type, data_type, dim3, dim4, name, ondevice)
END DO
!$OMP BARRIER
!$OMP BARRIER
END SUBROUTINE allocate_fields
SUBROUTINE allocate_field_(layout, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : t_layout
!====================================== PRIVATE : allocate_field ===================================
SUBROUTINE allocate_field_(layout, assigned_dom, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : t_layout, order_ij_l_p, order_l_ij_p
USE domain_mod
USE omp_para
TYPE(t_layout) :: layout
TYPE(t_field) :: field
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
CHARACTER(*), OPTIONAL :: name
TYPE(t_layout), INTENT(IN) :: layout(:)
LOGICAL, INTENT(IN) :: assigned_dom(:)
TYPE(t_field) :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ij_size
IF(PRESENT(name)) THEN
field%name = name
ELSE
field%name = '(undefined)'
END IF
IF (PRESENT(dim4)) THEN
field%ndim=4
field%dim4=dim4
field%dim3=dim3
ELSE IF (PRESENT(dim3)) THEN
field%ndim=3
field%dim3=dim3
field%dim4=1
ELSE
field%ndim=2
field%dim3=1
field%dim4=1
ENDIF
field%data_type=data_type
field%field_type=field_type
ij_size = layout%ij_size
IF (data_type==type_integer) ALLOCATE(field%ival4d(ij_size, field%dim3, field%dim4))
IF (data_type==type_real) ALLOCATE(field%rval4d(ij_size, field%dim3, field%dim4))
IF (data_type==type_logical) ALLOCATE(field%lval4d(ij_size, field%dim3, field%dim4))
IF (field%ndim==3) THEN
IF (data_type==type_integer) field%ival3d => field%ival4d(:,:,1)
IF (data_type==type_real) field%rval3d => field%rval4d(:,:,1)
IF (data_type==type_logical) field%lval3d => field%lval4d(:,:,1)
ELSE IF (field%ndim==2) THEN
IF (data_type==type_integer) field%ival2d => field%ival4d(:,1,1)
IF (data_type==type_real) field%rval2d => field%rval4d(:,1,1)
IF (data_type==type_logical) field%lval2d => field%lval4d(:,1,1)
ENDIF
field%ondevice = .FALSE.
IF (PRESENT(ondevice)) THEN
IF (ondevice) CALL create_device_field(field)
END IF
INTEGER :: ind, ij_size
DO ind=1,SIZE(field)
IF (.NOT. assigned_dom(ind) .OR. .NOT. is_omp_level_master) CYCLE
IF(PRESENT(name)) THEN
field(ind)%name = name
ELSE
field(ind)%name = '(undefined)'
END IF
IF (PRESENT(dim4)) THEN
field(ind)%ndim=4
field(ind)%dim4=dim4
field(ind)%dim3=dim3
ELSE IF (PRESENT(dim3)) THEN
field(ind)%ndim=3
field(ind)%dim3=dim3
field(ind)%dim4=1
ELSE
field(ind)%ndim=2
field(ind)%dim3=1
field(ind)%dim4=1
ENDIF
field(ind)%data_type=data_type
field(ind)%field_type=field_type
ij_size = layout(ind)%ij_size
SELECT CASE( layout(ind)%index_order )
CASE( order_ij_l_p )
IF (data_type==type_integer) ALLOCATE(field(ind)%ival4d(ij_size, field(ind)%dim3, field(ind)%dim4))
IF (data_type==type_real) ALLOCATE(field(ind)%rval4d(ij_size, field(ind)%dim3, field(ind)%dim4))
IF (data_type==type_logical) ALLOCATE(field(ind)%lval4d(ij_size, field(ind)%dim3, field(ind)%dim4))
IF (field(ind)%ndim==2) THEN
IF (data_type==type_integer) field(ind)%ival2d => field(ind)%ival4d(:,1,1)
IF (data_type==type_real) field(ind)%rval2d => field(ind)%rval4d(:,1,1)
IF (data_type==type_logical) field(ind)%lval2d => field(ind)%lval4d(:,1,1)
ENDIF
CASE( order_l_ij_p )
IF (data_type==type_integer) ALLOCATE(field(ind)%ival4d(field(ind)%dim3, ij_size, field(ind)%dim4))
IF (data_type==type_real) ALLOCATE(field(ind)%rval4d(field(ind)%dim3, ij_size, field(ind)%dim4))
IF (data_type==type_logical) ALLOCATE(field(ind)%lval4d(field(ind)%dim3, ij_size, field(ind)%dim4))
IF (field(ind)%ndim==2) THEN
IF (data_type==type_integer) field(ind)%ival2d => field(ind)%ival4d(1,:,1)
IF (data_type==type_real) field(ind)%rval2d => field(ind)%rval4d(1,:,1)
IF (data_type==type_logical) field(ind)%lval2d => field(ind)%lval4d(1,:,1)
ENDIF
END SELECT
IF (field(ind)%ndim==3) THEN
IF (data_type==type_integer) field(ind)%ival3d => field(ind)%ival4d(:,:,1)
IF (data_type==type_real) field(ind)%rval3d => field(ind)%rval4d(:,:,1)
IF (data_type==type_logical) field(ind)%lval3d => field(ind)%lval4d(:,:,1)
END IF
field(ind)%ondevice = .FALSE.
IF (PRESENT(ondevice)) THEN
IF (ondevice) CALL create_device_field(field(ind))
END IF
END DO
END SUBROUTINE allocate_field_
!==================================== deallocate_field ===================================
!==================================== PUBLIC : deallocate_field ===================================
SUBROUTINE deallocate_field_glo(field)
USE domain_mod
IMPLICIT NONE
TYPE(t_field),POINTER :: field(:)
INTEGER :: ind
DO ind=1,ndomain_glo
CALL deallocate_field_(field(ind))
END DO
DEALLOCATE(field)
LOGICAL :: assigned_dom(ndomain_glo)
! ONLY the master thread is allowed to call this routine
CALL deallocate_field_(assigned_dom, field)
DEALLOCATE(field)
END SUBROUTINE deallocate_field_glo
SUBROUTINE deallocate_field(field)
USE domain_mod
USE omp_para
IMPLICIT NONE
TYPE(t_field),POINTER :: field(:)
INTEGER :: ind
!$OMP BARRIER
DO ind=1,ndomain
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
CALL deallocate_field_(field(ind))
END DO
CALL deallocate_field_(assigned_domain, field)
!$OMP BARRIER
!$OMP MASTER
DEALLOCATE(field)
......@@ -210,14 +229,12 @@ CONTAINS
SUBROUTINE deallocate_fields(field)
USE domain_mod
USE omp_para
TYPE(t_field),POINTER :: field(:,:)
INTEGER :: i, ind
IMPLICIT NONE
TYPE(t_field), POINTER :: field(:,:)
INTEGER :: i
!$OMP BARRIER
DO ind=1,ndomain
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
DO i=1,SIZE(field,2)
CALL deallocate_field_(field(ind,i))
END DO
DO i=1,SIZE(field,2)
CALL deallocate_field_(assigned_domain, field(:,i))
END DO
!$OMP BARRIER
!$OMP MASTER
......@@ -226,23 +243,31 @@ CONTAINS
!$OMP BARRIER
END SUBROUTINE deallocate_fields
SUBROUTINE deallocate_field_(field)
USE domain_mod
!==================================== PRIVATE : deallocate_field ===================================
SUBROUTINE deallocate_field_(assigned_dom, field)
USE omp_para
TYPE(t_field) :: field
IMPLICIT NONE
LOGICAL, INTENT(IN) :: assigned_dom(:)
TYPE(t_field) :: field(:)
INTEGER :: data_type
data_type=field%data_type
INTEGER :: ind
DO ind=1,SIZE(field)
IF (.NOT. assigned_dom(ind) .OR. .NOT. is_omp_level_master) CYCLE
data_type=field(ind)%data_type
{%- for tn, tln, tp in types %}
IF (data_type==type_{{tln}}) THEN
IF (field%ondevice) THEN
!$acc exit data delete(field%{{tn}}val4d(:,:,:))
IF (field(ind)%ondevice) THEN
!$acc exit data delete(field(ind)%{{tn}}val4d(:,:,:))
CONTINUE
END IF
DEALLOCATE(field%{{tn}}val4d)
DEALLOCATE(field(ind)%{{tn}}val4d)
END IF
{%- endfor %}
ENDDO
END SUBROUTINE deallocate_field_
!====================================== getval ===================================
......
!=================== Original source is in jsrc/ =================
MODULE field_mod
USE genmod
USE prec, ONLY : rstd
USE layout_mod
IMPLICIT NONE
......@@ -36,7 +38,7 @@ MODULE field_mod
MODULE PROCEDURE getval_l2d
MODULE PROCEDURE getval_l3d
MODULE PROCEDURE getval_l4d
END INTERFACE
END INTERFACE get_val
INTERFACE ASSIGNMENT(=)
MODULE PROCEDURE getval_r2d
......@@ -48,89 +50,34 @@ MODULE field_mod
MODULE PROCEDURE getval_l2d
MODULE PROCEDURE getval_l3d
MODULE PROCEDURE getval_l4d
END INTERFACE
END INTERFACE ASSIGNMENT(=)
! This module is PUBLIC, we do not want to propagate symbols from modules usedd at module level
PRIVATE :: allocate_field_, deallocate_field_
CONTAINS
!====================================== allocate_field ===================================
SUBROUTINE allocate_field_(layout, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : t_layout
USE omp_para
TYPE(t_layout) :: layout
TYPE(t_field) :: field
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ij_size
IF(PRESENT(name)) THEN
field%name = name
ELSE
field%name = '(undefined)'
END IF
IF (PRESENT(dim4)) THEN
field%ndim=4
field%dim4=dim4
field%dim3=dim3
ELSE IF (PRESENT(dim3)) THEN
field%ndim=3
field%dim3=dim3
field%dim4=1
ELSE
field%ndim=2
field%dim3=1
field%dim4=1
ENDIF
field%data_type=data_type
field%field_type=field_type
ij_size = layout%ij_size
IF (data_type==type_integer) ALLOCATE(field%ival4d(ij_size, field%dim3, field%dim4))
IF (data_type==type_real) ALLOCATE(field%rval4d(ij_size, field%dim3, field%dim4))
IF (data_type==type_logical) ALLOCATE(field%lval4d(ij_size, field%dim3, field%dim4))
IF (field%ndim==3) THEN
IF (data_type==type_integer) field%ival3d => field%ival4d(:,:,1)
IF (data_type==type_real) field%rval3d => field%rval4d(:,:,1)
IF (data_type==type_logical) field%lval3d => field%lval4d(:,:,1)
ELSE IF (field%ndim==2) THEN
IF (data_type==type_integer) field%ival2d => field%ival4d(:,1,1)
IF (data_type==type_real) field%rval2d => field%rval4d(:,1,1)
IF (data_type==type_logical) field%lval2d => field%lval4d(:,1,1)
ENDIF
field%ondevice = .FALSE.
IF (PRESENT(ondevice)) THEN
IF (ondevice) CALL create_device_field(field)
END IF
END SUBROUTINE allocate_field_
!====================================== PUBLIC : allocate_field ===================================
SUBROUTINE allocate_field_glo(field,field_type,data_type,dim3,dim4,name)
SUBROUTINE allocate_field_glo(field, field_type, data_type, dim3, dim4, name)
USE layout_mod, ONLY : layout => layout_glo
TYPE(t_field),POINTER :: field(:)
INTEGER,INTENT(IN) :: field_type
INTEGER,INTENT(IN) :: data_type
INTEGER,OPTIONAL :: dim3,dim4
IMPLICIT NONE
TYPE(t_field), POINTER :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
INTEGER :: ndom, ind
INTEGER :: ndom
LOGICAL, ALLOCATABLE :: assigned_dom(:)
ndom = SIZE(layout,1)
ALLOCATE(assigned_dom(ndom))
! ONLY the master thread is allowed to call this routine
ALLOCATE(field(ndom))
DO ind=1,ndom
CALL allocate_field_(layout(ind,field_type), field(ind), field_type, data_type, dim3, dim4, name)
ENDDO
assigned_dom(:) = .TRUE.
CALL allocate_field_(layout(:,field_type), assigned_dom, field, field_type, data_type, dim3, dim4, name)
DEALLOCATE(assigned_dom)
END SUBROUTINE allocate_field_glo
......@@ -141,28 +88,23 @@ CONTAINS
TYPE(t_field), POINTER :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ndom, ind
INTEGER :: ndom
ndom = SIZE(layout,1)
!$OMP BARRIER
!$OMP MASTER
ALLOCATE(field(ndom))
!$OMP END MASTER
!$OMP BARRIER
DO ind=1,ndom
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
CALL allocate_field_(layout(ind,field_type), field(ind), field_type, data_type, dim3, dim4, name, ondevice)
END DO
CALL allocate_field_(layout(:,field_type), assigned_domain, field, field_type, data_type, dim3, dim4, name, ondevice)
!$OMP BARRIER
END SUBROUTINE allocate_field
SUBROUTINE allocate_fields(nfield,field,field_type,data_type,dim3,dim4,name, ondevice)
SUBROUTINE allocate_fields(nfield, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : layout
USE domain_mod, ONLY : assigned_domain
USE omp_para, ONLY : is_omp_level_master
......@@ -170,10 +112,10 @@ CONTAINS
TYPE(t_field), POINTER :: field(:,:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3,dim4
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ndom, i, ind
INTEGER :: i, ndom
ndom = SIZE(layout,1)
......@@ -182,68 +124,115 @@ CONTAINS
ALLOCATE(field(ndom,nfield))
!$OMP END MASTER
!$OMP BARRIER
DO ind=1,ndom
IF (.NOT. assigned_domain(ind) .OR. .NOT. is_omp_level_master) CYCLE
DO i=1,nfield
CALL allocate_field_(layout(ind,field_type), field(ind,i),field_type, data_type, dim3, dim4, name, ondevice)
END DO
DO i=1,nfield
CALL allocate_field_(layout(:,field_type), assigned_domain, field(:,i), field_type, data_type, dim3, dim4, name, ondevice)
END DO
!$OMP BARRIER
END SUBROUTINE allocate_fields
!==================================== deallocate_field ===================================
SUBROUTINE deallocate_field_(field)
!====================================== PRIVATE : allocate_field ===================================
SUBROUTINE allocate_field_(layout, assigned_dom, field, field_type, data_type, dim3, dim4, name, ondevice)
USE layout_mod, ONLY : t_layout, order_ij_l_p, order_l_ij_p
USE domain_mod
USE omp_para
TYPE(t_field) :: field
INTEGER :: data_type
data_type=field%data_type
IF (data_type==type_real) THEN
IF (field%ondevice) THEN
!$acc exit data delete(field%rval4d(:,:,:))
CONTINUE
TYPE(t_layout), INTENT(IN) :: layout(:)
LOGICAL, INTENT(IN) :: assigned_dom(:)
TYPE(t_field) :: field(:)
INTEGER, INTENT(IN) :: field_type
INTEGER, INTENT(IN) :: data_type
INTEGER, OPTIONAL :: dim3, dim4
CHARACTER(*), OPTIONAL :: name
LOGICAL, INTENT(IN), OPTIONAL :: ondevice
INTEGER :: ind, ij_size
DO ind=1,SIZE(field)
IF (.NOT. assigned_dom(ind) .OR. .NOT. is_omp_level_master) CYCLE
IF(PRESENT(name)) THEN
field(ind)%name = name
ELSE
field(ind)%name = '(undefined)'
END IF
DEALLOCATE(field%rval4d)
END IF
IF (data_type==type_integer) THEN
IF (field%ondevice) THEN