Creating DLL for Excel with OpenMP


I am trying to create a Fortran based DLL with OpenMP for use in Excel VBA. I am able to successfully create and use the non-OpenMP version. However, as soon as I include the OpenMP directives, and create the DLL, Excel crashes as soon as tries to use the DLL. If I compile the same code as an executable, I see the expected OpenMP behavior and output.

!program main
!implicit none
!call myarrtest(xx,yy,4,4)
!write(*,*) xx
!write(*,*) yy
!end program

subroutine myarrtest(arrin,arrout,sz1,sz2)

use omp_lib

!DEC$ ATTRIBUTES REFERENCE::arrin,arrout,sz1,sz2

implicit none

!$omp parallel num_threads(4) private(nthreads, tid)

tid = omp_get_thread_num()

!if (tid .eq. 0) then
!nthreads = omp_get_num_threads()
!print *, 'Number of threads = ', nthreads
!end if
!print *, 'Hello World from thread = ', tid

do j=1,sz2
end do

!$omp end parallel

end subroutine

I compile the above code using the following command

pgfortran -mp -Mmakedll -Bstatic -o myarrtest_openmp.dll myarrtest_openmp.f90

The executable can be compiled by adding/removing appropriate comments. The executable seems to work fine.

The Excel side of VBA call is as follows.

Declare Sub myarrtest Lib "C:\OpenShare\Programming_Stuff\Fortran_Apps\Excel_Fortran_DLL\mytest\myarrtest_openmp.dll" _
    (ByRef x As Double, ByRef y As Double, ByRef n1 As Integer, ByRef n2 As Integer)
Call myarrtest(vbarr(1, 1), fortarr(1, 1), n1, n2)

Any ideas of why the OpenMP setup crashes in Excel would be greatly appreciated. On a side note, I was able to successfully achieve this using Intel Fortran. I am hoping to solve this as I would like to eventually move towards a hybrid OpenMP+CUDA Fortran implementation.

Thanks in advance,

  • Sam V


I think you are saying that OpenMP code runs when linked
statically with the executable, and it crashes when trying to
dynamically link an OpenMP routine at runtime.

If you put a second OpenMP call/routine into the executable, does the
dynamically linked one now work?

My guess is there is something that needs to be set up/initialized
before executing an OpenMP DLL routine.