- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page