我可以使用依赖于Fortran中文件接口/头文件数据的预处理器指令对USE语句进行条件选择吗?

我可以使用依赖于Fortran中文件接口/头文件数据的预处理器指令对USE语句进行条件选择吗?,fortran,fortran90,intel-fortran,Fortran,Fortran90,Intel Fortran,我想在fortran代码中使用不同的库(我也在使用英特尔fortran编译器),具体取决于编译时可用的MKL版本。MKL安装中包含一个文件接口,它为版本号和生成日期定义预处理器宏-/opt/intel/MKL/include/MKL.fi 我认为流程如下: 从上面提到的文件接口获取MKL的版本号 使用版本号通过预处理器指令决定使用哪个库 执行使用语句使用正确的库进行编译 但是,如果我将任何use语句放在include语句之后,编译会在抛出error之后中止:此use语句在作用单元中的位置不正确。

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

我认为流程如下:

  • 从上面提到的文件接口获取MKL的版本号
  • 使用版本号通过预处理器指令决定使用哪个库
  • 执行
    使用
    语句使用正确的库进行编译
  • 但是,如果我将任何
    use
    语句放在
    include
    语句之后,编译会在抛出
    error之后中止:此use语句在作用单元中的位置不正确。

    是否有任何方法可以使用依赖于文件接口或头文件信息的预处理器指令来实现对
    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
    
    模块MKLVersion
    !在这里测试定义和值
    #ifdef英特尔MKL_版本
    #如果英特尔MKL\U版本>=110200
    仅使用LAPACK95:ggevx、geevx、sygvd
    #elif英特尔MKL_版本<110200
    使用MKL95_-LAPACK,仅限:ggevx、geevx、sygvd
    #恩迪夫
    #恩迪夫
    ! 但是在我们到达这里之前,不要真正得到定义
    包括“/opt/intel/mkl/include/mkl.fi”
    端模块MKLVersion
    
    这个问题的简短答案最终是否定的——正如Steve Lionel指出的,包含的文件有接口语句,不能放在USE语句之前

    然而,我为我的特定用例找到了一个解决方案,它支持使用新旧MKL版本编译代码。根据这一点,有一种方法可以调用将与旧版本的MKL一起使用的库:

    注: *f95_precision.mod、mkl95_lapack.mod和mkl95_precision.mod文件将在未来版本中删除。当前版本支持两个USE语句-因此您可以选择“USE MKL95_LAPACK”或“USE LAPACK95”。为了将来的兼容性,我们建议使用“USE LAPACK95”语句


    因此
    USE MKL95_LAPACK
    可以替换为
    USE LAPACK95
    ,而不会破坏一切,这很好

    提前移动include可能不会有任何帮助(如果可以的话):文本include发生在预处理后的编译阶段。也许有一种预处理器
    #include
    方法可以工作?或者将带有值的定义传递给预处理器。注意,定位问题不是包含本身,而是从包含中拉入的接口等语句。这实际上也是我,Steve!我昨天离开的时候在这里发了帖子,因为我想你会赶上我们的时间,可能会有一段时间不回答。