这个问题的灵感来自带有BLAS 的OpenMP
其动机是,我希望Fortran源代码能够灵活地使用与串行/并行BLAS相关的编译器选项。我可以在Makefile
中为mkl
指定-mkl=parallel
或为lopenblas
指定USE_OPENMP=1
。我可以执行make ifort
或make gfortran
或make blah blah
来切换Makefile
中的库。但是,
a( 如果我在Makefile
中使用-mkl=parallel
,我需要在源代码中设置call mkl_set_num_threads(numthreads)
b( 如果我将OpenBLAS
与USE_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时,事情可能会很复杂——似乎我不知道如何切换有关编译器选项的源代码。
另外,来自环境文件.bashrc
的OMP_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中的任意信息传递给源代码。
单独的文件
不使用预处理器,您可以拥有同一文件的多个副本,每个副本都有不同的选项集,并且只编译项目的正确文件。
一种稍微好一点的方法是有一个模块文件和多个子模块,每个子模块包含一组选项,无论选项如何,模块文件都是相同的。这减少了多个文件产生错误的空间,并在需要更改选项时减少了编译时间。