A part of my job is programming special unit operations in PRO/II.
These unit operations are delivered as a DLL (UASLB.dll
) that is put in the folder of the PRO/II executables.
The interface with the PRO/II internals is very simple, it is simple Fortran with a series of functions, subroutines and old school COMMON
blocks.
The recommended compiler to create the DLL is the well known Intel Fortran compiler.
Under Windows, from there, everything is simple, you have some sample code that you can modify, you compile, put the DLL where it should be and launch PRO/II to test.
But... if you want to use the Maths Kernel Library, then you have a problem. Why? Because PRO/II is itself using the MKL and as such, you need to build and deliver your code with the same version of the MKL. This is pretty annoying because you are suddenly locked and cannot use another version of the MKL and sometimes you cannot get the exact same version, for example, depending on the state of your Intel Fortran license.
The solution is partially given in this question on StackOverflow. This is the method for some C++ code, but we can achieve the same in Fortran.
Create a text file, named Intel.MKL.manifest
(without the .txt
extension) with the following content:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="Intel.MKL" processorArchitecture="amd64" version="2019.0.5.1" type="win32" />
<file name="mkl_core.dll" />
<file name="mkl_sequential.dll" />
</assembly>
The version string must match the version string of the mkl_core.dll
you find in your redistribution folder of the MKL.
For my installation, the folder is: C://Program Files (x86)/IntelSWTools/compilers_and_libraries_2019/windows/redist/intel64_win/mkl
.
Please note that in my case, I am running everything as 64-Bit versions, but you can have x86
instead of amd64
. In fact, the processorArchitecture
key is optional.
- Given the
bin
folder where your DLL, hereUASLB.dll
, is, create the subfolderIntel.MKL
in it. - In the
Intel.MKL
folder, copy the content of the redistribution of the MKL in it. That is, you should havemkl_core.dll
,mkl_sequential.dll
, etc. in thebin/Intel.MKL
folder. - Put, like said in the SO question, the
Intel.MKL.manifest
file inside theIntel.MKL
folder.
The rest of the work has to be done at the creation of the DLL by embedding a manifest inside the DLL referencing the Intel.MKL
assembly with its right version.
Fortran is not C++, so the best way to reference our special assembly is to do it in the options of the project.
- Enable the generation of the manifest.
- Add in the command line of the linker the following argument:
/manifestDependency:"name='Intel.MKL' processorArchitecture='amd64' version='2019.0.5.1' type='win32'"
During compilation, it will create in the output folder an .intermediate.manifest
file which should have the following content:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity name='Intel.MKL' processorArchitecture='amd64' version='2019.0.5.1' type='win32' />
</dependentAssembly>
</dependency>
</assembly>
This is what is then embedded in the DLL. The result is that the DLL will correctly load the your MKL version. You can see it with a dependency walker. Please note that all these manifest
stuff is the Windows way of loading the right library and this is working better than expected.
Do not hesitate to contact me if you have Fortran questions.