Refactored sea ice in NEMO 5.x
Just a place to capture any problems/progress as I look at getting the refactored sea ice working on GPU.
Code builds and runs (OpenACC loops) but is very slow. One of the main culprits is icethd_dh which consists of loads of tiny kernels. This is because we haven't parallelised the main loop over jpti. Attempting to do this manually reveals that there are two calls within the loop:
...
e_s_1d(ji,:) = snw_ent(zh_s, ze_s)
if (h_s_1d(ji) > 0._wp) then
do jk = 1, nlay_s, 1
t_s_1d(ji,jk) = rt0 + (-e_s_1d(ji,jk) * r1_rhos * r1_rcpi + rLfus * r\1_rcpi)
enddo
else
do jk = 1, nlay_s, 1
t_s_1d(ji,jk) = rt0
enddo
end if
call ice_var_vremap(zh_i_old, ze_i_old, e_i_1d(ji,:))
if (nn_icesal == 4) then
call ice_var_vremap(zh_i_old, zs_i_old, sz_i_1d(ji,:))
end if
...
where snw_ent is a function defined in the same module and ice_var_vremap is from the icevar module.
I've tried manually adding !$acc routine to both of these but this currently fails at link time. The better alternative is to inline them...
Attempt to use 924_module_inline branch:
Transforming ice_thd_dh with acc kernels
Module inline of 'ice_var_snwblow' failed:
Transformation Error: KernelModuleInlineTrans failed to retrieve PSyIR for routine 'ice_var_snwblow' due to: RoutineSymbol
'ice_var_snwblow' exists in Container 'icevar' but is of UnknownFortranType:
interface ice_var_snwblow
module procedure ice_var_snwblow_1d, ice_var_snwblow_2d
end interface
Cannot currently module inline such a routine.
Module inline of 'ice_var_vremap' failed:
Transformation Error: routine 'ice_var_vremap' contains accesses to 'zh_cum1' which is declared in the same module scope.
Cannot inline such a routine.
So the subroutine accesses a variable in its parent module and the call to the snw_ent function isn't found.
The first problem is simply because I'm working with the file after PSyclone has hoisted some automatic arrays to module scope. If I do it before this then ice_var_vremap is successfully module inlined!
However, cannot then 'inline' either routine:
Transformation Error: Routine 'snw_ent' cannot be inlined because it contains a Symbol 'zeh_cum0' with an UnknownInterface: 'REAL(KIND = wp), DIMENSION(0 : nlay_s + 1) :: zeh_cum0'
Inlining of 'ice_var_vremap' failed:
Transformation Error: Routine 'ice_var_vremap' cannot be inlined because it contains a Symbol 'ph_old' which is an Argument of UnknownType: 'REAL(KIND = wp), DIMENSION(0 : nlay_i + 1), INTENT(IN) :: ph_old'
Do we still not support array variables declared with non-default lower bounds? No we don't - this is #949.