https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128041

            Bug ID: 128041
           Summary: [OpenMP] Metadirective with 'teams' does not generate
                    'teams' directive
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: openmp, rejects-valid, wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

The following code should produce (twice):

      #pragma omp target num_teams(0) thread_limit(0) firstprivate(n)
            #pragma omp teams shared(n)
                    #pragma omp distribute private(i.1)

but it produces for the second code the following - note the "-2" for
num_teams:

      #pragma omp target num_teams(-2) thread_limit(0) firstprivate(n)
            #pragma omp teams shared(n)
                    #pragma omp distribute private(i.3)

That's for Fortran, for C/C++ it is even worse, producing for the second:

      #pragma omp target num_teams(-2) thread_limit(0) firstprivate(N)
            #pragma omp distribute private(i.3)

Yes, there is no 'teams' at all.

NOTE: This should work with both static and pseudo-static context selectors
(aka 'device={…}' which is late resolved when offloading is enabled) - and it
must work with combined directives and with clauses.

[When not inside of in 'target', it must also work with dynamic context
selectors, but then there is no 'target' and no num_teams-on-target to take
care of.]

* * *

Long version of the testcase:
https://github.com/OpenMP-Validation-and-Verification/OpenMP_VV/blob/master/tests/5.0/metadirective/test_metadirective_arch_nvidia_or_amd.c#L28-L36

* * *

Short versions:
---------------------------------------------------------
int metadirective2(int N) {
   int i;
     #pragma omp target map(from: i)
     {
       #pragma omp teams
       #pragma omp distribute parallel for
         for (i = 0; i < N; i++) {   }
     }
     #pragma omp target map(from: i)
     {
       #pragma omp metadirective \
                  otherwise (teams)
       #pragma omp distribute parallel for
         for (i = 0; i < N; i++) {   }
     }
   return i;
}
---------------------------------------------------------
integer function metadirective2(N)
  implicit none
  integer, value :: N
  integer :: i

  !$omp target map(from: i)
    !$omp teams
       !$omp distribute parallel do
       do i = 1, N 
       end do
    !$omp end teams
  !$omp end target
  !$omp target map(from: i)
     !$omp begin metadirective otherwise (teams)
       !$omp distribute parallel do
       do i = 1, N 
       end do
     !$omp end metadirective
  !$omp end target
  metadirective2 = i
end
---------------------------------------------------------

Reply via email to