Search code examples
fortranfortran90intel-fortran

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


I would like to use different libraries in my fortran code (I am using intel fortran compiler as well) depending on which version of MKL is available at compile time. There is a file interface included with an install of MKL which defines preprocessor macros for version numbers and build date - /opt/intel/mkl/include/mkl.fi

I thought the flow would be as follows:

  1. Get version number of MKL from file interface mentioned above
  2. Use the version number to decide which library to use via preprocessor directives
  3. execute use statement to compile with correct library

If I place any use statements after an include statement, however, the compilation aborts after throwing error #6278: This USE statement is not positioned correctly within the scoping unit.

Is there any way to achieve conditional selection of use statements using preprocessor directives which rely on information from a file interface or header file?

I cannot see how it is possible, because any use statements have to be before the include statement which provides the data required to decide which use statement to execute. I have included below a sample which demonstrates what I'm trying to do, but will not work·

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

Solution

  • The short answer to this question is, ultimately, no - as Steve Lionel pointed out, the included file had INTERFACE statements, which cannot come before a USE statement.

    However, I found a solution for my particular use case, which enables compilation of code with both old and new MKL versions. According to this intel article from 2009, there is a way to call libraries which will work with older version of 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.

    So USE MKL95_LAPACK can be replaced with USE LAPACK95 without breaking everything, which is good.