openmp & derived types with allocatable components

openmp & derived types with allocatable components

imagem de Alexis R.

I have trouble finding documentation or examples that deal with OpenMP threading of code with derived types. Can anyone recommend a good online resource or a book that covers this well?

Right now, I am trying to clarify what OpenMP3.0 directives & clauses can be used with derived types. I have read a gfortran bug report* stating that OpenMP3.0 does not specify behaviour when derived types with allocatable components are encountered. Is this correct? I didn't find this in the OpenMP3.0 specs. What's a reliable source of information on this?

In my case, I was trying to use FIRSTPRIVATE on variables of a derived type with allocatable components. Ifort (11.1.069) didn't complain during compilation, but the runtime behaviour was wrong.

If this isn't allowed, would it be possible to get ifort to give a warning or error at compile time?

*URL link feature of the forum is broken - this link is http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38724#c5

11 posts / 0 new
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.
imagem de jimdempseyatthecove

What you might be trying to do is ambiguous at best. Assume your derived type has some scalars and an allocatable array, and a pointer. While it may be clear that FIRSTPRIVATE should copy the scalars, what do you expect from the array and pointer?

a) copy of the array descriptor (and reference to same memory with aliases and without TARGET)
b) an empty array descriptor (where you must allocate)
c) and array descriptor auto-allocated to original array size then copy made there of
d) same issue of a, b, c) with pointer which may point to scalar or array.

Try breaking up

!$OMP PARALLEL DO ...

to

!$OMP PARALLEL
(construct your private copy here the way you want it (no ambiguity))
!$OMP DO ...

Jim Dempsey

www.quickthreadprogramming.com
imagem de Alexis R.

Thanks for your answer. I have since given up on using FIRSTPRIVATE, and instead am using PRIVATE for those objects and explicitely allocating memory to them in the threaded region, exactly as you suggested.

It turns out I am dealing with exactly the situation you described. My derived type has a few scalars, a REAL allocatable array and and a COMPLEX pointer array pointing to the REAL allocatable array thanks to C_F_POINTER trickery. I understand that what I was trying to do was ambiguous, although I was hoping for something like your option c).

imagem de Martyn Corden (Intel)

I'm told that the OpenMP 3.0 standard does not addressthe new language features introduced in Fortran 2003 (this includes allocatable components of derived types, as well as all sorts of object oriented features). Since an allocatable component of a derived type may itself be a derived type array with allocatable components, the potential complications go even beyond what Jim pointed out.

gfortran simply emits an error if a firstprivate entity has an allocatable component; (pointer components, which predate Fortran 2003, are allowed). Intel Fortran does not emit an error, but it looks like the firstprivate clause is ignored, and the allocatable component is treated as shared. I will submit a request to generate an error message as you suggest.

It seems like your options are either to use fixed dimension arrays as components of derived types, in order to use firstprivate, or to allocate and initializeyourself theallocatablecomponents of a derived type that has been declared as private,as Jim suggests.

imagem de dan0112

I have a very similar problem and thought I will try here before opening a new thread.

The difference is that I have a derived type with an allocatable array that should be SHARED among the threads. I tried a lot of variants, including
!$OMP PARALLEL
(construct shared my_variable here)
!$OMP DO SHARED(my_variable)

but nothing seems to work. Intel Debugger complains with SIGBUS, saying that "my_variable=no value" . Any suggestions?

imagem de Tim Prince

It looks like you would require a !$omp master clause around your "construct shared variable," if you don't move that section ahead of !$omp parallel shared(...). The shared clause works only on !$omp parallel, not on !$omp do. The way you have it, you ask all the threads to "construct shared variable," so you would have race conditions unless you do something inside to specialize each thread.

imagem de jimdempseyatthecove

I concur with TimP here. In your above case you would want:

(construct shared my_variable here)
!$OMP PARALLEL DO SHARED(my_variable)

Jim Dempsey

www.quickthreadprogramming.com
imagem de dan0112

Thanks to both of you. I had tried both solutions, and have tried again now. Always the same error. On various Intel compilers, including the most recent.

At compile time, the flag -openmp-report2 yields the message 'OpenMP DEFINED LOOP WAS PARALLELIZED.' At run-time, IDB shows that the threads are created, but the execution stops at the first $OMP directive with the error message given in my first post.

Any futher ideas?

imagem de jimdempseyatthecove

>>The difference is that I have a derived type with an allocatable array that should be SHARED among the threads.

Here is a potential "gotcha".

FORTRAN now has a feature to reallocate left hand side, should left hand side not be suitable for assignment from right hand side.
*** You must NOT have an auto reallocate left hand side occure on an array in use by another thread ***

As a non-usable quick and dirty test. Configure to allocate the derived type array(s) before the !$OMP PARALLEL DO SHARED(YourSharedArray)
Place !$OMP CRITICAL (YourSharedArray) and !$OMP END CRITICAL (YourSharedArray) around all

YourSharedArray = ...

statements, as well as all

YourSharedArray(i) = ...
YourSharedArray(i)%MemberArray = ...

Where it may be possible that a realloc_lhs occurs

Should this fix the problem, *** at the expense of performance ***, then you need to fix the assignments such that realloc_lhs does not occur (allocate sufficient room prior to entering the parallel region). Once these problems are fixed then you can remove the CRITICAL section(s).

You also might experiment with disabling realloc_lhs for the source containing this parallel do loop. This should cause an error report if reallocation is required.

Jim Dempsey

www.quickthreadprogramming.com
imagem de dan0112

I might have narrowed down the problem. I am attaching a very small program that is producing behavior that looks similar to my problem. The code is Fortran-conforming, but I am not sure about the OpenMP aspects, in particular whether I am getting the data scope clauses right. If the OpenMP part is not wrong, then there might be a compiler bug, because the code produces the expected result if compiled with

ifort -openmp

but aborts before finishing when compiled with
ifort -openmp -O0

I am very grateful for any comments.

Anexos: 

AnexoTamanho
Download main.f90302 bytes
Download policyfunctions.f901.64 KB
imagem de dan0112

Please ignore the files I uploaded, because I think I am figuring out what's going wrong. The problem in the uploaded program is that the scope of a variable is different in the Fortran setting and the OpenMP setting. Indeed, I am causing undefined behavior, which explains why different results with -O0 and the implied -O2 are possible. Let's see whether I get this working now.

Faça login para deixar um comentário.