Conda环境编译依赖Intel MKL的Fortran程序时找不到mkl_service.mod
编译依赖Intel MKL的Fortran程序时无法找到mkl_service.mod文件的问题
环境
- 操作系统:Ubuntu 最新LTS版本
- Conda环境包:
- gfortran 14.1.0(conda-forge源)
- MKL 2024.2.0(intel_663编译版本)
相关文件
1. test_mkl.f90
program main use mkl_service implicit none print *, "MKL module loaded successfully" end program main
2. Makefile
CONDA_ENV := mpsd CONDA_ACTIVATE := source $$(conda info --base)/etc/profile.d/conda.sh ; conda activate SETUP_SCRIPT := ./setup.sh SHELL := /bin/bash .SHELLFLAGS := -ec FORT = gfortran FLAGS = -fdefault-integer-8 -O3 -m64 -Wl,--no-as-needed -Wunused -std=gnu INCLUDE = -I$(MKLROOT)/include -I$(CONDA_PREFIX)/include -I$(CONDA_PREFIX)/include/intel64/lp64 LIBS = -L$(MKLROOT)/lib/intel64 -lmkl_gf_ilp64 -lmkl_gnu_thread -lmkl_core -lgomp -lpthread -lm -ldl EXE = test_mkl .PHONY: all clean print_versions all: activate_env print_versions $(EXE) activate_env: @echo "Activating Conda environment and running setup script" @$(CONDA_ACTIVATE) $(CONDA_ENV) && source $(SETUP_SCRIPT) print_versions: @echo "Checking Fortran compiler version:" @$(CONDA_ACTIVATE) $(CONDA_ENV) && $(FORT) --version @echo "Checking MKL version:" @$(CONDA_ACTIVATE) $(CONDA_ENV) && conda list | grep mkl $(EXE): test_mkl.f90 @echo "Compiling and linking $(EXE)" $(CONDA_ACTIVATE) $(CONDA_ENV) && source $(SETUP_SCRIPT) && \ $(FORT) $(FLAGS) $(INCLUDE) $< -o $@ $(LIBS) clean: @echo "Cleaning up" @rm -f $(EXE)
3. setup.sh
#!/bin/bash export MKLROOT=$CONDA_PREFIX export LD_LIBRARY_PATH=$MKLROOT/lib:$LD_LIBRARY_PATH export CPATH=$CONDA_PREFIX/include:$CPATH export INCLUDE_PATH=$CONDA_PREFIX/include export FPATH=$CONDA_PREFIX/include:$FPATH export MKL_INCLUDE=$CONDA_PREFIX/include echo "MKLROOT: $MKLROOT" echo "CPATH: $CPATH" echo "INCLUDE_PATH: $INCLUDE_PATH" echo "FPATH: $FPATH" echo "MKL_INCLUDE: $MKL_INCLUDE"
4. environment.yml
name: mpsd channels: - intel - conda-forge - defaults dependencies: - python=3.12 - mkl - mkl-include - mkl-devel - intel-fortran-rt - gfortran - make
错误信息
执行make命令时输出:
f951: Warning: Nonexistent include directory '/include' [-Wmissing-include-dirs] f951: Warning: Nonexistent include directory '/include' [-Wmissing-include-dirs] f951: Warning: Nonexistent include directory '/include/intel64/lp64' [-Wmissing-include-dirs] test_mkl.f90:3:7: 3 | use mkl_service | 1 Fatal Error: Cannot open module file 'mkl_service.mod' for reading at (1): No such file or directory compilation terminated. make: *** [makefile:33: test_mkl] Error 1
已尝试操作
- 重新安装Conda环境中的MKL包
- 确认
mkl_service.mod存在于$CONDA_PREFIX/include/intel64/lp64路径下:
➜ ls $CONDA_PREFIX/include/intel64/lp64 blas95.mod f95_precision.mod lapack95.mod mkl_service.mod
- 验证MKLROOT及相关环境变量已正确设置
问题
- 为什么编译器找不到mkl_service.mod文件?
- gfortran 14.1.0与MKL 2024.2.0是否存在兼容性问题?
- 如何解决该问题并成功编译程序?
解答
1. 编译器找不到模块文件的原因
从错误提示里的'/include'空路径可以看出,Makefile中的MKLROOT和CONDA_PREFIX变量在编译时没有被正确展开,导致-I参数指向了无效的根目录下的/include,而非Conda环境的实际路径。
Makefile中每个命令都是在独立的子shell中执行的,activate_env目标里设置的环境变量不会传递到后续的$(EXE)目标编译命令中——虽然$(EXE)目标里也执行了激活环境和setup脚本,但Makefile在解析INCLUDE变量时,是在Make进程的shell中解析的,此时这些环境变量还未被设置,所以$(MKLROOT)和$(CONDA_PREFIX)是空值,最终生成的-I参数变成了-I/include这种无效路径。
2. 兼容性问题
gfortran 14.1.0与MKL 2024.2.0不存在已知的严重兼容性问题。Intel MKL对gfortran的支持一直比较完善,只要编译参数匹配(比如整数位数、线程库等),就能正常工作。
3. 解决方法
方法一:修改Makefile,让变量在命令执行时展开
将INCLUDE和LIBS变量中的$转义,让shell而非Make进程解析环境变量:
# 修改INCLUDE和LIBS定义,用$$转义$ INCLUDE = -I$$MKLROOT/include -I$$CONDA_PREFIX/include -I$$CONDA_PREFIX/include/intel64/lp64 LIBS = -L$$MKLROOT/lib/intel64 -lmkl_gf_ilp64 -lmkl_gnu_thread -lmkl_core -lgomp -lpthread -lm -ldl
方法二:提前激活Conda环境再执行make
在终端中先手动激活环境并执行setup脚本,再运行make:
source $(conda info --base)/etc/profile.d/conda.sh conda activate mpsd source setup.sh make
方法三:优化Makefile的环境激活逻辑
将环境激活和变量设置整合到编译命令的同一子shell中,确保变量生效:
$(EXE): test_mkl.f90 @echo "Compiling and linking $(EXE)" @bash -c 'source $$(conda info --base)/etc/profile.d/conda.sh && conda activate $(CONDA_ENV) && source $(SETUP_SCRIPT) && \ $(FORT) $(FLAGS) -I$$MKLROOT/include -I$$CONDA_PREFIX/include -I$$CONDA_PREFIX/include/intel64/lp64 $< -o $@ -L$$MKLROOT/lib/intel64 -lmkl_gf_ilp64 -lmkl_gnu_thread -lmkl_core -lgomp -lpthread -lm -ldl'
额外验证点
确认mkl_service.mod的路径被正确加入gfortran的模块搜索路径:编译时可以加上-v参数查看实际的搜索路径,比如:
gfortran -v test_mkl.f90 -I$CONDA_PREFIX/include -I$CONDA_PREFIX/include/intel64/lp64
内容的提问来源于stack exchange,提问作者Hofbr
相关产品推荐
相关产品推荐

