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

MS VC DLL linking with IVF static library

jimdempseyatthecove
Honored Contributor III
4,094 Views

I have some unresolved symbol issues. First background

Solution has a C# project that uses an MS VC++ .DLL also in the solution, the DLL in turn links with an IVF static library. I am receiving linking errors when linking the .DLL. I have resolved most of the unresolved symbols excepting for:

error LNK2001: unresolved external symbol for_check_mult_overflow64
error LNK2001: unresolved external symbol for_alloc_allocatable
error LNK2001: unresolved external symbol for_dealloc_allocatable
error LNK2001: unresolved external symbol for_stop_core
error LNK2019: unresolved external symbol for_cpystr
error LNK2019: unresolved external symbol d_int_val
error LNK2019: unresolved external symbol for_fp_class_s_
error LNK2019: unresolved external symbol for_fp_class_t_
error LNK2019: unresolved external symbol for_fp_class_x_
error LNK2019: unresolved external symbol for_is_nan_s_
error LNK2019: unresolved external symbol __for_ieee_set_flag_
error LNK2019: unresolved external symbol for_is_nan_t_
error LNK2019: unresolved external symbol for_is_nan_x_
error LNK2019: unresolved external symbol for_get_fpe_
error LNK2019: unresolved external symbol for_exponent4_v
error LNK2019: unresolved external symbol for_exponent8_v
error LNK2019: unresolved external symbol for_exponent16_v
error LNK2019: unresolved external symbol __for_ieee_next_after_k4_8
error LNK2019: unresolved external symbol __for_ieee_next_after_k8_
error LNK2019: unresolved external symbol __for_ieee_next_after_k16_
error LNK2019: unresolved external symbol __for_ieee_rem_k8_
error LNK2019: unresolved external symbol __for_ieee_rem_k16_
error LNK2019: unresolved external symbol __for_ieee_scalb_k44_
error LNK2019: unresolved external symbol __for_ieee_scalb_k84_
error LNK2019: unresolved external symbol __for_ieee_scalb_k164_
error LNK2019: unresolved external symbol for_set_fpe_
error LNK2019: unresolved external symbol __for_ieee_get_flag_
error LNK2019: unresolved external symbol __for_ieee_set_halting_mode_
error LNK2019: unresolved external symbol __for_ieee_get_halting_mode_ 

The solution also contains and IVF test program that links with the IFV static library. The test program links and runs properly.

Compiling the C++ project with Intel C++ has issues with namespace System.

I haven't tried making my Fortran static library into a .DLL. I though I'd ask before going that route.

Jim Dempsey

0 Kudos
29 Replies
jimdempseyatthecove
Honored Contributor III
1,281 Views

With some experimentation I finally have the program linking again. Here is what I did:

On the C++ side:

#define mySUBROUTINE extern "C" void __cdecl
mySUBROUTINE crames_input(INTEGER NLAYERS,INTEGER NLOADSRECT,INTEGER NLOADSCIRC, INTEGER NPOINTS,DOUBLE_PRECISION* LAYERARR,
        DOUBLE_PRECISION* LOADARRRECT,DOUBLE_PRECISION* LOADARRCIRC,INTEGER* NPOINTSARR,
        DOUBLE_PRECISION* POINTSARR,DOUBLE_PRECISION* RESULTSARR,DOUBLE_PRECISION* PRINCARR,
        INTEGER IOPTION1,INTEGER ACCURACY ,INTEGER NSLIPMODEL,DOUBLE_PRECISION* SED);

(with macros defining types)

On the Fortran side remove the !DEC$ A

SUBROUTINE crames_input(nlays1,nlds_rect1,nlds_circ1,nmp1,layerarr,loadarr1,loadarr2, &
    npointsarr,pointsarr,resultsarr,principalarr,iOption1,iAccuracy1,iSlip1,sedarr) BIND(C, NAME= 'crames_input')

!not!DEC$ ATTRIBUTES STDCALL, ALIAS: 'crames_input' ::  crames_input
!DEC$ ATTRIBUTES REFERENCE::layerarr,loadarr1,loadarr2
!DEC$ ATTRIBUTES REFERENCE::npointsarr,pointsarr,resultsarr
!DEC$ ATTRIBUTES REFERENCE::principalarr
!DEC$ ATTRIBUTES REFERENCE::sedarr
!not required!DEC$ ATTRIBUTES VALUE::nlays1,nlds_rect1,nlds_circ1,nmp1,iOption1,iAccuracy1,iSlip1

So the effective solution is to

Remove !DEC$ ATTRIBUTES STDCALL, ALIAS: 'crames_input'' :: crames_input

Add BIND(C, NAME='crames_input')

Note, I also tried !DEC$ ATTRIBUTES C, ALIAS: 'crames_input'' :: crames_input

which failed as well.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,281 Views

Ah, so you were saying STDCALL on the Fortran side but not on the C++ side. That would certainly cause issues.,

Note that BIND(C) will apply the platform's name decoration rules, which for 32-bit is a leading underscore and 64-bit none. If you just use ALIAS without DECORATE, you don't get that, possibly also leading to a mismatch.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,281 Views

Not really.

I was (formerly was) using STDCALL on both sides but was using the older !DEC$ ATTRIBUTES STDCALL method.

I attempted to use, the older, !DEC$ ATTRIBUTES C on both sides, that failed too.

I switched to the newer BIND(C,...) format, and this worked. (at least it is working right now)

Yesterday the program was linking fine using the older format, this morning it did not.

I did not try ALIAS with DECORATE. That may have worked as the C++ side was looking for decorated name even though the extern "C" should have stripped off the decoration.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,281 Views

"decorated" does not mean "mangled". ?FooBar@@$$J10YGXXZ' is a mangled name. You get this in C++ when you don't use 'extern "C"

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,281 Views

Steve,

A new wrinkle.

_Offload_number_of_devices() = 1
crames_get_num_mics() = 1
crames_try_offload_mic(0) = On the sink, dlopen() returned NULL. The result of d
lerror() is "/var/volatile/tmp/coi_procs/1/7879/load_lib/80962214MIC.out: undefi
ned symbol: for_check_mult_overflow64"
On the remote process, dlopen() failed. The error message sent back from the sin
k is /var/volatile/tmp/coi_procs/1/7879/load_lib/80962214MIC.out: undefined symb
ol: for_check_mult_overflow64
offload error: cannot load library to the device 0 (error code 20)
Press any key to continue . . .

When linking the DLL with OFFLOADs the for_check_multioverflow comes back. Without offloads I believe it is OK.

Note, this error is coming from an attempt to load (resolve) the Linux equivalent of the Windows .DLL but using the Windows entry point name.

If for example, you have a routine named FooBar, and you forget to specify the attribute:

!dir$ attributes offload : mic :: FooBar
call FooBar()

Then you get a similar error. The Windows name for FooBar appears in the error message (as a suffix named alternate is use on The linux side).

Is there a work around for this? Link with ifort? How from VS 2013?

Jim

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,281 Views

Here is what I found.

The prior (earlier) issue was the missing environment variable necessary for the build to locate the libraries... for a static library running Host code.

I am now building a OFFLOAD .DLL that contains the two-way code one set of entry points and code and a differently set of modified entry point names for running on MIC.

The problem now with the (blended) DLL, is similar to what it was with the Host-only static library. The only difference is the unresolved external symbols do not show up at Link time, rather they (messages) are deferred until dynamic load failure to resolve unresolved external reference. When you have this when running a C# forms application, the informative error message goes into the bit bucket.

The problem now appears to be the library where the offload variant of for_check_mult_overflow64 is not being linked into the .dll (the external reference is for use in later load).

Is this a case where the path to the MIC variant libraries is somewhere else?

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,281 Views

The MIC target libraries are in the lib\mic folder.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,281 Views

Didn't work to add to the link library folders. The ...compiler\lib\mic contains the .so and .a libraries These are not the "fat" libraries on Windows.

I should note that the sample application I run without my .dll library has an OpenMP region inside the offset region. This uses a Linux .so library and therefore that .so file (libiomp5?) must be somehow directed to be injected into the MIC along with the offload code. I am assuming that there is an equivalent to an annotation that gets inserted into the .obj and thus .dll for the offload loader to use to find and locate the .so files on the host to be copied over to the MIC at program start (or first offload). Is there such a thing?

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,281 Views

I'm going to ask Lorri to look at this - I admit I am not all that familiar with the offload environment on Windows.

0 Kudos
Reply