myusrnam wrote:For a 'parallel for' directive, what is the default status of a variable within its construct-----shared, or private? I find it difficult to understand the spec on this issue.
In general, OpenMP uses a shared memory model, so by default most things are shared. That said, there are a lot of "ifs, ands, and buts". If you look at the OpenMP V2.5 spec, section 2.8 Data Environment tries to explain all the various cases for the different languages. So let's take the following simple example:
- Code: Select all
int a = 0, b = 0, i;
#pragma omp parallel firstprivate(a)
static, int e;
#pragma omp for
for (i = 0; i < 5; i++)
myusrnam wrote:From (unoffiical) documents I've read on the web, I *think* this is how it works: variables in the construct of a 'parallel for' directive (which, basically, means variables within the for loop being parallelized) are shared except for the iterator of the loop and except for any variables created off the stack inside the loop, or created inside of any functions / methods called within the loop. Is this correct?
In my simple example, when the parallel directive is encountered (page and line numbers are from the OpenMP V2.5 spec):
- "a" is firstprivate because of the clause (p64:35-36 - Variables referenced in the construct are said to have an explicitly determined sharing attribute if they are listed in a data-sharing attribute clause on the construct).
- "b" and "i" are shared (p65:1-6 - Variables referenced in the construct whose sharing attribute is not predetermined or explicitly determined will have their sharing attribute implicitly determined. In a parallel construct, the sharing attributes of these variables is determined by the default clause, if present. If no default clause is present, variables with implicitly determined sharing attributes are shared).
Now looking at the variables declared within the parallel region:
- "d" is private (p64: 1-2 - Variables with automatic storage duration which are declared in a scope inside the
construct are private).
- "e" is shared (p64:4 - Static data members are shared).
Now we see the for directive:
- "i" is private (p64:5-6 - The loop iteration variable in the for-loop of a for or parallel for construct is private in that construct).
So you are correct on the first part.
The last part - variables are shared except when "created inside of any functions" is incorrect. If you look at section 18.104.22.168 Sharing Attribute Rules for Variables Referenced in a Region, but not in a Construct, you will see there are many cases where the variables are shared. For example (static variables declared in called routines in the region are shared):
- Code: Select all
static int a; // a is shared
#pragma omp parallel
myusrnam wrote:I have a follow on question. When a "shared" clause is used with a 'parallel for' directive, does OpenMP interpret this as the user specifying that *ONLY* the variables within that clause are shared, and all others private? Perhaps my question can be phrased more generally. What is the status of a variable *NOT* mentioned in the shared clause? What if the default status of that variable would have been shared had the clause not existed? Does that variable still remain shared even if it is not mentioned in the 'shared' clause?
From section 22.214.171.124 (p64:35-36), variables referenced in the construct are said to have an explicitly determined sharing attribute if they are listed in a data-sharing attribute clause on the construct. So by putting a variable in the shared clause, you have explicitly stated what you want it's sharing attributes to be. It doesn't say anything about the sharing attributes of any of the other variables. They are determined in accordance with the information in section 2.8.
myusrnam wrote:We recently had an application core dump after inserting a 'parallel for' directive with an incomplete list of shared variables in a "shared" clause. By "incomplete" I mean that, just by inspection, one could identify variables in the for loop being parallelized that were obviously shared, but which had been left out of the shared clause's list. When I removed the entire shared clause, the core dump went away and the code seemed to function correctly, when using multiple threads. I am wondering if this is because, by using a shared clause, we made all variables not mentioned in that clause 'private', and, in this manner, accidentally corrupted the value of what should have been a shared variable. It also occured to me that *if* shared clauses work this way and if the default definition of shared variables encompasses almost all variables one would normally think of as shared, I am thinking that use of 'shared' clauses is (a) almost never needed (since the default captures all you're likely to want), and (b)is dangerous.
Normally I would say that a shared clause is not necessary. However, when parallelizing code, personally I would use "default(none)" and explicitly state the sharing attributes for each variable in a clause. I know this can be a lot of work. However, there are tools that can help do this and in doing this you make sure you really know how each variable is being handled. In the long run, it usually saves you time. In any case, from what you have said, I have no idea why putting the variable in a shared clause would cause a core dump. If you can give me a small example, maybe it would make more sense to me.