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

Can't use allocatable arrays with !$OMP DECLARE TARGET in a module

cu238
Beginner
378 Views

In OpenMP GPU Offload coding, allocatable arrays seem to be extremely HARD to use as "present".

Consider the module:

MODULE ALL_VARS

!$OMP DECLARE TARGET(XT,YT)

Real,Allocatable :: XT(:),YT(:)

End MODULE ALL_VARS

After XT and YT are allocated with

Allocate(XT(0:NT),YT(0:NT))

and updated with

!$OMP TARGET UPDATE TO (XT,YT)

the code below

!$OMP TARGET DEFAULTMAP(present: allocatable)
!$OMP TEAMS DISTRIBUTE PARALLEL DO
do I=0,NT
    XT(I)=0.0
    YT(I)=0.0
enddo
!$OMP END TARGET

will report errors:

Libomptarget message: device mapping required by 'present' map type modifier does not exist for host address 0x0000015a1d036990 (493628 bytes)

Libomptarget error: Call to getTargetPointer returned null pointer ('present' map type modifier).
Libomptarget error: Call to targetDataBegin failed, abort target.
Libomptarget error: Failed to process data before launching the kernel.
Libomptarget error: Run with
Libomptarget error: LIBOMPTARGET_DEBUG=1 to display basic debug information.
Libomptarget error: LIBOMPTARGET_DEBUG=2 to display calls to the compute runtime.
Libomptarget error: LIBOMPTARGET_INFO=4 to dump host-target pointer mappings.
Libomptarget error: Source location information not present. Compile with -g or -gline-tables-only.
Libomptarget fatal error 1: failure of target construct while offloading is mandatory

If updated code

!$OMP TARGET UPDATE TO (XT,YT)

is replaced by

!$OMP TARGET ENTER DATA MAP(to:XT,YT)

, there will be no 'present' map error reports, but XT and YT will not be shared by subroutines using the same module (ALL_VARS) and fail to pass values.

I don't know how to get global allocatable arrays used in GPU with OpenMP.

I wish there is a way.

Thanks a lot.

 

Labels (2)
0 Kudos
1 Solution
TobiasK
Moderator
241 Views

@cu238


This is interesting. I have to discuss with our internal experts but I think it's a bug in the Openmp spec. It just does not make sense to have allocatables allowed in a "declare target" clause.

The reason is quite simply, you are allowed to map an unallocated array but as long as it is mapped the allocation status may not change.

Now if you declare an allocatable array with declare target it is mapped you map it before execution of the program, hence you are never allowed to change it's allocation status.


That's also why your second attempt does not work. You have to remove the declare target.


Handling of such global arrays is straight forward, after the point where you allocate the array, put your !$omp enter target data map(alloc:..) clause and make it available in the device environment. Just remember to remove it from the device environment before you deallocate the array on the host.

Remember that you need to synchronize the data between host and device manually, all mapping clauses are ignored on data that is already present.



View solution in original post

0 Kudos
5 Replies
Ron_Green
Moderator
335 Views

what is the value of NT?

0 Kudos
cu238
Beginner
299 Views

NT=80526

0 Kudos
TobiasK
Moderator
242 Views

@cu238


This is interesting. I have to discuss with our internal experts but I think it's a bug in the Openmp spec. It just does not make sense to have allocatables allowed in a "declare target" clause.

The reason is quite simply, you are allowed to map an unallocated array but as long as it is mapped the allocation status may not change.

Now if you declare an allocatable array with declare target it is mapped you map it before execution of the program, hence you are never allowed to change it's allocation status.


That's also why your second attempt does not work. You have to remove the declare target.


Handling of such global arrays is straight forward, after the point where you allocate the array, put your !$omp enter target data map(alloc:..) clause and make it available in the device environment. Just remember to remove it from the device environment before you deallocate the array on the host.

Remember that you need to synchronize the data between host and device manually, all mapping clauses are ignored on data that is already present.



0 Kudos
cu238
Beginner
163 Views

Thanks a lot for your guiding.  It's really important to my program.

I used to use 1-line Code A

!$OMP TARGET ENTER DATA MAP(to:XT,YT)

which I thought should be equivalent to 2-lines Code B

!$OMP TARGET ENTER DATA MAP(alloc:XT,YT)

!$OMP TARGET UPDATE TO (XT,YT)

but Code A does not work correctly.

Now I use Code B and the program's result is correct.

By the way, I wish that Code A could be either equivalent to Code B or display an error like "Allocatable Arrays could only be mapped by 'alloc:' ... "

Thanks again.

0 Kudos
TobiasK
Moderator
88 Views

@cu238


sorry my previous commit is wrong, declare target on a global allocatable array is allowed.

However, I still believe it should not be allowed since it generates a lot of trouble.


to make your code work, can you please add

!$omp target enter data map(always,to:xt,yt)?


the always modifier forces an update of the arrays even though they are already present in the device environment. Otherwise the map clause is ignored since the arrays are already there.


0 Kudos
Reply