简体   繁体   中英

Why do I get undefined behavior when using OpenMP's firstprivate with std::vector on Intel compiler?

I have a problem when using OpenMP in combination with firstprivate and std::vector on the Intel c++ compiler. Take the following three functions:

#include <omp.h>

void pass_vector_by_value(std::vector<double> p) {
#pragma omp parallel
{
    //do sth
}
}

void pass_vector_by_value_and_use_firstprivate(std::vector<double> p) {
#pragma omp parallel firstprivate(p)
{
    //do sth
}
}

void create_vector_locally_and_use_firstprivate() {
std::vector<double> p(3, 7);
#pragma omp parallel firstprivate(p)
{
    //do sth
}
}

The code compiles without warnings doing:

icc filename.cpp -openmp -Wall -pedantic

(icc version 14.0.1 (gcc version 4.7.0 compatibility))

or:

g++ filename.cpp -fopenmp -Wall -pedantic

(gcc version 4.7.2 20130108 [gcc-4_7-branch revision 195012] (SUSE Linux))

but after compiling with icc I am getting runtime errors such as:

*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x00007fff31bcc980 ***

when calling the second function (pass_vector_by_value_and_use_firstprivate)

So the error only occurs when the firstprivate clause is used (which should invoke the copy constructor) and the vector is passed by value to the function (which should invoke the copy constructor as well). When either not passing the vector but creating it locally in the function or not using firstprivate there is no error! On gcc I do not get any errors.

I am wondering if the code somehow produces undefined behavior or if this is a bug in icc ?

I get the same problem with ICC but not GCC. Looks like a bug. Here is a workaround

void pass_vector_by_value2(std::vector<double> p) {
    #pragma omp parallel
    {
        std::vector<double> p_private = p;
        //do sth with p_private      
    }
}

On the other hand, in general, I don't pass non-POD by value to functions anyway. I would use a reference but if you do that you get the error

error: ‘p’ has reference type for ‘firstprivate’

The solution to that is the code I posted above anyway. Pass it by value or by reference and then define a private copy inside the parallel region as I did in the code above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM