可以在同一个过程中使用多个版本的MKL吗?

时间:2014-07-21 14:01:49

标签: dll intel-mkl

我们正在为Windows环境中的第三方应用程序开发插件(每个插件都是存储在预先指定的文件夹中的DLL文件)。该应用程序在内部使用英特尔MKL 10.3.9.1,并在其安装文件夹中附带MKL DLL。

我们的插件DLL也依赖于MKL,但我们必须使用更高版本(11.1.3.1),因为我们使用VS2012(旧版本的MKL不支持它)。我们将MKL DLL放在插件文件夹中,以及我们自己的DLL,它是针对所述MKL版本构建的。这就是我们的代码与MKL的链接(在x64配置中):

#pragma comment(lib, "mkl_intel_lp64_dll")
#pragma comment(lib, "mkl_intel_thread_dll")

当应用程序运行时,它会从其文件夹中加载MKL 10.3 DLL。当加载插件DLL时,似乎加载了MKL 11.1 DLL(至少访问了文件),但随后应用程序冻结(如果连接了调试器,我会看到访问冲突异常)。如果我们的代码的MKL依赖部分被存根替换,有效地消除了对MKL的依赖,应用程序运行并使用插件就好了。

我猜这些问题出现是因为我们的DLL期望与MKL 11.1一起使用,但实际上是获得了之前加载的MKL 10.3(请注意,不同MKL版本的DLL具有相同的名称)。

有谁知道是否可以将两个不同版本的MKL加载到同一个进程中?

1 个答案:

答案 0 :(得分:0)

我设法解决了这个问题,并允许我们的插件使用不同版本的MKL而不是托管应用程序,采取以下步骤(受this thread的启发,由this answer引用 - 描述了一个不同但相关的场景):

  1. 将MKL 11.1 DLL放在名为Intel.MKL的插件文件夹下的子文件夹中(而不是插件文件夹本身,我们的插件DLL存储在其中)。

  2. 在上述Intel.MKL.manifest文件夹中添加名为Intel.MKL的文件,其中包含以下内容:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity name="Intel.MKL" processorArchitecture="amd64" version="11.1.3.1" type="win32" />
        <file name="mkl_core.dll" />
        <file name="mkl_intel_thread.dll" />
    </assembly>
    
  3. 在我们的插件DLL的代码中,将其添加到某些* .cpp文件中:

    #pragma comment(linker, "/manifestDependency:\"name='Intel.MKL' processorArchitecture='amd64' version='11.1.3.1' type='win32' \"")  
    
  4. 保留引用MKL导入库的#pragma注释,因为它们出现在问题中。此外,无需在应用程序自己的二进制文件夹中为MKL 10.3 DLL创建清单,也无需触摸应用程序EXE。

  5. 通过这些更改,我可以看到应用程序在启动时从其自己的文件夹加载MKL 10.3 DLL,以及在加载插件时从Intel.MKL子文件夹加载MKL 11.1 DLL。从插件调用mkl_get_version_string时,确实返回了预期的版本(11.1)。