| ! The "thread_limit" clause was added to the "target" construct in OpenMP 5.1. |
| ! RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 %s -o - | FileCheck %s --check-prefixes=BOTH,HOST |
| ! RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefixes=BOTH,DEVICE |
| |
| ! BOTH-LABEL: func.func @_QPteams |
| subroutine teams() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[NUM_TEAMS:.*]], %{{.*}} -> %[[THREAD_LIMIT:.*]] : i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| !$omp target |
| |
| ! BOTH: omp.teams |
| |
| ! HOST-SAME: num_teams( to %[[NUM_TEAMS]] : i32) thread_limit(%[[THREAD_LIMIT]] : i32) |
| ! DEVICE-SAME: num_teams({{.*}}) thread_limit({{.*}}) |
| !$omp teams num_teams(1) thread_limit(2) |
| call foo() |
| !$omp end teams |
| |
| !$omp end target |
| |
| ! BOTH: omp.teams |
| ! BOTH-SAME: num_teams({{.*}}) thread_limit({{.*}}) { |
| !$omp teams num_teams(1) thread_limit(2) |
| call foo() |
| !$omp end teams |
| end subroutine teams |
| |
| ! BOTH-LABEL: func.func @_QPdistribute_parallel_do |
| subroutine distribute_parallel_do() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[LB:.*]], %{{.*}} -> %[[UB:.*]], %{{.*}} -> %[[STEP:.*]], %{{.*}} -> %[[NUM_THREADS:.*]] : i32, i32, i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| |
| ! BOTH: omp.teams |
| !$omp target teams |
| |
| ! BOTH: omp.parallel |
| |
| ! HOST-SAME: num_threads(%[[NUM_THREADS]] : i32) |
| ! DEVICE-SAME: num_threads({{.*}}) |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| ! BOTH-NEXT: omp.loop_nest |
| |
| ! HOST-SAME: (%{{.*}}) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) |
| !$omp distribute parallel do num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do |
| !$omp end target teams |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams |
| call foo() !< Prevents this from being SPMD. |
| |
| ! BOTH: omp.parallel |
| ! BOTH-SAME: num_threads({{.*}}) |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| !$omp distribute parallel do num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do |
| !$omp end target teams |
| |
| ! BOTH: omp.teams |
| !$omp teams |
| |
| ! BOTH: omp.parallel |
| ! BOTH-SAME: num_threads({{.*}}) |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| !$omp distribute parallel do num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do |
| !$omp end teams |
| end subroutine distribute_parallel_do |
| |
| ! BOTH-LABEL: func.func @_QPdistribute_parallel_do_simd |
| subroutine distribute_parallel_do_simd() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[LB:.*]], %{{.*}} -> %[[UB:.*]], %{{.*}} -> %[[STEP:.*]], %{{.*}} -> %[[NUM_THREADS:.*]] : i32, i32, i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| |
| ! BOTH: omp.teams |
| !$omp target teams |
| |
| ! BOTH: omp.parallel |
| |
| ! HOST-SAME: num_threads(%[[NUM_THREADS]] : i32) |
| ! DEVICE-SAME: num_threads({{.*}}) |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| ! BOTH-NEXT: omp.simd |
| ! BOTH-NEXT: omp.loop_nest |
| |
| ! HOST-SAME: (%{{.*}}) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) |
| !$omp distribute parallel do simd num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do simd |
| !$omp end target teams |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams |
| call foo() !< Prevents this from being SPMD. |
| |
| ! BOTH: omp.parallel |
| ! BOTH-SAME: num_threads({{.*}}) |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| ! BOTH-NEXT: omp.simd |
| !$omp distribute parallel do simd num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do simd |
| !$omp end target teams |
| |
| ! BOTH: omp.teams |
| !$omp teams |
| |
| ! BOTH: omp.parallel |
| ! BOTH-SAME: num_threads({{.*}}) |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| ! BOTH-NEXT: omp.simd |
| |
| ! DEVICE-NOT: omp.parallel |
| ! DEVICE-NOT: omp.distribute |
| ! DEVICE-NOT: omp.wsloop |
| ! DEVICE-NOT: omp.simd |
| !$omp distribute parallel do simd num_threads(1) |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute parallel do simd |
| !$omp end teams |
| end subroutine distribute_parallel_do_simd |
| |
| ! BOTH-LABEL: func.func @_QPdistribute |
| subroutine distribute() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[LB:.*]], %{{.*}} -> %[[UB:.*]], %{{.*}} -> %[[STEP:.*]] : i32, i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| |
| ! BOTH: omp.teams |
| !$omp target teams |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.loop_nest |
| |
| ! HOST-SAME: (%{{.*}}) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) |
| !$omp distribute |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute |
| !$omp end target teams |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams |
| call foo() !< Prevents this from being Generic-SPMD. |
| |
| ! BOTH: omp.distribute |
| !$omp distribute |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute |
| !$omp end target teams |
| |
| ! BOTH: omp.teams |
| !$omp teams |
| |
| ! BOTH: omp.distribute |
| !$omp distribute |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute |
| !$omp end teams |
| end subroutine distribute |
| |
| ! BOTH-LABEL: func.func @_QPdistribute_simd |
| subroutine distribute_simd() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[LB:.*]], %{{.*}} -> %[[UB:.*]], %{{.*}} -> %[[STEP:.*]] : i32, i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| |
| ! BOTH: omp.teams |
| !$omp target teams |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.simd |
| ! BOTH-NEXT: omp.loop_nest |
| |
| ! HOST-SAME: (%{{.*}}) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) |
| !$omp distribute simd |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute simd |
| !$omp end target teams |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams |
| call foo() !< Prevents this from being Generic-SPMD. |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.simd |
| !$omp distribute simd |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute simd |
| !$omp end target teams |
| |
| ! BOTH: omp.teams |
| !$omp teams |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.simd |
| !$omp distribute simd |
| do i=1,10 |
| call foo() |
| end do |
| !$omp end distribute simd |
| !$omp end teams |
| end subroutine distribute_simd |
| |
| ! BOTH-LABEL: func.func @_QPloop |
| subroutine loop() |
| ! BOTH: omp.target |
| |
| ! HOST-SAME: host_eval(%{{.*}} -> %[[LB:.*]], %{{.*}} -> %[[UB:.*]], %{{.*}} -> %[[STEP:.*]] : i32, i32, i32) |
| |
| ! DEVICE-NOT: host_eval({{.*}}) |
| ! DEVICE-SAME: { |
| |
| ! BOTH: omp.teams |
| !$omp target teams |
| |
| ! BOTH: omp.parallel |
| |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| ! BOTH-NEXT: omp.loop_nest |
| |
| ! HOST-SAME: (%{{.*}}) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) |
| !$omp loop |
| do i=1,10 |
| end do |
| !$omp end target teams |
| end subroutine loop |
| |
| ! BOTH-LABEL: func.func @_QPdistribute_parallel_do_with_modified_trip |
| subroutine distribute_parallel_do_with_modified_trip() |
| integer :: i, x |
| integer :: m(1) |
| integer :: res(10) |
| m(1) = 10 |
| x = 1000000 |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams map(res) |
| x = 1 |
| ! BOTH: omp.parallel |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| !$omp distribute parallel do |
| do i = 1, m(x) |
| res(i) = 5 + i |
| end do |
| !$omp end distribute parallel do |
| !$omp end target teams |
| end subroutine distribute_parallel_do_with_modified_trip |
| |
| ! BOTH-LABEL: func.func @_QPdistribute_parallel_do_with_assignment |
| subroutine distribute_parallel_do_with_assignment() |
| integer :: i, m |
| integer :: res(10) |
| |
| ! BOTH: omp.target |
| ! BOTH-NOT: host_eval({{.*}}) |
| ! BOTH-SAME: { |
| ! BOTH: omp.teams |
| !$omp target teams map(from:m,res) private(m) |
| m = 5 |
| ! BOTH: omp.parallel |
| ! BOTH: omp.distribute |
| ! BOTH-NEXT: omp.wsloop |
| !$omp distribute parallel do |
| do i = 1, 10 |
| res(i) = 5 + i |
| end do |
| !$omp end distribute parallel do |
| !$omp end target teams |
| end subroutine distribute_parallel_do_with_assignment |