Hello,
I am currently developing a Fortran library to compute integrals of a user-defined function over a given manifold. These integrals involve a sampling over the points of the manifold which I have parallelized using OpenMP. My goal is to implement GPU offloading by using nvfortran, but right now I am only trying to reproduce previous results in multicore CPUs. The sampling process is done as follows,
!$ OMP PARALLEL DEFAULT(SHARED) PRIVATE(k)
!$ OMP DO COLLAPSE(3)
do ik1 = 1, task%samples(1)
do ik2 = 1, task%samples(2)
do ik3 = 1, task%samples(3)
k = ...
data_k(ik1, ik2, ik3, :) = task%calculator(task, system, k, error)
enddo
enddo
enddo
!$ OMP END DO
!$ OMP END PARALLEL
Where task
is a Fortran derived type containing information on the sampling and a procedure pointer task%calculator
, which refers to the previously mentioned user-defined function.
When compiling with ifort/ifx/gfortran with the -qopenmp/-fopenmp flag, the library compiles and works properly. However, when doing so in nvfortran with -fopenmp/-mp=multicore flags leads to the error
/opt/nvidia/hpc_sdk/Linux_x86_64/23.7/compilers/share/llvm/bin/llc: error: /opt/nvidia/hpc_sdk/Linux_x86_64/23.7/compilers/share/llvm/bin/llc: /tmp/nvfortran8xJm0Wzu_b0o.ll:3085:12: error: use of undefined value '%u'
store ptr %u, ptr %536, align 8, !dbg !339
Some related posts [1], [2] have addressed variations of this issue in the past, but have failed to provide a general solution. I have noticed that disabling OpenMP leads to a successful compilation and that the compiler error originates in the assignment data_k(ik1, ik2, ik3, :) = task%calculator(task, system, k, error)
. However, if instead of sampling the procedure pointer task%calculator
one samples a “regular” procedure test
with the same interface as task%calculator
, even when using OpenMP, the compilation is successful.
Is there any way to circumvent this issue while using procedure pointers?
Thanks for your help,
Álvaro
A remark:
The interface of task%calculator
is:
abstract interface
function abs_calculator(task, system, k, error) result(u)
import :: global_k_data, sys, dp
class(global_k_data), intent(in) :: task
type(sys), intent(in) :: system
real(kind=dp), intent(in) :: k(3)
logical, intent(inout) :: error
complex(kind=dp) :: u(product(task%integer_indices), product(task%continuous_indices))
end function abs_calculator
end interface