GEOS-ESM / NDSL

NOAA NASA Domain Specific Language middleware layer
0 stars 0 forks source link

True mixed precision #55

Closed FlorianDeconinck closed 15 hours ago

FlorianDeconinck commented 4 months ago

The Aer Activation port shows the usage of 64-bit literals in an otherwise 32-bit code

Until now we were operating under the assumption of a fully 32-bit or fully 64-bit precision calculation, with the exception of the occasional upcasting of a Field to keep precision up.

With this finding, we are back to the drawing board.

Fortran uses a "variable precision is the precision of the operation" technique to define ops precision between literals and variables. We could try to replicate this in GT4Py/DaCe to force "best precision" on single ops.

Another option is to work at NDSL level and have an override on a particular stencil to be at 64-bit, if GT4Py/DaCe allows for it.

Parent: https://github.com/GEOS-ESM/SMT-Nebulae/issues/36


FlorianDeconinck commented 1 month ago

Use case in UW

subroutine conden(p,thl,qt,th,qv,ql,qi,rvls,id_check)

      implicit none

      real, intent(in)     :: p
      real, intent(in)     :: thl
      real, intent(in)     :: qt
      real, intent(out)    :: th
      real, intent(out)    :: qv
      real, intent(out)    :: ql
      real, intent(out)    :: qi
      real, intent(out)    :: rvls
      integer, intent(out) :: id_check

      ! Local
      real*8               :: tc
      real                 :: temps,ps
      real*8               :: leff,nu,qc
      integer              :: iteration
      real*8               :: qs    ! Saturation specific humidity

      tc = thl*exnerfn(p)

!     nu = max(min((258._r8-tc)/20._r8,1.0_r8),0.0_r8)    ! ice fraction of condensate
      nu = ICE_FRACTION(real(tc),0.0,0.0)
      leff = (1._r8- nu)*xlv + nu*xls    ! effective latent heat

      temps = tc
      ps = p
      qs = GEOS_QSAT(temps, ps/100.)
      rvls = qs

      if ( qs .ge. qt ) then  ! no condensation
         id_check = 0
         qv = qt
         qc = 0.
         ql = 0.
         qi = 0.
         th = thl !tc/exnerfn(p)
      else                    ! condensation
         do iteration = 1,10
            temps = temps + ( (tc-temps)*cp/leff + qt - rvls )/( cp/leff + ep2*leff*rvls/(r*temps*temps) )
            qs = GEOS_QSAT(temps, ps/100.)
            rvls = qs
         end do
         qc = max( qt-qs, 0._r8 )
         qv = qt - qc
         ql = qc*(1._r8 - nu)
         qi = nu*qc
         th = temps/exnerfn(p)
         if ( abs((temps-(leff/cp)*qc)-tc) .ge. 1._r8 ) then
            id_check = 1
         else
            id_check = 0
         end if
      end if

      return
   end subroutine conden
FlorianDeconinck commented 3 weeks ago

Lives in https://github.com/FlorianDeconinck/gt4py/tree/cartesian/cast_to_int

FlorianDeconinck commented 15 hours ago

Ticket https://github.com/GEOS-ESM/NDSL/issues/58 carries the remaining of the work