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
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 ,  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,
The interface of
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