我可以使用依赖于 Fortran 文件 interface/header 文件中的数据的预处理器指令来有条件地选择 USE 语句吗?

Can I do conditional selection of USE statements using preprocessor directives which rely on data from a file interface/header file in Fortran?

我想 use 在我的 Fortran 代码中使用不同的库(我也在使用英特尔 Fortran 编译器),这取决于编译时可用的 MKL 版本。 MKL 安装中包含一个文件接口,它为版本号和构建日期定义预处理器宏 - /opt/intel/mkl/include/mkl.fi

我以为流程是这样的:

  1. 从上述文件接口获取MKL的版本号
  2. 使用版本号通过预处理器指令use决定哪个库
  3. 执行use语句以使用正确的库进行编译

如果我在 include 语句之后放置任何 use 语句,但是,编译会在抛出 error #6278: This USE statement is not positioned correctly within the scoping unit.

后中止

是否有任何方法可以使用依赖于文件接口或头文件信息的预处理器指令来实现 use 语句的条件选择?

我看不出这是怎么可能的,因为任何 use 语句都必须在 include 语句之前,该语句提供了决定执行哪个 use 语句所需的数据。我在下面包含了一个示例,该示例演示了我正在尝试做什么,但不起作用·

module MKLVersion

!Test for definition and value up here
#ifdef INTEL_MKL_VERSION  

#if INTEL_MKL_VERSION >=  110200
    use LAPACK95, only : ggevx, geevx, sygvd

#elif INTEL_MKL_VERSION < 110200
    use MKL95_LAPACK, only : ggevx, geevx, sygvd

#endif
#endif

! but dont actually get the definition till we get here

include '/opt/intel/mkl/include/mkl.fi'  

end module MKLVersion

这个问题的简短回答最终是否定的——正如 Steve Lionel 所指出的,包含的文件有 INTERFACE 语句,它不能出现在 USE 语句之前。

但是,我为我的特定用例找到了一个解决方案,它可以使用新旧 MKL 版本编译代码。根据这个 intel article from 2009,有一种调用库的方法可以与旧版本的 MKL 一起使用:

Notes: * f95_precision.mod, mkl95_lapack.mod and mkl95_precision.mod files will be removed in one of the future releases. The current version supports two USE statements - so you can choose or "USE MKL95_LAPACK" or " USE LAPACK95 ". For the future compatibility we recommend using "USE LAPACK95" statement.

所以 USE MKL95_LAPACK 可以用 USE LAPACK95 代替而不破坏一切,这很好。