llvm/llvm-project

[OpenMP] Metadirective uses default for non-const user condition

Open

#82.754 aperta il 23 feb 2024

Vedi su GitHub
 (11 commenti) (0 reazioni) (0 assegnatari)C++ (10.782 fork)batch import
clang:openmpgood first issueopenmp

Metriche repository

Star
 (26.378 star)
Metriche merge PR
 (Merge medio 1g 2h) (1000 PR mergiate in 30 g)

Descrizione

Description

I've been looking at a few lesser used OpenMP directives recently and ran across metadirective. While the syntax always looks a bit intimidating, I wanted to know more about it and experimented with a few test cases. While doing this, I've noticed that Clang seems to use the default case whenever a user condition is used. To show this issue, I've prepared the following reproducer.

Reproducer

#include <cassert>
#include <iostream>
#include <omp.h>

int main( int argc, char** argv )
{
    constexpr size_t num_threads = 4;

    constexpr int constexpr_val = 1;
    #pragma omp metadirective \
        when( user= {condition(constexpr_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );
        }

    const int const_val = 1;
    #pragma omp metadirective \
        when( user= {condition(const_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );           
        }     

    int non_const_val = 1;
    #pragma omp metadirective \
        when( user= {condition(non_const_val > 0)} : parallel num_threads( num_threads ) ) \
        default()
        {
            #pragma omp single
            assert( num_threads == omp_get_num_threads() );
        }     
}

Here, I just want to make sure that the metadirective works. In theory, all three cases should result in the same: Having a parallel region with four threads. However, this is not the case with LLVM 15.0.7 and newer. Here's the output from LLVM trunk:

$ clang --version
clang version 19.0.0git (https://github.com/llvm/llvm-project.git 1fe6be8794964c011aeba7a66bd2dcd891d21ab0)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/apps/software/Clang/trunk/bin
$ clang++ -fopenmp reproducer.cpp
$ ./a.out                                                                                                                                                                                                                                                          
a.out: reproducer.cpp:33: int main(int, char **): Assertion `num_threads == omp_get_num_threads()' failed.
[1]    1133016 IOT instruction (core dumped)  ./a.out

NVHPC 23.9 handles this test perfectly fine. oneAPI 2024.0 fails the same way and GCC 12.3.0 even fails the first assertion. Replacing the non_const_val with a true user condition (like std::cin > non_const_val) doesn't change the outcome of the test. Looking at the IR, it seems like the metadirective is replaced by the default, resulting in no check at all if the parallel region should be used: https://godbolt.org/z/9oM5ooeE1

Guida contributor