Issue 208672
Summary [Clang][Flang][OpenMP] `if` clause for `teams` construct has no effect on accelerator
Labels
Assignees
Reporter Thyre
    This is a follow-up to #205345, #207444 

---

The OpenMP v5.2 and v6.0 specification mention the following addition to the OpenMP teams construct:

> When an `if` clause is present on a `teams` construct and the `if` clause _expression_ evaluates to `false`, the number of formed teams is one. The use of a variable in an `if` clause _expression_ of a `teams` construct causes an implicit reference to the variable in all enclosing constructs. The `if` clause _expression_ is evaluated in the context outside of the `teams` construct.

Prior to #207444, this was not respected for Clang for host-side execution. Here, calls to `__kmp_push_num_teams` were missing.
However, accelerator execution is still affected by this, and does not respect the number of teams. In https://github.com/llvm/llvm-project/pull/207444#issuecomment-4912406134, I took a look at the generated IR code by Clang. While calls to `__kmp_push_num_threads` are inserted, the call is essentially a no-op. Instead, the number of leagues for the created team are set in the call to `__tgt_target_kernel`. This is not handled yet.

In Clang, [`CGOpenMPRuntime::getNumTeamsExprForTargetDirective`](https://github.com/llvm/llvm-project/blob/ef1b46f29293db7b16dee598fb1e8f2a62555c33/clang/lib/CodeGen/CGOpenMPRuntime.cpp#L6474) only checks for `OMPNumTeamsClause`, not for a potential `OMPIfClause`. I assume that a similar fix to #207444 should suffice here. In Flang, [`emitTargetCall`](https://github.com/llvm/llvm-project/blob/642b85388cca2114e467c58c02fe79b32f7b221f/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp#L9712) checks for an if condition, but only for the `target` construct itself. Handling for a potential `if` clause on the teams construct is not implemented.
This leads to the following incorrect number of teams printed:

```fortran
program main
    use omp_lib

    implicit none
 integer :: teams

    !$omp target teams if(teams: .false.) map(tofrom: teams)
      teams = omp_get_num_teams()
    !$omp end target teams

 write (*,*) teams
end program main
```

```console
$ flang -v 2>&1 | head -n 1
flang version 23.0.0git (https://github.com/llvm/llvm-project.git c2f5040f47c8e7991b36cea3afc0b855956a5475
$ flang -fopenmp --offload-arch=gfx1101 test.f90 -fopenmp-version=52
warning: OpenMP support for version 52 in flang is still incomplete [-Wexperimental-option]
warning: OpenMP support for version 52 in flang is still incomplete [-Wexperimental-option]
warning: OpenMP support for version 52 in flang is still incomplete [-Wexperimental-option]
$ ./a.out
 216
```

and a similar result for Clang:

```c
#include <omp.h>
#include <stdio.h>

int main(void) {
  int teams = 0;
  int parallel = 0;
 #pragma omp target teams distribute parallel for device(0) if(parallel: 0) if(teams: 0) map(tofrom: teams)
  for(int i = 0; i < 1000; ++i)
  {
 teams = omp_get_num_teams();
    parallel = omp_get_num_threads();
  }
 printf("Num Leagues %d\n", teams);
  printf("Num Threads %d\n", parallel);
}
```

```console
$ clang -v 2>&1 | head -n 1
clang version 23.0.0git (https://github.com/llvm/llvm-project.git c2f5040f47c8e7991b36cea3afc0b855956a5475)
$ clang -fopenmp --offload-arch=gfx1101 test.c -O0 -fopenmp-version=52
$ ./a.out
Num Leagues 216
Num Threads 0
```

Here, the `parallel` construct is properly ignored, whereas the `teams` construct still creates 216 teams instead of 1.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to