I am under windows. The fortran code in mkl_example.f
:
subroutine matmultmkl(M1, M2, M3, M, N, K) bind(c, name='matmultmkl')
!DEC$ ATTRIBUTES DLLEXPORT :: matmultmkl
use iso_c_binding, only: c_float, c_int
integer(c_int),intent(in) :: M, N, K
real(c_float), intent(in) :: M1(M, N), M2(N, K)
real(c_float), intent(out):: M3(M, K)
CALL DGEMM('N','N',M,K,N,1.,M1,M,M2,N,0.,M3,M)
end subroutine
I compile it with command line (in a cmd windows where I ran compilervars.bat
before) using the following batch file :
@Echo off
setlocal ENABLEDELAYEDEXPANSION
SET "IFORT_INITIAL_FLAGS=-c -fpp"
SET "IFORT_OPTIMIZATION_FLAGS=/O3"
ifort %IFORT_OPTIMIZATION_FLAGS% %IFORT_INITIAL_FLAGS% /I"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.4.311\windows\mkl\include" -o mkl_example.obj mkl_example.f
ifort -dll -o mylib.dll mkl_example.obj /link /LIBPATH:"C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2020.4.311\windows\mkl\lib\intel64_win" mkl_intel_lp64.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib
Then I run the follow python script mkl_example.py
:
from ctypes import *
import time
import os
os.add_dll_directory("C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2020.4.311/windows/mkl/lib/intel64_win")
os.add_dll_directory("C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_2020.4.311/windows/compiler/lib/intel64_win")
import numpy as np
mylib = CDLL('./mylib.dll')
mylib.matmultmkl.argtypes = [ POINTER(c_float),
POINTER(c_float),
POINTER(c_float),
POINTER(c_int),
POINTER(c_int),
POINTER(c_int) ]
mylib.matmultmkl.restype = None
M=1000
N=1000
K=1000
a = np.empty((M,N), dtype=c_float)
b = np.empty((N,K), dtype=c_float)
c = np.empty((M,K), dtype=c_float)
a[:] = np.random.rand(M,N)
b[:] = np.random.rand(N,K)
# Fortran mkl call
start = time.time()
mylib.matmultmkl( a.ctypes.data_as(POINTER(c_float)),
b.ctypes.data_as(POINTER(c_float)),
c.ctypes.data_as(POINTER(c_float)),
c_int(M), c_int(N), c_int(K) )
stop = time.time()
print(f"Fortran mkl \t {stop - start}s")
The output is :
Traceback (most recent call last):
File "path\to\mkl_example.py", line 14, in <module>
mylib = CDLL('./mylib.dll')
File "C:\PYTHON\3\3.8.2_64bits\lib\ctypes\__init__.py", line 373, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: path\to\mylib.dll' (or one of its dependencies). Try using
the full path with constructor syntax.
If y remove all the mkl stuff and code a function myself, the mylib.dll
is found at runtime by the python. Hence in the case where I link to the mkl, the message doesn't mean that even if mylib.dll
is at the right place it is not found at runtime for some weird reason, but thet indeed one of it's dependencies is not found.
I don't see what I can do except finding all dependencies at putting them in the same folder next to the fortran dll and the python file. But if this is the only way, maybe I prefer quitting definitely.