是否可以让 Fortran 源代码检测编译器标志?

Is that possible to let Fortran source code detect compiler flags?

问题的灵感来自

动机是,我希望 Fortran 源代码能够灵活地适应与 serial/parallel BLAS 相关的编译器选项。我可以在 Makefile 中为 mkl 指定 -mkl=parallel 或为 lopenblas 指定 USE_OPENMP=1。 我可能会 make ifortmake gfortranmake blah blah 来切换 Makefile 中的库。 但是,

a) 如果我在Makefile中使用-mkl=parallel,我需要在源代码中设置call mkl_set_num_threads(numthreads)

b) 如果我使用 OpenBLASUSE_OPENMP=1,我可能需要在源代码中使用 openblas_set_num_threads(num_threads) https://rdrr.io/github/wrathematics/openblasctl/man/openblas_set_num_threads.html#:~:text=threads%20to%20use.-,Details,t%20simply%20call%20R%27s%20Sys.

c) 目前如果只有 lblas and/or 和 -mkl=sequential,我必须手动配置 dgemm 线程(作为一种块分解) ,无论 OMP_NUM_THREADS。没关系,但我需要使用 if 来控制源代码以这种方式运行,如果源代码包含 a) 和 b)

c) 中的手动编程 dgemm 线程在某种程度上是通用的。当我想从库中利用并行 blas 时,事情似乎很复杂,以至于我不知道如何切换有关编译器选项的源代码。

来自环境文件 .bashrc 的添加 OMP_NUM_THREADS 不是可取的。 (抱歉,我应该早点提到这一点)源代码读取了一个指定正在使用的内核数量的输入文件,并使用 omp_set_num_thread 设置目标内核数量,而不是从环境文件中读取。

Addition2,从我在MKL上的测试来看,OMP_NUM_THREADS无法压制call mkl_set_num_threads。也就是说,我必须指定 call mkl_set_num_threads 才能使用 -mkl=parallel 标志。

至少有两种方法。

预处理器变量

如中所述 and ,除其他外,您可以将变量从 Makefile 直接传递到适当的预处理器。

例如,在您设置 -mkl=parallel 的 Makefile 分支中,您也可以设置 -DMKL_PARALLEL。然后,在您的源代码中,您可以有一个看起来像

的块
#ifdef MKL_PARALLEL
  call mkl_set_num_threads(numthreads)
#endif

只要您使用适当的预处理器编译代码,就可以将任意信息从 Makefile 传递到源代码。

单独的文件

您可以拥有同一个文件的多个副本,每个副本都有一组不同的选项,并且只为项目编译正确的文件,而不是使用预处理器。

一个稍微好一点的方法是有一个模块文件,无论选项如何,它总是相同的,还有多个 submodules,每个文件包含一组选项。这减少了由多个文件引起的错误空间,并在您需要更改选项时减少编译时间。