Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29279 Discussions

How to control serially in openmp parallel section

Vivid
New Contributor I
6,614 Views

I wrote parallel code through openmp in fortran. A number of dynamically allocated arrays are included. In order to prevent data infringement between threads, it is allocated at the start branch within the parallel statement and freed before parallel termination.

It seems that memory invasion occurs when using the existing allocation method. Assuming 4 threads, the problem seems to occur because thread 3 accesses the memory area allocated by thread 0 at the same time. I would be very grateful if you could tell me how to solve it.

0 Kudos
25 Replies
Vivid
New Contributor I
1,051 Views

This answer was also very helpful. 

 

1. Shared type, barrier, single, Deadlock

I found out that the shared type can control memory so that B is not allocated redundantly through barrier and single, as you mentioned.

Here's what I understand about deadlock:
The situation is different in that the code you provided occurs in one place, but the actual code calls the subroutine 'yourReallocationOfB' for reallocation from several subroutines called within omp do. Whenever the size of the array is insufficient, it instructs to reallocate and store the values again. There are not that many cases where the size of the array is judged to be insufficient, but it happens more than once. In this case, the barrier and single directives seem to indicate that a deadlock may occur because different threads are waiting at the barrier.

 

2. threadprivate, module, GA.IN_tests(10) -> GA.IN_tests(100)

The remaining issues are as follows:

type (T_H_Class) :: GA, and GA was declared as threadprivate. Although GA.IN_test was declared as 10, it must be reallocated to GA.IN_test(100) by some calculation within the omp do statement. Here, not all threads 0 to 3 are reallocated. Some threads may need 30 GA.IN_tests.

And when GA.IN_tests are reallocated from 10 to 100, a subroutine for reallocation will be called. With the same mechanism mentioned earlier. In the subroutine TEST(B), allocatable type A is assigned and B's data is stored in A. After releasing B, assign it as 100, copy the value stored in A to B, then release A and return.

Based on your answers, this may be a risk of deadlock. If I use barrier, each thread will be waiting at the barrier before calling TEST(B). If I do not use the barrier, it seems that thread 1 may invade the area of thread 3 in the heap area memory, which is a large chunk. It would be better if there was no reallocation within the omp do loop within the omp area, but reallocation is absolutely necessary due to the nature of the code.

 

3. dll

I'm not sure what third party dll means. I am using Intel's Fortran compiler and have enabled openMP in the solution option. Do you mean a subroutine that reallocates active common types from program start to end? This subroutine declares the pointer type to reallocate the common array A. It was declared as allocatable, target, and save, but a problem occurred, so it was declared as pointer type. So, in this subroutine for dynamic allocation, an array could be passed and passed as a parameter.

There seems to be no problem with this common statement as it is declared as shared to only read the value. If a situation arises where I want to write a value, I think I should declare and use a copied allocatable array.

 

4. pointer

I would like to understand pointer and allocatable well and modify the code. Can I refer to other posts on the forum? It's a bit of an old post, but I think the purpose is the same. https://community.intel.com/t5/Intel-Fortran-Compiler/POINTER-vs-ALLOCATABLE/m-p/841082

 

I'm sorry for causing you so much trouble due to my lack of knowledge about openmp.

Thank you so much.

Vivid

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,042 Views

>>... can control memory so that B is not allocated redundantly...

Not only that, but also the barrier assures that B is not currently in use.

 

>> deadlock

A deadlock will occur should threads of a team be waiting at different barriers. 

 

>> GA.IN_tests

You stated that GA was a threadprivate. As such, each thread has its own GA, thus its own GA.IN_tests array. As such, each thread can have different sizes as well as different memory locations for its data. Allocation/deallocation/reallocation need not be protected.

 

>> dll

You stated you are using a 3rd party library. On Windows this is typically a DLL (Linux a .so). But if this is a .lib file (or .obj file(s)). The same issue applies should the API should the call into the library pass data in/out via COMMON /SomeSpecifiedNameHere/ ...

In that case, their code most likely did not declare that named common was threadprivate, and as a result, all calls from all threads would use the master thread's data.

On the flip side, should the API only pass data in/out via arguments on call, then the call may or may not be thread-safe. Should this library contain SAVE variables, then it won't be thread-safe. Also, if the library performs I/O, there may be issues.

 

(more later)

Jim Dempsey

Vivid
New Contributor I
1,030 Views

I'm glad to see your response before I leave work.

 

>>dll

First of all, I probably made a mistake when I said that I was using a third-party library, lib obj, etc.

My guess is that I conveyed that misunderstanding while explaining the following.

The subroutine for dynamic allocation and deallocation was entered in the A.f90 file, but there was a problem when calling this subroutine from B.f90. So, I wrote down the variables of the subroutine by writing an interface in the A_header.fi file. And the problem was solved by declaring include 'A_header.fi' when calling the reallocation subroutine in B.f90.

 

Interface
  Subroutine REAL_ALLOC (TEXT, ARRAY1, INDEX1, INDEX2, I_DEC)
    Integer*4:: INDEX1, INDEX2
    Integer*4:: I_DEC
    Real*8, Pointer:: ARRAY1(:)
    Character*5:: TEXT
  END Subroutine
END Interface

 

 

 

Your answer

>> GA.IN_tests

You stated that GA was a threadprivate. As such, each thread has its own GA, thus its own GA.IN_tests array. As such, each thread can have different sizes as well as different memory locations for its data. Allocation/deallocation/reallocation need not be protected.

 

I found this answer very helpful. Based on the answers, we will configure a test project again and test it. Since GA is threadprivate, this means that you don't have to worry about memory invasion regarding allocation at all.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,039 Views

Think of OpenMP as a team project (with people). You have to avoid conflicts, and when there are dependencies, you must wait for the dependencies to be resolved.

 

Jim Dempsey

jimdempseyatthecove
Honored Contributor III
1,023 Views

That is an incorrect way to reallocate GA.IN_test. It is unclear as to if INDEX1 and INDEX2 are indices or sizes. Or if I_DEC is a size and INDEX1, INDEX2 are lower bounds and upper bounds.

 

Please show the call, what the caller expects to be returned, and what REAL_ALLOC does. Be complete at to the types, including attributes (e.t. threadprivate and/or target).

 

Jim Dempsey

 

 

0 Kudos
Reply