Skip to content

ACC005 strided-section-argument-in-kernel ​

warning enabled by default

A non-contiguous section of a shared array is passed to a procedure inside OpenACC device code.

Why ​

A non-contiguous section (q(b, 1:3), a(i, :), a(1:n:2)) passed to a procedure is copied into a contiguous temporary. Inside a kernel that temporary is not privatised by nvfortran: all threads share it and race. The race is invisible while every thread writes the same values (uniform grids, constant coefficients) and corrupts results as soon as the values differ. Copy the elements into a private fixed-size local before the call, or pass the whole array and the indices.

Reported ​

fortran
!$acc parallel loop
do b = 1, nb
  call cell_metrics(dxyz=dxyz_gpu(b, 1:3), vol=vol(b))
end do

Preferred ​

fortran
!$acc parallel loop private(dxyz_b)
do b = 1, nb
  dxyz_b(1) = dxyz_gpu(b, 1); dxyz_b(2) = dxyz_gpu(b, 2); dxyz_b(3) = dxyz_gpu(b, 3)
  call cell_metrics(dxyz=dxyz_b, vol=vol(b))
end do

Suppressing ​

For one occurrence, with the reason on the same line (or alone on the line before the statement):

fortran
! fobis: ignore[ACC005] <why this occurrence is fine>

For the whole project, ignore = ACC005 in the fobos [lint] section.

References ​

Sections of the shipped knowledge packs behind this rule:

  • hpc-practice:gpu-practice#device-code-pitfalls (fobis kb show hpc-practice:gpu-practice#device-code-pitfalls)