ARR04-F. Ensure arrays ranges mapped to devices cover all accessed elements
Developers shall ensure that any array section or range explicitly mapped to a device memory space (e.g., GPU) fully encompasses all indices accessed within the offloaded region to prevent out-of-bounds access and undefined behavior.
In heterogeneous computing, it is common to map only the array portion required for a computation to reduce data transfer overhead. However, if an offloaded block accesses indices outside the explicitly mapped range, this results in undefined behavior, which can manifest as invalid memory access on the device, hardware traps, segmentation faults, or program crashes.
An "apparently accessible" subscript is invalid if the corresponding memory has not been mapped to the device. While the Fortran standard requires subscripts to stay within declared bounds for safety, the programmer must additionally ensure consistency between data mapping directives and the loop boundaries executed on the device.
Noncompliant Code Example
In this noncompliant example, the developer attempts to optimize a vector addition by mapping only the first 50 elements of arrays A , B , and sum to the devide (e.g., GPU). However, the DO loop iterates through the entire size of the arrays, from 1 to 100. The GPU kernel will attempt to access elements 51 through 100, which have not been mapped, leading to a memory violation.
subroutine partial_copy(A, B, sum)
use iso_fortran_env, only: real32
implicit none
real(real32), intent(in) :: A(100), B(100)
real(real32), intent(out) :: sum(100)
integer :: i
! Noncompliant: the mapped range 1:50 does not cover the range 1:100 used in the loop
!$omp target map(to: A(1:50), B(1:50)) map(from: sum(1:50))
!$omp parallel do private(i)
do i = 1, 100
sum(i) = A(i) + B(i)
end do
!$omp end target
end subroutine
Compliant Solution
In the compliant solution, the mapped range 1:100 is updated to match the actual usage in the loop.
subroutine partial_copy(A, B, sum)
use iso_fortran_env, only: real32
implicit none
real(real32), intent(in) :: A(100), B(100)
real(real32), intent(out) :: sum(100)
integer :: i
! Compliant: the mapped range 1:100 covers the range 1:100 used in the loop
!$omp target map(to: A(1:100), B(1:100)) map(from: sum(1:100))
!$omp parallel do private(i)
do i = 1, 100
sum(i) = A(i) + B(i)
end do
!$omp end target
end subroutine
Risk Assessment
Failing to map the used range of an array results in out-of-bounds device memory access. This can lead to information exposure if the device reads unmapped memory, arbitrary code execution if an unmapped write operation is exploited, or program crashes or hardware faults due to invalid memory access.
| Recommendation | Severity | Likelihood | Detectable | Repairable | Priority | Level |
| ARR04-F | High | Likely | Yes | Yes | P27 | L1 |
Attachments:
button_arrow_left.png (image/png)
button_arrow_up.png (image/png)
button_arrow_right.png (image/png)


