The question is inspired by OpenMP with BLAS
The motivation is, I want the Fortran source code to be flexible to the complier options related to serial/parallel BLAS. I may specify -mkl=parallel
for mkl
or USE_OPENMP=1
for lopenblas
in the Makefile
.
I may do make ifort
or make gfortran
or make blah blah
to switch the libaries in the Makefile
.
But,
a) If I use -mkl=parallel
in the Makefile
, I need to set call mkl_set_num_threads(numthreads)
in the source code,
b) If I use OpenBLAS
with USE_OPENMP=1
, I may need openblas_set_num_threads(num_threads)
in the source code
https://rdrr.io/github/wrathematics/openblasctl/man/openblas_set_num_threads.html#:~:text=threads%20to%20use.-,Details,t%20simply%20call%20R%27s%20Sys.
c) for the time being if there is only lblas
and/or with -mkl=sequential
, I have to manually configurate dgemm
threads (as kind of block decomposition), regardless OMP_NUM_THREADS
. That's ok, but I need to use if
to control the source code goes in that way, if the source code has lines for a) and b)
The manually programming dgemm
threads in c) is somehow universal. When I would like to exploit parallel blas from libraries, things can be complicated it seems such that I don't know how to switch in source code regarding the compiler options.
Addition, OMP_NUM_THREADS
from enviroment file, .bashrc
, is not preferable. (Sorry I should have mentioned this point earlier) The source code read an input file which specify the number of cores being used, and use omp_set_num_thread
to set the targeted number of cores, than from the enviroment file.
Addition2, from my test on MKL
, OMP_NUM_THREADS
cannot surpress call mkl_set_num_threads
. Namely, I have to specify call mkl_set_num_threads
to work with -mkl=parallel
flag.
There are at least two approaches to this.
As explained in e.g. this question and this question, among others, you can pass variables from a Makefile directly to an appropriate preprocessor.
For example, in the branches of the Makefile where you set -mkl=parallel
you could also set -DMKL_PARALLEL
. Then, in your source code you could have a block which looks something like
#ifdef MKL_PARALLEL
call mkl_set_num_threads(numthreads)
#endif
Provided you compile your code with an appropriate preprocessor, this allows you to pass arbitrary information from your Makefile to your source code.
Instead of using a preprocessor, you can have multiple copies of the same file, each with a different set of options, and only compile the correct file for the project.
A slightly nicer way of doing this is to have one module file, which is always the same regardless of options, and multiple submodules, each of which contains one set of options. This reduces the room for error arising from multiple files, and reduces compilation time if you need to change the options.