Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7942 Discussions

Incorrect initialization of a shared object in an OpenMP parallel for - bug in the intel compiler?

Giovanni_R_
Beginner
676 Views

I have the following code:

#include <iostream>
using std::cout;

struct Test {
int a[3];
};

void function (Test b) {
#pragma omp parallel for default(none) shared(cout,b)
for (int i=0; i<10; i++) {
cout << b.a[0] << " " << b.a[1] << " " << b.a[2] <<std::endl;
}
}


int main() {

Test a;
a.a[0]=1;
a.a[1]=2;
a.a[2]=3;

function(a);



}

When running it I would expect it to print 1 2 3 on each line. Indeed this happens when compiling in serial or with openmp using, e.g., g++. However when using the intel compiler (version 15.0.4 20150805 on Linux) with openmp I get 1 0 1 on each line. Is this a bug in the compiler, or am I doing something disallowed by the c++ or openmp standard? Note that if I pass the object by reference to the function everything is fine.

0 Kudos
8 Replies
Kittur_G_Intel
Employee
676 Views

Hi,
Even with g++ the test case you indicate cannot be producing the same result, the reason being the shared line containing cout.
Note that cout is not an atomic operation and not thread safe as well. Also,  as it's shared two or more threads can output simultaneously.  Hence it is essential to ensure that cout calls are executed in critical region or by only the master thread. Hence the result you get whether using gcc or icc won't be consistent or the same with different runs. Executing cout in the critical section as below is the way to go for this small example you have to ensure consistent results.
    #pragma omp critical
    {
      cout << b.a[0] << " " << b.a[1] << " " << b.a[2] <<std::endl;
    }
 
_Kittur

 

 

 

0 Kudos
Giovanni_R_
Beginner
676 Views

Hi,

no - that's not the issue. I only use cout to highlight what the problem is. The code I showed is just the minimal example from a much more complicated code where the problem came out, where I use a more complicated version of class Test to do some computation. And like in this case, the array inside the Test class has wrong values inside the openmp loop.

In any case, I'm running with only one thread so what you describe is not an issue. The problem is that b is incorrectly initialised by the compiler when entering the openmp loop.

0 Kudos
Giovanni_R_
Beginner
676 Views

In case it is not clear from my previous comment, the issue remains also when I put the critical as suggested by Kittur. Once again, is this a compiler bug or am I doing something disallowed by the standard (and if yes, what?)?

0 Kudos
Kittur_G_Intel
Employee
676 Views

@Giovanni:  Based on the small test snippet you attached is what my comment was made.  

File Attached: run.out -  showing  the run of  the code snippet with omp critical added for the line containing cout and printing of b array values which work fine  If you can attach a reproducer that can reproduce the issue you mention I'd be glad to look into and file an issue as well. Can you try and attach one if possible?  Thanks.

_Kittur

0 Kudos
Giovanni_R_
Beginner
676 Views

@Kittur: thanks for looking into this, I hope that what I attached is what you need, I tried to reproduce what you sent. Let me know if you need further information

0 Kudos
Kittur_G_Intel
Employee
676 Views

Hi Giovanni,
I know what the issue is now. It doesn't output correctly with the 15.0.4 version you're correct. Somehow I thought I'd tried with that version and looks like it was the 16.0.1 version which seems to have resolved this issue.

So, could you please download the latest 16.0 update 1 release from the Intel Registration Center and try it out? It should work properly for the code snippet you attached with omp critical pragma inserted, thx.

_Kittur

0 Kudos
Giovanni_R_
Beginner
676 Views

Hi Kittur,

many thanks for looking into this. Unfortunately I am a scientist and my code runs on supercomputers; I must rely on the sysadmins to upgrade the compiler, and I don't directly have access to the intel compilers on my local machines. The same situation applies to other users of the code; they will get it as source and compile it on the supercomputer they are going to use. Now that you have confirmed that this was indeed a bug in the compiler, there are two things that I would like to know from you:

1) which versions of the compiler are affected, so that I can let my users know. It seems that the error is fixed in version 16 from what you said, but I don't know in which version it was introduced

2) if you can confirm that passing the object by reference to the function is fine. I know that in the cases I've tried is fine, but obviously this is no guarantee that it always works, i might just have been lucky

Giovanni

0 Kudos
Kittur_G_Intel
Employee
676 Views

HI Giovanni,
Yes I verified again and here's my response to your questions:

1)  I tried all the last released version of 14.0.6 and the error exists but goes away when you pass by reference. I also tried all versions of 15.0 and error exists but goes away when you pass by reference.  That said, of course with the 16.0.0 and the latest 16.0.1 release it works fine and also when you pass by reference

2) Yes, I verified that passing by reference works fine with all versions above on the code snippet we're working with here, thanks.

_Regards,
Kittur 

 

0 Kudos
Reply