bsc-pm / mcxx

Mercurium is a C/C++/Fortran source-to-source compilation infrastructure aimed at fast prototyping developed by the Programming Models group at the Barcelona Supercomputing Center
GNU Lesser General Public License v3.0
69 stars 23 forks source link

Compilation with OmpSs-2 and OpenMP #39

Closed Z10Frank closed 2 years ago

Z10Frank commented 2 years ago

Hello, I was exploring the compatibility with OpenMP with a simple test. I know that OpenMP compatibility is not fully supported, nor it is guaranteed in any case, but I am wondering if I am making some mistakes in the compilation.

My test:

#include <stdio.h>
#include <iostream>
#include <omp.h>
using namespace std;

int main(int argc, char *argv[])
{
    #pragma omp for 
    for (int i=0; i<10; i++)
    {
        cout<<"Hello omp, iteration "<<i<<"\n"<<endl;
    }

    for (int i=0; i<10; i++)
    {
        #pragma oss task firstprivate(i)
        {
            #pragma oss critical
            {
                cout<<"Hello OmpSs-2/, iteration "<<i<<endl;
            }
        }
    }
    return 0;
}

My compilation commands:

export CXX=icpc
export CC=icc
export MERCURIUM=/gpfs/users/massimof/mcxx/install/bin/
export PATH=$MERCURIUM:$PATH

I_MPI_CXX=mcxx MPICH_CXX=mcxx OMPI_CXX=mcxx mpiicpc --ompss-2 -O3 -std=c++11 -o test_OpenMP_OmpSs-2 --openmp-compatibility -fopenmp test_OpenMP_OmpSs-2.cpp -lz

In correspondence with the OpenMP pragma, an error occurs: error: this construct is not supported by Nanos6. Using a #pragma omp parallel for yields warning: explicit parallel regions do not have any effect in OmpSs.

Mercurium should have been compiled with OpenMP support:

export MERCURIUM=/gpfs/users/massimof/mcxx/install
export BISON=/gpfs/users/massimof/bison-2.6.5/install/bin/bison
export FLEX=/gpfs/users/massimof/flex-2.6.4/install/bin/flex
export GPERF=/gpfs/users/massimof/gperf-3.1/install/bin/gperf
export NANOSSIX=/gpfs/users/massimof/nanos6/install
export GIT=/gpfs/softs/spack/opt/spack/linux-centos7-cascadelake/gcc-9.2.0/git-2.25.0-lojbmyepxnaay2yotcnyzwwty36rnjyq/bin/git
export NANOSS=/gpfs/users/massimof/ompss-19.06/nanox-0.15/install

./configure BISON=$BISON FLEX=$FLEX GPERF=$GPERF GIT=$GIT --prefix=$MERCURIUM --enable-ompss-2 --with-nanos6=$NANOSSIX --enable-openmp --with-nanox=$NANOSS
make -j 10
make install

In the log file for the compilation of Mercurium it can be read:

checking if enabled OmpSs support in the compiler for Nanos++... no
checking if enabled OpenMP support in the compiler for Nanos++... yes
checking if enabled OmpSs-2 support in the compiler for Nanos6... yes
checking nanos.h usability... yes
checking nanos.h presence... yes
checking for nanos.h... yes
checking whether used installation of Nanos++ has instrumentation support... yes
...
checking nanos6.h usability... yes
checking nanos6.h presence... yes
checking for nanos6.h... yes
checking for nanos6_in_final in -lnanos6... yes

If I try to compile only with OmpSs-2 pragmas, everything works correctly. So, is there something missing in my compilation?

rofirrim commented 2 years ago

Hi @Z10Frank,

I think in this case you can use #pragma oss task for as described here

https://pm.bsc.es/ftp/ompss-2/doc/spec/directives/index.html#task-for-clause

Let me know if this is useful.

Kind regards,

Z10Frank commented 2 years ago

Hello, thank you for your answer, I know the #pragma oss task for construct, but my purpose was rather to understand the compatibility with OpenMP itself.

The objective is to progressively "taskify" a load imbalanced part of an existing code that already uses OpenMP, in particular with parallel regions, omp for, omp simd. So a preliminary question is if the use of OmpSs-2 in this code would imply the substitution of all existing OpenMP pragmas with "equivalents" in OmpSs-2. Or if there is a way to switch between OpenMP and OmpSs-2 pragmas with an if condition.

rofirrim commented 2 years ago

The objective is to progressively "taskify" a load imbalanced part of an existing code that already uses OpenMP, in particular with parallel regions, omp for, omp simd. So a preliminary question is if the use of OmpSs-2 in this code would imply the substitution of all existing OpenMP pragmas with "equivalents" in OmpSs-2.

The OmpSs-2 compatibility with OpenMP is limited. It may happen that some constructs will require you to substitute/temporarily disable the unsupported OpenMP constructs.

Or if there is a way to switch between OpenMP and OmpSs-2 pragmas with an if condition.

Not sure what you mean by "if" condition here, one option is using the macro _OMPSS_2 so you can enable OpenMP or OmpSs-2 progressively in your code. This macro is enabled when you use --ompss-2 with Mercurium.

#if _OMPSS_2
#pragma oss task ...
#else 
#pragma omp ...
#endif

Hope this helps.

Z10Frank commented 2 years ago

Thank you! To keep it in the archives, my test after the modifications:

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

using namespace std;

int main(int argc, char *argv[])
{
    #ifndef _OMPSS_2
    #pragma omp parallel
    #endif
    {

    #ifndef _OMPSS_2
    //with OpenMP
    #pragma omp for
    for (int i=0; i<10; i++)
    {
        #pragma omp critical
        cout<<"Hello omp for from thread "<<omp_get_thread_num()<<" iteration "<<i<<"\n"<<endl;
    }

    #else
    // with OmpSs-2
    for (int i=0; i<10; i++)
    {
        #pragma oss task firstprivate(i)
        {
        #pragma oss critical
        {
            cout<<"Hello OmpSs-2/, iteration "<<i<<endl;
        }
        }
    }
    #endif

    } // end parallel region if OpenMP is used
    return 0;

}

To compile with OpenMP:

mpiicpc -o test_OpenMP -fopenmp test_OpenMP_OmpSs-2.cpp

To compile with OmpSs-2:

I_MPI_CXX=mcxx MPICH_CXX=mcxx OMPI_CXX=mcxx mpiicpc -o test_OmpSs-2 --ompss-2 test_OpenMP_OmpSs-2.cpp