Ignore:
Timestamp:
07/15/19 12:29:31 (5 years ago)
Author:
adurocher
Message:

trunk : GPU implementation with OpenACC ( merge from glcp.idris.fr )

File:
1 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/trunk/src/vertical/disvert.f90

    r898 r953  
    11MODULE disvert_mod 
    22  USE icosa 
     3  USE abort_mod 
    34  REAL(rstd), SAVE, POINTER :: ap(:) 
    45!$OMP THREADPRIVATE(ap)  
     
    146147    END IF 
    147148 
     149    !$acc enter data copyin(ap(:), bp(:), mass_dak(:), mass_dbk(:)) async 
     150     
    148151  END SUBROUTINE init_disvert   
    149152   
    150   SUBROUTINE compute_rhodz(comp, ps, rhodz) 
     153  SUBROUTINE compute_rhodz(comp, ps, rhodz, ondevice) 
    151154    USE icosa 
    152155    USE omp_para 
     
    154157    REAL(rstd), INTENT(IN) :: ps(iim*jjm) 
    155158    REAL(rstd), INTENT(INOUT) :: rhodz(iim*jjm,llm) 
     159    LOGICAL, INTENT(IN), OPTIONAL :: ondevice ! .TRUE. compute on device, .FALSE. stay on host 
    156160    REAL(rstd) :: m, err 
    157161    INTEGER :: l,i,j,ij,dd 
     162    LOGICAL :: ondevice_ 
     163 
    158164    err=0. 
     165 
     166    ! by default, do not compute on device 
     167    ondevice_ = .FALSE. 
     168    IF (PRESENT(ondevice)) ondevice_ = ondevice 
    159169 
    160170    IF(comp) THEN 
     
    164174    END IF 
    165175 
     176    !$acc data present(ps(:), rhodz(:,:), ap(:), bp(:)) async if (ondevice_) 
     177 
    166178    IF(comp) THEN 
    167     DO l = ll_begin, ll_end 
    168        DO j=jj_begin-dd,jj_end+dd 
    169           DO i=ii_begin-dd,ii_end+dd 
    170              ij=(j-1)*iim+i 
    171              m = ( ap(l) - ap(l+1) + (bp(l)-bp(l+1))*ps(ij) )/g  
    172                 rhodz(ij,l) = m 
    173           ENDDO 
    174         ENDDO 
    175       ENDDO 
    176              ELSE 
     179      !$acc parallel loop collapse(3) async if (ondevice_) 
    177180      DO l = ll_begin, ll_end 
    178181        DO j=jj_begin-dd,jj_end+dd 
     
    180183            ij=(j-1)*iim+i 
    181184            m = ( ap(l) - ap(l+1) + (bp(l)-bp(l+1))*ps(ij) )/g 
    182                 err = MAX(err,abs(m-rhodz(ij,l))) 
     185            rhodz(ij,l) = m 
    183186          ENDDO 
    184        ENDDO 
    185     ENDDO 
    186  
    187        IF(err>1e-10) THEN 
     187        ENDDO 
     188      ENDDO 
     189    ELSE 
     190      !$acc parallel loop reduction(max:err) collapse(3) async if (ondevice_) 
     191      DO l = ll_begin, ll_end 
     192        DO j=jj_begin-dd,jj_end+dd 
     193          DO i=ii_begin-dd,ii_end+dd 
     194            ij=(j-1)*iim+i 
     195            m = ( ap(l) - ap(l+1) + (bp(l)-bp(l+1))*ps(ij) )/g 
     196            err = MAX(err,abs(m-rhodz(ij,l))) 
     197          ENDDO 
     198        ENDDO 
     199      ENDDO 
     200 
     201      !$acc wait 
     202      IF(err>1e-10) THEN 
    188203          PRINT *, 'Discrepancy between ps and rhodz detected', err 
    189204          STOP 
     
    191206    ENDIF 
    192207 
     208    !$acc end data 
    193209  END SUBROUTINE compute_rhodz 
    194210 
    195   
     211 
    196212  SUBROUTINE write_apbp 
    197213  USE icosa 
Note: See TracChangeset for help on using the changeset viewer.