Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28456 Discussions

Loading a Fortran dll from python in visual studio

MattHouston
New Contributor I
2,675 Views

I created a blank visual studio (2019 Enterprise, last update as of posting) solution, and then a fortran dll project in it with only one source file containing the following code :

 

 

module example
    use iso_c_binding
    implicit none
contains
    subroutine sqr_2d_arr(nd, val) BIND(C, NAME='sqr_2d_arr')
        !DEC$ ATTRIBUTES DLLEXPORT :: sqr_2d_arr
        integer, intent(in) :: nd
        integer, intent(inout) :: val(nd, nd)
        integer :: i, j
        do j = 1, nd
        do i = 1, nd
            val(i, j) = (val(i, j) + val(j, i)) ** 2
        enddo
        enddo
    end subroutine sqr_2d_arr
end module example

 

 

Compilation went fine.

To compare with the C++ case I also added a C++ dll project to my solution with no code, and compiled it.

I intend to call my fortran DLL from Python, inside VIsual Studio (so I could directly break in the Fortran from the Python etc.)

Hence I created a "python application" project in my solution, even added the path to my fortran dll to the "search paths" of my python project, and added one python source code file with the following solution :

 

 

import os
os.add_dll_directory(r"path\to\the\directory\contaning\the\fortran\dll")

import ctypes as ct
import numpy as np

# import the dll

fortlibcpp = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thecpp.dll")
fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")

# setup the data
N = 10
nd = ct.pointer( ct.c_int(N) )          # setup the pointer
pyarr = np.arange(0, N, dtype=int) * 5  # setup the N-long
for i in range(1, N):                   # concatenate columns until it is N x N
    pyarr = np.c_[pyarr, np.arange(0, N, dtype=int) * 5]

# call the function by passing the ctypes pointer using the numpy function:
_ = fortlib.sqr_2d_arr(nd, np.ctypeslib.as_ctypes(pyarr))

print(pyarr)

 

 

And hit F5 to debug.

I did not add the path of the directory containing my C++ DLL and yet the execution of the line

 

 

fortlibcpp = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thecpp.dll")

 

 

went fine.

The line

 

 

fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")

 

 

though, triggered the following exception :

 

 

Could not find module 'path\to\the\directory\contaning\the\fortran\dll\thefortran.dll' (or one of its dependencies). Try using the full path with constructor syntax.
Stack trace:
 >  File "path\to\the\directory\contaning\the\python\source\file\source.py", line 10, in <module> (Current frame)
 >    fortlib = ct.CDLL(r"path\to\the\directory\contaning\the\fortran\dll\thefortran.dll")
Loaded 'ctypes'

 

 

I did not touch the properties of the Fortran DLL project though, maybe there's something to tweak there that I am missing (nothing of this kind to do on the C++ side though), but I don't know.

Also, the Fortran DLL looks perfectly kosher in dependency walker.

What am I doing wrong ?

[Configuration : Visual Studio 2019 Enterprise 16.10.3 ; the issue I related appears : Intel Parallel Studio 2020 Update 4 and Intel One Api 2021.3 Fortran compiler (classic for the One Api)] 

0 Kudos
1 Solution
MattHouston
New Contributor I
2,609 Views

I used Process Monitor with a filter with "process name is 'python.exe'" and "operation is 'CreateFile'" and lauch the python code which showed that libifcoremdd.dll was actively searched with no result ... Hence I added "oneAPI\compiler\2021.3.0\windows\redist\intel64_win\compiler" to the runtime path in the python, which solved my issue ...

View solution in original post

0 Kudos
7 Replies
mecej4
Honored Contributor III
2,661 Views

Do you actually have a path named literally as 

path\to\the\directory\contaning\the\fortran\dll

located in the working directory? Including the misspelled "contaning" instead of "containing" ?

Usually, strings such as "name_of_your_computer", etc., which one finds in software documentation, are supposed to be replaced with user-supplied strings.

 

0 Kudos
MattHouston
New Contributor I
2,658 Views

Nope, I don't ...

I just replaced my original path, for a privacy matter, by these paths for posting here, with a typo in the process.

[Thank you for considering, for the sake of completeness, that I could be completely stupid and copy a "this/is/a/path" mutatis mutandis into code without modyfing it. ;)]

0 Kudos
mecej4
Honored Contributor III
2,641 Views

It was because you left that implausible path in the exception report that I asked if you had used the path without appropriate modification. Such slips can be made by any of us when using copy+paste of snippets of code.

0 Kudos
MattHouston
New Contributor I
2,618 Views

I know, I was just kidding, out of despair because of my problem.

0 Kudos
MattHouston
New Contributor I
2,610 Views

I used Process Monitor with a filter with "process name is 'python.exe'" and "operation is 'CreateFile'" and lauch the python code which showed that libifcoremdd.dll was actively searched with no result ... Hence I added "oneAPI\compiler\2021.3.0\windows\redist\intel64_win\compiler" to the runtime path in the python, which solved my issue ...

0 Kudos
FortranFan
Honored Contributor II
2,583 Views

@MattHouston ,

 

Please see this page at Intel Fortran Reference online.  If you were not already aware, that page might help you gain better insight into the dependencies with Fortran DLLs built with Intel Fortran compiler.

If you are in good control of the whole package management of what you are doing e.g., individual / toy programs or with very, very small teams, etc. with one or a few users if at all only, which is a vast domain of current Fortran use these days, particularly on Windows, you can consider /libs:static option even for your Fortran DLL build which should then allow you to proceed WITHOUT the libifcore*.dll dependency of your DLL during its consumption with other executives whether it be Excel or Python, etc.

 

 

0 Kudos
MattHouston
New Contributor I
2,561 Views

Thank you for the reference, I will look at it but indeed, using a static library could be simpler for me that a dynamic one. (Especially for the cases where I will link to the MKL.)

0 Kudos
Reply