Skip to content

Commit

Permalink
[flang][cuda] Emit error when host array is used in CUF kernel (#100693)
Browse files Browse the repository at this point in the history
Restriction from the standard 2.11.2.

Arrays used or assigned in the loop must have the device, managed or
unifed attribute.
  • Loading branch information
clementval authored Jul 26, 2024
1 parent 4826079 commit 16975ad
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 7 deletions.
32 changes: 32 additions & 0 deletions flang/lib/Semantics/check-cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,25 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
WarnOnIoStmt(source);
}
}
template <typename A>
void ErrorIfHostSymbol(const A &expr, const parser::CharBlock &source) {
for (const Symbol &sym : CollectCudaSymbols(expr)) {
if (const auto *details =
sym.GetUltimate().detailsIf<semantics::ObjectEntityDetails>()) {
if (details->IsArray() &&
(!details->cudaDataAttr() ||
(details->cudaDataAttr() &&
*details->cudaDataAttr() != common::CUDADataAttr::Device &&
*details->cudaDataAttr() != common::CUDADataAttr::Managed &&
*details->cudaDataAttr() !=
common::CUDADataAttr::Unified))) {
context_.Say(source,
"Host array '%s' cannot be present in CUF kernel"_err_en_US,
sym.name());
}
}
}
}
void Check(const parser::ActionStmt &stmt, const parser::CharBlock &source) {
common::visit(
common::visitors{
Expand Down Expand Up @@ -349,6 +368,19 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
[&](const common::Indirection<parser::IfStmt> &x) {
Check(x.value());
},
[&](const common::Indirection<parser::AssignmentStmt> &x) {
if (IsCUFKernelDo) {
const evaluate::Assignment *assign{
semantics::GetAssignment(x.value())};
if (assign) {
ErrorIfHostSymbol(assign->lhs, source);
ErrorIfHostSymbol(assign->rhs, source);
}
}
if (auto msg{ActionStmtChecker<IsCUFKernelDo>::WhyNotOk(x)}) {
context_.Say(source, std::move(*msg));
}
},
[&](const auto &x) {
if (auto msg{ActionStmtChecker<IsCUFKernelDo>::WhyNotOk(x)}) {
context_.Say(source, std::move(*msg));
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/CUDA/cuda-data-transfer.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ subroutine sub4()
integer, parameter :: n = 10
real, device :: adev(n)
real :: ahost(n)
real :: b
real, managed :: b
integer :: i

adev = ahost
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ subroutine sub1()
integer :: i, j
integer, parameter :: n = 100
integer(8) :: istream
real :: a(n), b(n)
real :: c(n,n), d(n,n)
real, device :: a(n), b(n)
real, device :: c(n,n), d(n,n)

! CHECK-LABEL: func.func @_QPsub1()
! CHECK: %[[IV:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsub1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
Expand Down
3 changes: 2 additions & 1 deletion flang/test/Parser/cuf-sanity-common
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ module m
end subroutine
subroutine test
logical isPinned
real a(10), x, y, z
real, device :: a(10)
real :: x, y, z
!$cuf kernel do(1) <<<*, *, stream = 1>>>
do j = 1, 10
end do
Expand Down
10 changes: 10 additions & 0 deletions flang/test/Semantics/cuf09.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module m
end

program main
integer, device :: a_d(10 ,10)
integer :: b(10, 10)
!$cuf kernel do <<< *, * >>> ! ok
do j = 1, 0
end do
Expand Down Expand Up @@ -90,4 +92,12 @@ program main
else if (ifunc() /= 1) then
end if
end do

!$cuf kernel do (2) <<<*, *>>>
do j = 1, 10
do i = 1, 10
!ERROR: Host array 'b' cannot be present in CUF kernel
a_d(i,j) = b(i,j)
enddo
enddo
end
6 changes: 3 additions & 3 deletions flang/test/Semantics/reduce.cuf
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
! RUN: %python %S/test_errors.py %s %flang_fc1
subroutine s(n,m,a,l)
integer, intent(in) :: n
integer, intent(in) :: m(n)
real, intent(in) :: a(n)
logical, intent(in) :: l(n)
integer, device, intent(in) :: m(n)
real, device, intent(in) :: a(n)
logical, device, intent(in) :: l(n)
integer j, mr
real ar
logical lr
Expand Down

0 comments on commit 16975ad

Please sign in to comment.