MKL 示例代码使用 cmake 编译得很好,但在运行时崩溃

问题描述

我正在尝试从 MKL 网站运行以下示例。

#include <stdio.h>
#include "mkl_vsl.h"
 
int main()
{
   double r[1000]; /* buffer for random numbers */
   double s; /* average */
   VSLStreamStatePtr stream;
   int i,j;
    
   /* Initializing */        
   s = 0.0;
   vslNewStream( &stream,VSL_BRNG_MT19937,777 );
    
   /* Generating */        
   for ( i=0; i<10; i++ ) {
      vdRngGaussian( VSL_RNG_METHOD_GAUSSIAN_ICDF,stream,1000,r,5.0,2.0 );
      for ( j=0; j<1000; j++ ) {
         s += r[j];
      }
   }
   s /= 10000.0;
    
   /* Deleting the stream */        
   vslDeleteStream( &stream );
    
   /* Printing results */        
   printf( "Sample mean of normal distribution = %f\n",s );
    
   return 0;
}

我正在使用以下 CMakeLists.txt 文件来编译代码

cmake_minimum_required(VERSION 3.0.0)
project(rndGen VERSION 0.1.0)

add_executable(rndGen rndGenTest.cpp)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(MKLROOT "C:/Program\ Files\ (x86)/Intel/oneAPI/mkl/latest")
set(MKLLIB "${MKLROOT}/lib/intel64")

target_include_directories(rndGen
PUBLIC ${MKLROOT}/include
)

target_link_libraries(rndGen
PUBLIC ${MKLLIB}/mkl_intel_ilp64.lib
PUBLIC ${MKLLIB}/mkl_intel_thread.lib
PUBLIC ${MKLLIB}/mkl_core.lib
PUBLIC "C:/Program\ Files\ (x86)/Intel/oneAPI/compiler/latest/windows/compiler/lib/intel64_win/libiomp5md.lib"
)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

标题所述,代码崩溃。 VSCode 的调试器输出如下:

-------------------------------------------------------------------
You may only use the C/C++ Extension for Visual Studio Code
with Visual Studio Code,Visual Studio or Visual Studio for Mac
software to help you develop and test your applications.
-------------------------------------------------------------------
Loaded 'C:\mklTest\build\Debug\rndGen.exe'. Symbols loaded.
Loaded 'C:\Windows\System32\ntdll.dll'. 
Loaded 'C:\Windows\System32\kernel32.dll'. 
Loaded 'C:\Windows\System32\KernelBase.dll'. 
Loaded 'C:\Windows\System32\vcruntime140d.dll'. 
Loaded 'C:\Windows\System32\ucrtbased.dll'. 
The program '[16972] rndGen.exe' has exited with code -1073741515 (0xc0000135).

但是,使用以下命令在 cmd 中手动编译时,代码运行良好。

cl /EHsc rndGenTest.cpp -I "C:\Program Files (x86)\Intel\oneAPI\mkl\latest\include" "C:\Program Files (x86)\Intel\oneAPI\mkl\2021.1.1\lib\intel64\mkl_intel_ilp64.lib" "C:\Program Files (x86)\Intel\oneAPI\mkl\2021.1.1\lib\intel64\mkl_intel_thread.lib" "C:\Program Files (x86)\Intel\oneAPI\mkl\2021.1.1\lib\intel64\mkl_core.lib" "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\compiler\lib\intel64_win\libiomp5md.lib"

代码输出

Sample mean of normal distribution = 4.985218

我很确定我在 CMakeLists.txt 文件中遗漏了一些东西。有人可以指出我正确的方向吗?提前致谢。

编辑

感谢您的评论和回答。我尝试了所有这些,但没有一个奏效。我试图深入挖掘以找到问题的确切原因。显然,代码在两种方式下都可以很好地编译。但是,如果直接执行exe文件(在cmd中直接执行),则不起作用。如果我先打开 oneAPI 命令提示符,然后运行 ​​exe,它就可以正常工作。我的猜测是有一些环境变量或运行时库对 exe 不可用。如果是这样,我应该如何更改以便 exe 可以自行运行(无需运行 oneAPI 命令提示符)?

解决方法

在这种情况下,您可以尝试将测试与顺序 mkl 的库(mkl_sequential.lib 而不是 mkl_intel_thread.lib)重新链接,并尝试直接在 cmd 中执行。或者直接把 libiomp5md.dll 放到 exe 文件目录中。

,

我的猜测是您观察到 32 位和 64 位库之间的二进制不兼容。您正在链接 mkl_intel_ilp64.lib,但您没有定义符号 MKL_ILP64。特别地,这个宏定义了 MKL_INT 类型的大小:当定义 MKL_ILP64 时它有 64 位,否则为 32 位。难怪尝试调用 ILP64 库函数会导致运行时崩溃。

将以下行添加到您的 CMakeLists.txt 文件中:

target_compile_definitions(rndGen PUBLIC MKL_ILP64)

https://software.intel.com/sites/products/mkl/mkl_link_line_advisor.htm