[Flang][OpenMP] Validate omp_initial_device omp_invalid_device as device IDs (#193669)
As per OpenMP 5.2/6.0 the below are valid device values in a `#pragma
omp target` directive:
omp_initial_device (-1) -> refers to the host CPU.
omp_invalid_device (-2) -> an intentionally invalid device, used to
trigger a runtime error.
For the 2 values discussed above flang fails with:
```
error: The device expression of the DEVICE clause must be a positive integer expression
!$OMP TARGET DEVICE(-1)
error: Must have INTEGER type, but is REAL(4)
!$OMP TARGET DEVICE(OMP_INVALID_DEVICE)
```
Issue: https://github.com/llvm/llvm-project/issues/192989
This commit is contained in:
@@ -4735,8 +4735,20 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
|
|||||||
const parser::OmpDeviceClause &deviceClause{x.v};
|
const parser::OmpDeviceClause &deviceClause{x.v};
|
||||||
const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
|
const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
|
||||||
unsigned version{context_.langOptions().OpenMPVersion};
|
unsigned version{context_.langOptions().OpenMPVersion};
|
||||||
RequiresPositiveParameter(
|
// The predefined identifiers omp_initial_device (-1) and omp_invalid_device
|
||||||
llvm::omp::Clause::OMPC_device, device, "device expression");
|
// (-2) were introduced in OpenMP 5.2. Under earlier versions the device
|
||||||
|
// expression must be a non-negative integer.
|
||||||
|
if (version >= 52) {
|
||||||
|
if (const auto v{GetIntValue(device)}) {
|
||||||
|
if (*v < -2) {
|
||||||
|
context_.Say(GetContext().clauseSource,
|
||||||
|
"The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)"_err_en_US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RequiresPositiveParameter(
|
||||||
|
llvm::omp::Clause::OMPC_device, device, "device expression");
|
||||||
|
}
|
||||||
llvm::omp::Directive dir{GetContext().directive};
|
llvm::omp::Directive dir{GetContext().directive};
|
||||||
|
|
||||||
if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device,
|
if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
|
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
|
||||||
! Check OpenMP clause validity for the following directives:
|
! Check OpenMP clause validity for the following directives:
|
||||||
! 2.10 Device constructs
|
! 2.10 Device constructs
|
||||||
program main
|
program main
|
||||||
@@ -151,12 +151,24 @@ program main
|
|||||||
enddo
|
enddo
|
||||||
!$omp end target data
|
!$omp end target data
|
||||||
|
|
||||||
!ERROR: The device expression of the DEVICE clause must be a positive integer expression
|
! -2 is the reserved value omp_invalid_device (OpenMP 5.2+), so it is valid.
|
||||||
!$omp target enter data map(alloc:A) device(-2)
|
!$omp target enter data map(alloc:A) device(-2)
|
||||||
|
|
||||||
!ERROR: The device expression of the DEVICE clause must be a positive integer expression
|
! -2 is the reserved value omp_invalid_device (OpenMP 5.2+), so it is valid.
|
||||||
!$omp target exit data map(delete:A) device(-2)
|
!$omp target exit data map(delete:A) device(-2)
|
||||||
|
|
||||||
|
! -1 is the reserved value omp_initial_device (OpenMP 5.2+), so it is valid.
|
||||||
|
!$omp target enter data map(alloc:A) device(-1)
|
||||||
|
|
||||||
|
! -1 is the reserved value omp_initial_device (OpenMP 5.2+), so it is valid.
|
||||||
|
!$omp target exit data map(delete:A) device(-1)
|
||||||
|
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
|
||||||
|
!$omp target enter data map(alloc:A) device(-3)
|
||||||
|
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
|
||||||
|
!$omp target exit data map(delete:A) device(-3)
|
||||||
|
|
||||||
!ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
|
!ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
|
||||||
!$omp target enter data map(to:a) if(.true.) if(.false.)
|
!$omp target enter data map(to:a) if(.true.) if(.false.)
|
||||||
|
|
||||||
|
|||||||
82
flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90
Normal file
82
flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
! The predefined identifiers omp_initial_device (-1) and omp_invalid_device
|
||||||
|
! (-2) from the OpenMP 5.2+ specification must be accepted as valid device
|
||||||
|
! numbers in the DEVICE clause of target constructs.
|
||||||
|
|
||||||
|
! REQUIRES: openmp_runtime
|
||||||
|
|
||||||
|
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=52
|
||||||
|
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=60
|
||||||
|
|
||||||
|
program main
|
||||||
|
use omp_lib
|
||||||
|
|
||||||
|
real(8) :: arrayA(256)
|
||||||
|
integer :: N, dev
|
||||||
|
arrayA = 1.414d0
|
||||||
|
N = 256
|
||||||
|
|
||||||
|
! Literal values allowed by the OpenMP 5.2 / 6.0 specification.
|
||||||
|
!$omp target device(-1)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!$omp target device(-2)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!$omp target device(0)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
! Using the predefined identifiers from the omp_lib module.
|
||||||
|
!$omp target device(omp_initial_device)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!$omp target device(omp_invalid_device)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
! Also accepted on target data and its data motion variants.
|
||||||
|
!$omp target data map(to: arrayA) device(omp_initial_device)
|
||||||
|
!$omp end target data
|
||||||
|
|
||||||
|
!$omp target data map(to: arrayA) device(omp_invalid_device)
|
||||||
|
!$omp end target data
|
||||||
|
|
||||||
|
!$omp target enter data map(alloc: arrayA) device(omp_initial_device)
|
||||||
|
!$omp target enter data map(alloc: arrayA) device(omp_invalid_device)
|
||||||
|
|
||||||
|
!$omp target exit data map(delete: arrayA) device(omp_initial_device)
|
||||||
|
!$omp target exit data map(delete: arrayA) device(omp_invalid_device)
|
||||||
|
|
||||||
|
!$omp target update to(arrayA) device(omp_initial_device)
|
||||||
|
!$omp target update to(arrayA) device(omp_invalid_device)
|
||||||
|
|
||||||
|
! Runtime-determined values pass the semantic check.
|
||||||
|
dev = -1
|
||||||
|
!$omp target device(dev)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
! Values below -2 are still rejected.
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
|
||||||
|
!$omp target device(-3)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
end program main
|
||||||
36
flang/test/Semantics/OpenMP/device-pre-52.f90
Normal file
36
flang/test/Semantics/OpenMP/device-pre-52.f90
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
|
||||||
|
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
|
||||||
|
|
||||||
|
program main
|
||||||
|
real(8) :: arrayA(256)
|
||||||
|
integer :: N
|
||||||
|
arrayA = 1.414d0
|
||||||
|
N = 256
|
||||||
|
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a positive integer expression
|
||||||
|
!$omp target device(-1)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a positive integer expression
|
||||||
|
!$omp target device(-2)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!ERROR: The device expression of the DEVICE clause must be a positive integer expression
|
||||||
|
!$omp target device(-3)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
|
||||||
|
!$omp target device(0)
|
||||||
|
do i = 1, N
|
||||||
|
arrayA(i) = 3.14d0
|
||||||
|
enddo
|
||||||
|
!$omp end target
|
||||||
|
end program main
|
||||||
@@ -102,6 +102,9 @@
|
|||||||
integer(kind=omp_sched_kind), parameter, public :: omp_sched_auto = 4
|
integer(kind=omp_sched_kind), parameter, public :: omp_sched_auto = 4
|
||||||
integer(kind=omp_sched_kind), parameter, public :: omp_sched_monotonic = int(Z'80000000', kind=omp_sched_kind)
|
integer(kind=omp_sched_kind), parameter, public :: omp_sched_monotonic = int(Z'80000000', kind=omp_sched_kind)
|
||||||
|
|
||||||
|
integer (kind=omp_integer_kind), parameter, public :: omp_initial_device = -1
|
||||||
|
integer (kind=omp_integer_kind), parameter, public :: omp_invalid_device = -2
|
||||||
|
|
||||||
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_false = 0
|
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_false = 0
|
||||||
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_true = 1
|
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_true = 1
|
||||||
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_master = 2
|
integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_master = 2
|
||||||
|
|||||||
@@ -79,6 +79,11 @@
|
|||||||
integer(kind=omp_sched_kind)omp_sched_monotonic
|
integer(kind=omp_sched_kind)omp_sched_monotonic
|
||||||
parameter(omp_sched_monotonic=Z'80000000')
|
parameter(omp_sched_monotonic=Z'80000000')
|
||||||
|
|
||||||
|
integer(kind=omp_integer_kind)omp_initial_device
|
||||||
|
parameter(omp_initial_device=-1)
|
||||||
|
integer(kind=omp_integer_kind)omp_invalid_device
|
||||||
|
parameter(omp_invalid_device=-2)
|
||||||
|
|
||||||
integer(kind=omp_proc_bind_kind)omp_proc_bind_false
|
integer(kind=omp_proc_bind_kind)omp_proc_bind_false
|
||||||
parameter(omp_proc_bind_false=0)
|
parameter(omp_proc_bind_false=0)
|
||||||
integer(kind=omp_proc_bind_kind)omp_proc_bind_true
|
integer(kind=omp_proc_bind_kind)omp_proc_bind_true
|
||||||
|
|||||||
Reference in New Issue
Block a user