From d30b4e515a0cf509e56b88ddd7ddb87b9e601508 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 13 Apr 2023 15:35:45 -0700 Subject: [PATCH] [flang][openacc] Lower serial and serial loop construct Lower the parse tree to acc dialects operations. Make use of the parallel construct lowering and make it suitable for all compute constructs lowering. Reviewed By: PeteSteinfeld Differential Revision: https://reviews.llvm.org/D148273 --- flang/lib/Lower/OpenACC.cpp | 74 ++-- flang/test/Lower/OpenACC/acc-serial-loop.f90 | 613 +++++++++++++++++++++++++++ flang/test/Lower/OpenACC/acc-serial.f90 | 198 +++++++++ 3 files changed, 841 insertions(+), 44 deletions(-) create mode 100644 flang/test/Lower/OpenACC/acc-serial-loop.f90 create mode 100644 flang/test/Lower/OpenACC/acc-serial.f90 diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 0b8b2e2f..8c5f119 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -397,12 +397,13 @@ static void genACC(Fortran::lower::AbstractConverter &converter, } } -static mlir::acc::ParallelOp -createParallelOp(Fortran::lower::AbstractConverter &converter, - mlir::Location currentLocation, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, - const Fortran::parser::AccClauseList &accClauseList) { +template +static Op +createComputeOp(Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + const Fortran::parser::AccClauseList &accClauseList) { // Parallel operation operands mlir::Value async; @@ -550,9 +551,11 @@ createParallelOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector operandSegments; addOperand(operands, operandSegments, async); addOperands(operands, operandSegments, waitOperands); - addOperand(operands, operandSegments, numGangs); - addOperand(operands, operandSegments, numWorkers); - addOperand(operands, operandSegments, vectorLength); + if constexpr (std::is_same_v) { + addOperand(operands, operandSegments, numGangs); + addOperand(operands, operandSegments, numWorkers); + addOperand(operands, operandSegments, vectorLength); + } addOperand(operands, operandSegments, ifCond); addOperand(operands, operandSegments, selfCond); addOperands(operands, operandSegments, reductionOperands); @@ -570,28 +573,17 @@ createParallelOp(Fortran::lower::AbstractConverter &converter, addOperands(operands, operandSegments, privateOperands); addOperands(operands, operandSegments, firstprivateOperands); - mlir::acc::ParallelOp parallelOp = - createRegionOp( - firOpBuilder, currentLocation, operands, operandSegments); + Op computeOp = createRegionOp( + firOpBuilder, currentLocation, operands, operandSegments); if (addAsyncAttr) - parallelOp.setAsyncAttrAttr(firOpBuilder.getUnitAttr()); + computeOp.setAsyncAttrAttr(firOpBuilder.getUnitAttr()); if (addWaitAttr) - parallelOp.setWaitAttrAttr(firOpBuilder.getUnitAttr()); + computeOp.setWaitAttrAttr(firOpBuilder.getUnitAttr()); if (addSelfAttr) - parallelOp.setSelfAttrAttr(firOpBuilder.getUnitAttr()); + computeOp.setSelfAttrAttr(firOpBuilder.getUnitAttr()); - return parallelOp; -} - -static void -genACCParallelOp(Fortran::lower::AbstractConverter &converter, - mlir::Location currentLocation, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, - const Fortran::parser::AccClauseList &accClauseList) { - createParallelOp(converter, currentLocation, semanticsContext, stmtCtx, - accClauseList); + return computeOp; } static void genACCDataOp(Fortran::lower::AbstractConverter &converter, @@ -696,13 +688,14 @@ genACC(Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext stmtCtx; if (blockDirective.v == llvm::acc::ACCD_parallel) { - genACCParallelOp(converter, currentLocation, semanticsContext, stmtCtx, - accClauseList); + createComputeOp( + converter, currentLocation, semanticsContext, stmtCtx, accClauseList); } else if (blockDirective.v == llvm::acc::ACCD_data) { genACCDataOp(converter, currentLocation, semanticsContext, stmtCtx, accClauseList); } else if (blockDirective.v == llvm::acc::ACCD_serial) { - TODO(currentLocation, "serial construct lowering"); + createComputeOp( + converter, currentLocation, semanticsContext, stmtCtx, accClauseList); } else if (blockDirective.v == llvm::acc::ACCD_kernels) { TODO(currentLocation, "kernels construct lowering"); } else if (blockDirective.v == llvm::acc::ACCD_host_data) { @@ -711,18 +704,6 @@ genACC(Fortran::lower::AbstractConverter &converter, } static void -genACCParallelLoopOps(Fortran::lower::AbstractConverter &converter, - mlir::Location currentLocation, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, - const Fortran::parser::AccClauseList &accClauseList) { - createParallelOp(converter, currentLocation, semanticsContext, stmtCtx, - accClauseList); - createLoopOp(converter, currentLocation, semanticsContext, stmtCtx, - accClauseList); -} - -static void genACC(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::pft::Evaluation &eval, @@ -741,10 +722,15 @@ genACC(Fortran::lower::AbstractConverter &converter, if (combinedDirective.v == llvm::acc::ACCD_kernels_loop) { TODO(currentLocation, "OpenACC Kernels Loop construct not lowered yet!"); } else if (combinedDirective.v == llvm::acc::ACCD_parallel_loop) { - genACCParallelLoopOps(converter, currentLocation, semanticsContext, stmtCtx, - accClauseList); + createComputeOp( + converter, currentLocation, semanticsContext, stmtCtx, accClauseList); + createLoopOp(converter, currentLocation, semanticsContext, stmtCtx, + accClauseList); } else if (combinedDirective.v == llvm::acc::ACCD_serial_loop) { - TODO(currentLocation, "OpenACC Serial Loop construct not lowered yet!"); + createComputeOp( + converter, currentLocation, semanticsContext, stmtCtx, accClauseList); + createLoopOp(converter, currentLocation, semanticsContext, stmtCtx, + accClauseList); } else { llvm::report_fatal_error("Unknown combined construct encountered"); } diff --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90 new file mode 100644 index 0000000..e952554 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90 @@ -0,0 +1,613 @@ +! This test checks lowering of Openacc serial loop combined directive. + +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s + +subroutine acc_serial_loop + integer :: i, j + + integer :: async = 1 + integer :: wait1 = 1 + integer :: wait2 = 2 + integer :: numGangs = 1 + integer :: numWorkers = 10 + integer :: vectorLength = 128 + logical :: ifCondition = .TRUE. + integer, parameter :: n = 10 + real, dimension(n) :: a, b, c + real, dimension(n, n) :: d, e + real, pointer :: f, g + + integer :: gangNum = 8 + integer :: gangStatic = 8 + integer :: vectorNum = 128 + integer, parameter :: tileSize = 2 + +!CHECK: [[A:%.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ea"} +!CHECK: [[B:%.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Eb"} +!CHECK: [[C:%.*]] = fir.alloca !fir.array<10xf32> {{{.*}}uniq_name = "{{.*}}Ec"} +!CHECK: [[F:%.*]] = fir.alloca !fir.box> {bindc_name = "f", uniq_name = "{{.*}}Ef"} +!CHECK: [[G:%.*]] = fir.alloca !fir.box> {bindc_name = "g", uniq_name = "{{.*}}Eg"} +!CHECK: [[IFCONDITION:%.*]] = fir.address_of(@{{.*}}ifcondition) : !fir.ref> + + !$acc serial loop + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop async + DO i = 1, n + a(i) = b(i) + END DO + !$acc end serial loop + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: } attributes {asyncAttr} + + !$acc serial loop async(1) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[ASYNC1:%.*]] = arith.constant 1 : i32 +!CHECK: acc.serial async([[ASYNC1]] : i32) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop async(async) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[ASYNC2:%.*]] = fir.load %{{.*}} : !fir.ref +!CHECK: acc.serial async([[ASYNC2]] : i32) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop wait + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: } attributes {waitAttr} + + !$acc serial loop wait(1) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[WAIT1:%.*]] = arith.constant 1 : i32 +!CHECK: acc.serial wait([[WAIT1]] : i32) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop wait(1, 2) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[WAIT2:%.*]] = arith.constant 1 : i32 +!CHECK: [[WAIT3:%.*]] = arith.constant 2 : i32 +!CHECK: acc.serial wait([[WAIT2]], [[WAIT3]] : i32, i32) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop wait(wait1, wait2) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[WAIT4:%.*]] = fir.load %{{.*}} : !fir.ref +!CHECK: [[WAIT5:%.*]] = fir.load %{{.*}} : !fir.ref +!CHECK: acc.serial wait([[WAIT4]], [[WAIT5]] : i32, i32) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop if(.TRUE.) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[IF1:%.*]] = arith.constant true +!CHECK: acc.serial if([[IF1]]) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop if(ifCondition) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref> +!CHECK: [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1 +!CHECK: acc.serial if([[IF2]]) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop self(.TRUE.) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[SELF1:%.*]] = arith.constant true +!CHECK: acc.serial self([[SELF1]]) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop self + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: } attributes {selfAttr} + + !$acc serial loop self(ifCondition) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: [[SELF2:%.*]] = fir.convert [[IFCONDITION]] : (!fir.ref>) -> i1 +!CHECK: acc.serial self([[SELF2]]) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop copy(a, b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial copy([[A]], [[B]] : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop copy(a) copy(b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial copy([[A]], [[B]] : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop copyin(a) copyin(readonly: b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial copyin([[A]] : !fir.ref>) copyin_readonly([[B]] : !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop copyout(a) copyout(zero: b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial copyout([[A]] : !fir.ref>) copyout_zero([[B]] : !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop create(b) create(zero: a) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial create([[B]] : !fir.ref>) create_zero([[A]] : !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop no_create(a, b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial no_create([[A]], [[B]] : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop present(a, b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial present([[A]], [[B]] : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop deviceptr(a) deviceptr(b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial deviceptr([[A]], [[B]] : !fir.ref>, !fir.ref>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop attach(f, g) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial attach([[F]], [[G]] : !fir.ref>>, !fir.ref>>) { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop private(a) firstprivate(b) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial firstprivate([[B]] : !fir.ref>) private([[A]] : !fir.ref>) { +!CHECK: acc.loop private([[A]]: !fir.ref>) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop seq + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: } attributes {seq} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop auto + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: } attributes {auto} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop independent + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: } attributes {independent} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop gang + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop gang { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop gang(num: 8) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32 +!CHECK-NEXT: acc.loop gang(num=[[GANGNUM1]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop gang(num: gangNum) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref +!CHECK-NEXT: acc.loop gang(num=[[GANGNUM2]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop gang(num: gangNum, static: gangStatic) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop gang(num=%{{.*}}: i32, static=%{{.*}}: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop vector + DO i = 1, n + a(i) = b(i) + END DO +!CHECK: acc.serial { +!CHECK: acc.loop vector { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop vector(128) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[CONSTANT128:%.*]] = arith.constant 128 : i32 +!CHECK: acc.loop vector([[CONSTANT128]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop vector(vectorLength) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref +!CHECK: acc.loop vector([[VECTORLENGTH]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop worker + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop worker { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop worker(128) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[WORKER128:%.*]] = arith.constant 128 : i32 +!CHECK: acc.loop worker([[WORKER128]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop collapse(2) + DO i = 1, n + DO j = 1, n + d(i, j) = e(i, j) + END DO + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: } attributes {collapse = 2 : i64} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop + DO i = 1, n + !$acc loop + DO j = 1, n + d(i, j) = e(i, j) + END DO + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.loop { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop tile(2) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32 +!CHECK: acc.loop tile([[TILESIZE]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop tile(*) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32 +!CHECK: acc.loop tile([[TILESIZEM1]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop tile(2, 2) + DO i = 1, n + DO j = 1, n + d(i, j) = e(i, j) + END DO + END DO + +!CHECK: acc.serial { +!CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 +!CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 +!CHECK: acc.loop tile([[TILESIZE1]]: i32, [[TILESIZE2]]: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop tile(tileSize) + DO i = 1, n + a(i) = b(i) + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop tile(%{{.*}}: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc serial loop tile(tileSize, tileSize) + DO i = 1, n + DO j = 1, n + d(i, j) = e(i, j) + END DO + END DO + +!CHECK: acc.serial { +!CHECK: acc.loop tile(%{{.*}}: i32, %{{.*}}: i32) { +!CHECK: fir.do_loop +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} +!CHECK: acc.yield +!CHECK-NEXT: }{{$}} + +end subroutine acc_serial_loop diff --git a/flang/test/Lower/OpenACC/acc-serial.f90 b/flang/test/Lower/OpenACC/acc-serial.f90 new file mode 100644 index 0000000..5bc1998 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-serial.f90 @@ -0,0 +1,198 @@ +! This test checks lowering of OpenACC serial directive. + +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s + +subroutine acc_serial + integer :: i, j + + integer :: async = 1 + integer :: wait1 = 1 + integer :: wait2 = 2 + integer :: numGangs = 1 + integer :: numWorkers = 10 + integer :: vectorLength = 128 + logical :: ifCondition = .TRUE. + real, dimension(10, 10) :: a, b, c + real, pointer :: d, e + +! CHECK: [[A:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ea"} +! CHECK: [[B:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Eb"} +! CHECK: [[C:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ec"} +! CHECK: [[D:%.*]] = fir.alloca !fir.box> {bindc_name = "d", uniq_name = "{{.*}}Ed"} +! CHECK: [[E:%.*]] = fir.alloca !fir.box> {bindc_name = "e", uniq_name = "{{.*}}Ee"} +! CHECK: [[IFCONDITION:%.*]] = fir.address_of(@{{.*}}ifcondition) : !fir.ref> + + !$acc serial + !$acc end serial + +! CHECK: acc.serial { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial async + !$acc end serial + +! CHECK: acc.serial { +! CHECK: acc.yield +! CHECK-NEXT: } attributes {asyncAttr} + + !$acc serial async(1) + !$acc end serial + +! CHECK: [[ASYNC1:%.*]] = arith.constant 1 : i32 +! CHECK: acc.serial async([[ASYNC1]] : i32) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial async(async) + !$acc end serial + +! CHECK: [[ASYNC2:%.*]] = fir.load %{{.*}} : !fir.ref +! CHECK: acc.serial async([[ASYNC2]] : i32) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial wait + !$acc end serial + +! CHECK: acc.serial { +! CHECK: acc.yield +! CHECK-NEXT: } attributes {waitAttr} + + !$acc serial wait(1) + !$acc end serial + +! CHECK: [[WAIT1:%.*]] = arith.constant 1 : i32 +! CHECK: acc.serial wait([[WAIT1]] : i32) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial wait(1, 2) + !$acc end serial + +! CHECK: [[WAIT2:%.*]] = arith.constant 1 : i32 +! CHECK: [[WAIT3:%.*]] = arith.constant 2 : i32 +! CHECK: acc.serial wait([[WAIT2]], [[WAIT3]] : i32, i32) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial wait(wait1, wait2) + !$acc end serial + +! CHECK: [[WAIT4:%.*]] = fir.load %{{.*}} : !fir.ref +! CHECK: [[WAIT5:%.*]] = fir.load %{{.*}} : !fir.ref +! CHECK: acc.serial wait([[WAIT4]], [[WAIT5]] : i32, i32) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial if(.TRUE.) + !$acc end serial + +! CHECK: [[IF1:%.*]] = arith.constant true +! CHECK: acc.serial if([[IF1]]) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial if(ifCondition) + !$acc end serial + +! CHECK: [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref> +! CHECK: [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1 +! CHECK: acc.serial if([[IF2]]) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial self(.TRUE.) + !$acc end serial + +! CHECK: [[SELF1:%.*]] = arith.constant true +! CHECK: acc.serial self([[SELF1]]) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial self + !$acc end serial + +! CHECK: acc.serial { +! CHECK: acc.yield +! CHECK-NEXT: } attributes {selfAttr} + + !$acc serial self(ifCondition) + !$acc end serial + +! CHECK: [[SELF2:%.*]] = fir.convert [[IFCONDITION]] : (!fir.ref>) -> i1 +! CHECK: acc.serial self([[SELF2]]) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial copy(a, b, c) + !$acc end serial + +! CHECK: acc.serial copy([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial copy(a) copy(b) copy(c) + !$acc end serial + +! CHECK: acc.serial copy([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial copyin(a) copyin(readonly: b, c) + !$acc end serial + +! CHECK: acc.serial copyin([[A]] : !fir.ref>) copyin_readonly([[B]], [[C]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial copyout(a) copyout(zero: b) copyout(c) + !$acc end serial + +! CHECK: acc.serial copyout([[A]], [[C]] : !fir.ref>, !fir.ref>) copyout_zero([[B]] : !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial create(a, b) create(zero: c) + !$acc end serial + +! CHECK: acc.serial create([[A]], [[B]] : !fir.ref>, !fir.ref>) create_zero([[C]] : !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial no_create(a, b) create(zero: c) + !$acc end serial + +! CHECK: acc.serial create_zero([[C]] : !fir.ref>) no_create([[A]], [[B]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial present(a, b, c) + !$acc end serial + +! CHECK: acc.serial present([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial deviceptr(a) deviceptr(c) + !$acc end serial + +! CHECK: acc.serial deviceptr([[A]], [[C]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial attach(d, e) + !$acc end serial + +! CHECK: acc.serial attach([[D]], [[E]] : !fir.ref>>, !fir.ref>>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + + !$acc serial private(a) firstprivate(b) private(c) + !$acc end serial + +! CHECK: acc.serial firstprivate([[B]] : !fir.ref>) private([[A]], [[C]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.yield +! CHECK-NEXT: }{{$}} + +end subroutine -- 2.7.4