nvfortran
提到可以用-Mmkl
标记调用Intel MKL。但如果只使用此标记,生成的可执行文件则是与单线程动态库libmkl_sequential.so
链接的。如果尝试加入OpenMP标签-mp
,则会报错:
/usr/bin/ld: libmkl_intel_thread.so: undefined reference to `__kmpc_critical_with_hint’
报错信息1
另外Intel官网提供的链接标记则为:
-I"${MKLROOT}/include" -L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl
使用此标记会报错:
/usr/bin/ld: cannot find -liomp5
报错信息2
报错原因是动态库位于/opt/intel/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libiomp5.so
,该路径既不在环境变量中也未在链接标记中写明。
尝试修改链接标记为:
-I"${MKLROOT}/include" -L${MKLROOT}/lib/intel64 -L/opt/intel/lib/intel64_lin/ -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl
此时编译成功,但若执行程序则会Segmentation fault (core dumped)
。使用ldd
查看可执行文件动态库,可见nvfortran
自动链接了Nvidia OpenMP:
libnvomp.so => /opt/nvidia/hpc_sdk/Linux_x86_64/20.9/compilers/lib/libnvomp.so
该库会与Intel OpenMP相冲突。我们用patchelf
敲除该动态库依赖:
patchelf --remove-needed libnvomp.so foo.x
再次执行,问题解决。
另外要注意不要使用64位整型接口-lmkl_intel_ilp64
,否则还是会Segmentation fault (core dumped)
。