【问题标题】:Can multiple versions of MKL be used in the same process?可以在同一进程中使用多个版本的 MKL 吗?
【发布时间】:2014-07-21 14:01:48
【问题描述】:

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

我们的插件DLL也依赖于MKL,但是我们必须使用更高版本(11.1.3.1),因为我们使用的是VS2012(旧版本的MKL不支持它)。我们将 MKL DLL 与我们自己的 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 加载到同一个进程中?

【问题讨论】:

    标签: dll intel-mkl


    【解决方案1】:

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

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

    2. 在上述Intel.MKL文件夹中添加一个名为Intel.MKL.manifest的文件,内容如下:

      <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 cmets,因为它们出现在问题中。此外,无需在应用程序自己的二进制文件夹中为 MKL 10.3 DLL 创建清单,也无需触摸应用程序 EXE。

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

    【讨论】:

    • 附带说明,sxstrace 在添加清单依赖项后诊断 DLL 加载问题时被证明是一个非常宝贵的工具。
    猜你喜欢
    • 2010-09-23
    • 2010-12-06
    • 2020-08-15
    • 2011-05-22
    • 1970-01-01
    • 2019-06-04
    • 2012-05-24
    • 1970-01-01
    相关资源
    最近更新 更多