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



这个问题的灵感来自带有BLAS 的OpenMP

其动机是,我希望Fortran源代码能够灵活地使用与串行/并行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=线程%20to%20use.-,详细信息,t%20简单地%20调用%20R%27s%20Sys。

c( 目前,如果只有lblas和/或有-mkl=sequential,我必须手动配置dgemm线程(作为一种块分解(,而不考虑OMP_NUM_THREADS。这没关系,但如果源代码有a(和b(的行,我需要使用if来控制源代码的运行

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

另外,来自环境文件.bashrcOMP_NUM_THREADS不是优选的。(很抱歉,我之前应该提到这一点(源代码读取了一个输入文件,该文件指定了正在使用的内核数量,并使用omp_set_num_thread来设置目标内核数量,而不是从环境文件中读取。

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

至少有两种方法。

预处理器变量

正如本问题和本问题等中所解释的,您可以将Makefile中的变量直接传递给适当的预处理器。

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

#ifdef MKL_PARALLEL
call mkl_set_num_threads(numthreads)
#endif

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

单独的文件

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

一种稍微好一点的方法是有一个模块文件和多个子模块,每个子模块包含一组选项,无论选项如何,模块文件都是相同的。这减少了多个文件产生错误的空间,并在需要更改选项时减少了编译时间。

相关内容

  • 没有找到相关文章

最新更新