Arrays like uv(:,:,:) in T-DYN are declared as 3 dimensional arrays. One of the dimensions is used to separate u and v, i.e. u=>uv(1,:,:) and v=>uv(2,:,:).
With this order of the indices, the individual data for u (and v) is not contiguous in memory, which may lead to severe performance issues when using e.g. u separately.
If we loop these arrays, the first index should be the one with the fastest changing access index, as this data is adjacent in memory (but this is probably different depending on the used compiler and optimization settings).
For example in solve_tracers_ale we do
do elem=1, myDim_elem2D+eDim_elem2D
UV(:, :, elem) =UV(:, :, elem) + fer_UV(:, :, elem)
end do
and in update_vel
DO elem=1, myDim_elem2D
...
DO nz=nzmin, nzmax-1
UV(1,nz,elem)= UV(1,nz,elem) + UV_rhs(1,nz,elem) + Fx
UV(2,nz,elem)= UV(2,nz,elem) + UV_rhs(2,nz,elem) + Fy
END DO
END DO
Both examples could benefit from an index reordering.
For restart I/O and mean data output we access the individual levels of e.g. u, which also are not contiguous in memory. For this reason we have to copy the level data to a buffer (and back) when using MPI (e.g. like dynamics%uv(1,lvl,:) = laux)
I think we should consider to rearrange the indices for uv,uv_rhs,uv_rhsAB,fer_uv to have the elem index first, then the level index. For example
allocate(dynamics%uv( 2, nl-1, elem_size))
would be
allocate(dynamics%uv(elem_size, nl-1, 2))
Another thing. On juwels booster the nvfortran compiler somehow has trouble with some pointers to these non-contiguous regions. This looks like an error of nvfortran. I am still trying to pin the exact problem of this, you can find a first hack-ish workaround here: https://github.com/FESOM/fesom2/commits/nvfortran_subarray_workaround
Arrays like
uv(:,:,:)in T-DYN are declared as 3 dimensional arrays. One of the dimensions is used to separate u and v, i.e.u=>uv(1,:,:)andv=>uv(2,:,:).With this order of the indices, the individual data for u (and v) is not contiguous in memory, which may lead to severe performance issues when using e.g. u separately.
If we loop these arrays, the first index should be the one with the fastest changing access index, as this data is adjacent in memory (but this is probably different depending on the used compiler and optimization settings).
For example in
solve_tracers_alewe doand in
update_velBoth examples could benefit from an index reordering.
For restart I/O and mean data output we access the individual levels of e.g. u, which also are not contiguous in memory. For this reason we have to copy the level data to a buffer (and back) when using MPI (e.g. like
dynamics%uv(1,lvl,:) = laux)I think we should consider to rearrange the indices for
uv,uv_rhs,uv_rhsAB,fer_uvto have the elem index first, then the level index. For examplewould be
Another thing. On juwels booster the nvfortran compiler somehow has trouble with some pointers to these non-contiguous regions. This looks like an error of nvfortran. I am still trying to pin the exact problem of this, you can find a first hack-ish workaround here: https://github.com/FESOM/fesom2/commits/nvfortran_subarray_workaround