i got a Problem with the deallocation of an allocatable character return value between a dll and the executable. After the assignment completes the exe trys to deallocate the return-value of the foo-function, wich fails.
Debug Error Message: "Damage before <Address of BAR> which was allocated by aligned routine"
Code of the dll:
! Compiler Options: ! No influence on failure: ! /Qfp-stack-check /Od /traceback /warn:all /debug:full ! Those are influencing the issue: ! /MTd /Qopenmp module TEST_MODULE implicit none contains function foo() result(bar) !DEC$ ATTRIBUTES DLLEXPORT,ALIAS:"TEST_MODULE_test" :: foo character(:), allocatable :: bar bar = 'Wiesel' write(*,'("0x",Z8.8)') loc(bar) end function end module TEST_MODULE
Code of the exe: ! Compiler Options: ! No influence on failure: ! /Od /traceback /debug:full ! Those are influencing the issue: ! /MTd (/Qopenmp) program main use TEST_MODULE implicit none character(:), allocatable :: a_char a_char = foo() end program
It works, when both Targets are using /Qopenmp, or only the exe.
It also works, if /MD(d) is used for both (did not try to mix it).
The Problem occured with Compiler 17 and 17 Update 1. It works with Compiler 16 U3 and U4.
Visual Studio 2015 / Windows 10
This is not a defect. The error message arose related to RTL (performance) improvements in the 17.0 release involving allocation/deallocation support within an OpenMP region. The error occurs where the allocating and deallocating procedures are operating with different allocation/deallocation support. It is required procedures that allocate and deallocate an array must be compiled with the (about) same options. As you noted, this error only occurs where the DLL is compiled with /Qopenmp and the main program is not.
Some documentation enhancements (to the Dynamic Allocation topic - https://software.intel.com/en-us/node/678599) are now forthcoming in the next major release related to the scenario you presented. The proposed text is shared below.
Dynamic allocation occurs at run time and is handled by the Fortran Run-Time Library. There are several restrictions on allocation and deallocation that must be observed when these operations on a specific object are performed in program units that are separately compiled. When allocation and deallocation of an object are split between procedures in static code and dynamic shared libraries (.so files on Linux*) or dynamic-link libraries (DLLs on Windows*):
- If the dynamic library is compiled with the [q or Q]openmp compiler option, then the main program must be compiled and linked with [q or Q]openmp to include the OpenMP memory handling routines in the program.
- If the dynamic library allocates data in High bandwidth (HBW) memory on Linux*, then the program must be linked with the libmemkind library to include the HBW memory handling routines in the program.
This is unfortunate. IMHO the dynamic/shared library, when .NOT. explicitly having parallel regions and/or .NOT. calling OpenMP library support functions, should be able to detect if called from or not from an OpenMP application, and then call the appropriate heap manager. This assumes/requires the dynamic/shared library be thread-safe, but not necessarily via OpenMP.