Need help setting up project with Intel MKL

Hello Fortran Community!

I’m trying to start a new fluid simulation project and since this stuff is computation heavy, I would like to use the Intel Math Kernal Library. Because I’m working with Intel hardware, I thought this would be the best option to have optimized sparse algebra procedures ready to use. But I’m having trouble to set up the project. :face_with_diagonal_mouth:

I read various documentation, blog post or even threads in this forum, but ultimately nothing really worked. This is due to my inexperience with general project setup and the joy of using windows os. I know cmake/make exist, but I never really had to write my own build script, which makes fpm a godsend for me.
Another stepping stone is to figure out how to incorporate an IDE so proper debugging is possible. Currently I’m using vscode (version 1.85.2) and I have working task and launch configurations to run/debug the application or my unittests (all with the help of fpm :pray:).

Since I would like to add the Intel MKL to a new project if possible, I tried to install the Intel oneApi Toolkit (Base and HPC, both are version 2023.2) and use it with my already installed visual studio (version 17.7.5), but that did not work. Apperently the vs version 17.7.x has problems with the oneApi toolkit (at least this was commented in one of the thread I found here). Also some of the marketplace extensions seem to only work with linux.

Since I don’t want to learn a new IDE (unless I really have to), I stopped trying with the visual studio 2022 setup and instead was wondering, if I can get the library working in a vscode project. Since I already installed the oneAPI toolkits, I assume that the library should exist somewhere on my computer. The toolkits appear to be correctly installed in C:\Program Files (x86)\Intel\oneAPI\ and running setvars.bat seems to work correctly too. (at least the command echo %ONEAPI_ROOT% is returning the correct value). I also found the ifx compiler at C:\Program Files (x86)\Intel\oneAPI\compiler\2023.2.0\windows\bin.

But now I’m stumped and I would like to know, if there is a simple way to add the MKL to my project, such that I can still build it with fpm. If the answere is no, what is the next best option? Do other sparse BLAS libraries exist, that support a fpm.toml? If everything fails I could write my own, but I would rather not. I assume that existing libraries are much more optimized and tested than my own stuff would ever be. :sweat_smile:

Best reagards
Tavi007

-qmkl[=lib]
Tells the compiler to link to certain
libraries in the Intel(R) oneAPI Math Kernel Library (oneMKL). On Windows systems, you must specify this option at compile time.

So whatever is building your project for you needs to include this option. I.e.

fpm build --compiler ifx --profile debug --flag "-qmkl"
1 Like

Hey, thanks for the reply.

After adding “C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin” to my Path (something that apperently is not done automatically by the setvars.bat), fpm can at least find the ifx compiler and also compiles my fortran files, but the command still has trouble to compile the final .exe. This happens regardless of the “-qmkl” flag.

here is the full error message

fpm build --compiler ifx --profile debug --flag “-qmkl”
inverse.f90 done.
libmain.a done.
main.f90 done.
main.exe compiling…
[ 75%] Compiling…:failed command ifx -qmkl /warn:all /check:all /error-limit:1 /Od /Z7 /assume:byterecl /standard-semantics build\ifx_372E70A45AC2182B\main\app_main.f90.o build\ifx_A87C6B3A6E87C408\main\libmain.a -o build\ifx_DA73C41FEF58AD66\app\main.exe>build\ifx_DA73C41FEF58AD66\app\main.exe.log 2>&1
run:Termination status of the command-language interpreter cannot be obtained

I don’t understand the cause of the error and hope you/someone else can help me out. :slight_smile:

Hi @Tavi007

There is a Visual Studio Code (not Visual Studio) help and setup page for the Intel compilers here: Intel® oneAPI Extensions for Visual Studio Code

Not sure if it will help at all - but just in case it does have useful information that might fix your problem :slight_smile:

Simon

1 Like

That documentation helped and I’m now quite a bit furter with getting my app build. Thanks for that.

So the root cause for the previous error seemed to be, that the setvars.bat did not set all necessary environment variables for vscode. I could fix this issue by running the setvars.bat in the vscode terminal. Since I’m using powershell, i used the command (taken directly from the README of one of the oneApi samples provided by the intel extension found on the marketplace)

cmd.exe "/K" '"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" && powershell'

and with

$Env:Path.Split(';') 

i see a lot more variables than before. most noteably are

C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin
C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\lib
C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin\intel64
C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\redist\intel64_win\compiler

which are quite important in my windows setup, i assume.

Now i could finally build the exe with ifx compiler, though only manually. Currently I’m only testing a simple Hello world programm and the command “ifx ” worked fine. However running “fpm build --compiler ifx” still ends in a good old linker issue: build\ifx_E0754568269DC30E\main\libmain.a : fatal error LNK1107
This issue does not happen if I use gfortran or ifort as compiler and I don’t know what the exact problem is, because a libmain.a file was created, but it is somehow broken, even if I delete the build directory and make a clean build.

It feels like the end is almost reachable, so I hope you can help me out for the last bit too.

Did you try to also set the mkl env vars before as well?

> "C:\Program Files (x86)\Intel\oneAPI\mkl\2023.2.0\env\vars.bat" intel64

No, not yet, since I’m currently trying to get the project build with fpm and the ifx compiler. The next step would be to get the mkl linked, so I will keep this script in mind when I get to this part :slight_smile:

I think setvars.bat should setup the global environment, MKL included:

D:\>setvars
:: initializing oneAPI environment...
   Initializing Visual Studio command-line environment...
   Visual Studio version 16.11.31 environment configured.
   "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\"
   Visual Studio command-line environment initialized for: 'x64'
   ...
:  mkl -- latest
   ...
:: oneAPI environment initialized ::

In principle that should do it, but I have had similar issues before, and setting both was the only solution to actually get to link to mkl with “-qmkl” or “-Qmkl”(for windows).

I’m still struggling with the linker error mentioned above (LNK1107). Could somebody please help me?

So I still could not figure out a solution for the linker issue. But since the programm compiles just fine without fpm (instead compiling it directly with ifx/ifort), I tried to get the mkl working in a minimal project. But sadly I run into problems here too.

Here is what a tried. I have this small program

program main
   use mkl_blas, only: dgemm
   implicit none

   ! Matrix dimensions
   integer, parameter :: N = 3

   ! Matrices
   real(8) :: A(N, N), B(N, N), C(N, N)

   ! Initialize matrices A and B with some values
   A = reshape([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], [N, N])
   B = reshape([9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0], [N, N])

   ! Perform matrix multiplication: C = A * B
   call dgemm('N', 'N', N, N, N, 1.0d0, A, N, B, N, 0.0d0, C, N)

   ! Print the result matrix C
   print *, 'Result Matrix C:'
   print *, C
end program main

generated by chatgpt, which hopefully uses the a valid mkl procedure.

Now in the terminal I do the following commands:

"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
echo %MKLROOT%
ifx -o mkl_example app/main.f90 -qmkl 

The setvars.bat should have initialized the mkl correctly

:: initializing oneAPI environment...
   Initializing Visual Studio command-line environment...
   Visual Studio version 17.7.5 environment configured.
   "C:\Program Files\Microsoft Visual Studio\2022\Community\"
   Visual Studio command-line environment initialized for: 'x64'
:  advisor -- latest
:  compiler -- latest
:  dal -- latest
:  debugger -- latest
:  dev-utilities -- latest
:  dnnl -- latest
:  dpcpp-ct -- latest
:  dpl -- latest
:  inspector -- latest
:  ipp -- latest
:  ippcp -- latest
:  itac -- latest
:  mkl -- latest
:  mpi -- latest
:  tbb -- latest
:  vtune -- latest
:: oneAPI environment initialized ::

and MKLROOT is also set to “C:\Program Files (x86)\Intel\oneAPI\mkl\latest”
However the compile command fails, because the mkl procedure can not be found. the compiler also ignored the -qmkl option, because the option is unknown…

Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.

ifx: command line warning #10006: ignoring unknown option '/qmkl'
app/main.f90(2): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [MKL_BLAS]
   use mkl_blas, only: dgemm
-------^
app/main.f90(16): error #6406: Conflicting attributes or multiple declaration of name.   [DGEMM]
   call dgemm('N', 'N', N, N, N, 1.0d0, A, N, B, N, 0.0d0, C, N)
--------^
app/main.f90(2): error #6580: Name in only-list does not exist or is not accessible.   [DGEMM]
   use mkl_blas, only: dgemm
-----------------------^
compilation aborted for app/main.f90 (code 1)

Can someone please explain why the compiler does not know the -qmkl option?

Have you tried to capitalise the q, i.e. -Qmkl ?

Good call. The compiler at least now knows the option, but sadly the build still fails, because the mkl_blas module could not be found.

The BLAS procedures are external. Only if you use the BLAS 95 interface, you need to add use blas95.

If you want to get interface checking, you should add

include "mkl_blas.fi"

in the declaration section of the sub-program where needed.

Thanks for the help.

I also found this issue, that is similar to mine. If I understood it correctly, then not every file provided by Intel oneApi is yet compiled. One can find the fortran source files for the api modules in …/mkl//include. From here go into the intel64 folder and you see subfolder for specific compiler options. From the link:

IFort-32-bit-targets, copy to …\mkl\include\ia32.
If for 64-bit targets, and your default integer is 4-bytes, copy to …\mkl\include\intel64\Lp64.
If for 64-bit targets and default 8-byte integers, use the option /integer-size:8 and copy the module file to …\mkl\include\intel64\Ilp64.

Since there isn’t any mkl_blas.mod file in any of the folder, the compile won’t find the module while compiling.
In my case there was already the blas95.mod file and adjusting my program to use this module instead, I could finally compile it.

program main
   use blas95
   implicit none

   ! Matrix dimensions
   integer, parameter :: N = 3
   integer :: i, j, k

   ! Matrices
   real(8) :: A(N, N), B(N, N), C(N, N), D(N, N)

   ! Initialize matrices A and B with some values
   A = reshape([1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 3.0], [N, N])
   B = reshape([1.0, 1.0, 1.0, 10.0, 10.0, 10.0, 100.0, 100.0, 100.0], [N, N])

   ! Perform matrix multiplication: C = A * B
   C = matmul(A, B)
   !call dgemm('N', 'N', N, N, N, 1.0d0, A, N, B, N, 0.0d0, C, N)
   !call gemm(A, B, C, 'N', 'N', 1.0, 0.0)

   ! just checking if the procedure is correct
   do i = 1, N
      do j = 1, N
         D(i, j) = 0.0
         do k = 1, N
            D(i, j) = D(i, j) + A(i, k)*B(k, j)
         end do
      end do
   end do

   ! Print the result matrix C
   print *, 'Matrix A:'
   print *, A
   print *, 'Matrix B:'
   print *, B
   print *, 'Result Matrix C:'
   print *, C
   print *, 'Result Matrix D:'
   print *, D
end program main

I will now try to get the mkl_blas module running and will come back if I have more questions or found a solution (so future people with the same problem might find this thread useful :wink: ).

A week later and I think I got it finally working.

Here is what I learned. So first of, it is sufficient to compile the needed mkl files with the compile flags of your choice and add them to the correct subfolder of …\mkl\include.

To use the function, you have to declare them as external first, so the compiler knows, that these procedures should be provided when linking to the mkl.

I highly recommend to write your own wrapper module, if you tend to use the procedure more than once. So something like this:

module MKLWrapperModule
   implicit none

   external mkl_dgemv

contains

   function full_mat_vec(A, x) result(y)
      real*8, allocatable :: A(:, :)
      real*8, allocatable :: x(:), y(:)
      call mkl_dgemv('N', size(A, 1), size(A, 2), 1.0d0, A, size(x, 1), x, 1, 0.0d0, y, 1)
   end function full_mat_vec

end module MKLWrapperModule