By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,361 Members | 1,700 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,361 IT Pros & Developers. It's quick & easy.

Calling Fortran from Python

P: n/a
Howdy,

I have been trying to call the following Fortran function from Python
(using Windows XP, Compaq Fortran and Python 2.4). I tried F2Py,
Pyfort and calldll with no success.

I think I came very close with calldll. Here is a short summary

Fortran code:

SUBROUTINE SAMPLE(IERR1,IERR2,AIN,AOUT)
C
C SIMPLE SAMPLE OF A DLL
C
!DEC$ATTRIBUTES DLLEXPORT :: SAMPLE
!DEC$ATTRIBUTES ALIAS:'SAMPLE' :: SAMPLE
INTEGER,INTENT(OUT) :: IERR1,IERR2
REAL*8,INTENT(IN) :: AIN(*)
REAL*8,INTENT(OUT) :: AOUT(*)
C
C *** SET MAXIMUM EXPECTED ELEMENTS OF ARRAY AIN AND AOUT
C
PARAMETER (MAXNVIN=101,MAXNVOUT=200)
C
C *** SET ERROR INDICATORS TO ZERO
C
IERR1=0
IERR2=0
C
C *** GET NUMBER OF INPUT VALUES
C
NVIN=AIN(1)
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVIN .GT. MAXNVIN) THEN
IERR1=1
IERR2=1
RETURN
ENDIF
C
C *** SET NUMBER OF OUTPUT VALUES
C
NVOUT=2*NVIN
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVOUT .GT. MAXNVOUT) THEN
IERR1=1
IERR2=2
RETURN
ENDIF
C
C *** INITIALIZE AOUT INDEX
C
JOUT=0
C
C *** COMPUTE TWO OUTPUT VALUES FOR EACH INPUT VALUE
C
DO I=1,NVIN
JOUT=JOUT+1
AOUT(JOUT)=2.*AIN(I+1)
JOUT=JOUT+1
AOUT(JOUT)=3.*AIN(I+1)
END DO
RETURN
END

compiled it to a dll and called this dll from another Fortran program
with success, so this tells me that dll is OK.

This is how I tried to call it from python 2.4

import calldll
handle = calldll.load_library('c:/sample_dll.dll')
addr = calldll.get_proc_address(handle, 'SAMPLE')
#so far so good, I got a handle and address
e1 = 0
e2 = 0
ain = [2, 3, 4]
aout = [ ]
calldll.call_foreign_function(addr, 'hhll', 'l',(e1, e2,ain,aout))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: an integer is required

Has anyone provide a similar example with Pyfort, F2Py or calldll?

Thanks in advance.

Apr 3 '07 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Mangabasi wrote:
Has anyone provide a similar example with Pyfort, F2Py or calldll?
With the latest f2py in numpy:

$ cat sample.pyf
! -*- f90 -*-
! Note: the context of this file is case sensitive.

python module sample ! in
interface ! in :sample
subroutine sample(ierr1,ierr2,ain,aout) ! in :sample:sample.f
integer intent(out) :: ierr1
integer intent(out) :: ierr2
real*8 dimension(*),intent(in) :: ain

!! This is what I had to modify from the generated interface. I
!! changed 'dimension(*)' to 'dimension(len(ain))'.
real*8 dimension(len(ain)),intent(out) :: aout
end subroutine sample
end interface
end python module sample

! This file was auto-generated with f2py (version:2_3582).
! See http://cens.ioc.ee/projects/f2py2e/

]$ f2py -c -m sample sample.pyf sample.f

running build
running config_fc
running build_src
building extension "sample" sources
creating /tmp/tmpZL8qAw
creating /tmp/tmpZL8qAw/src.macosx-10.3-fat-2.5
f2py options: []
f2py: sample.pyf
Reading fortran codes...
Reading file 'sample.pyf' (format:free)
Post-processing...
Block: sample
Block: sample
Post-processing (stage 2)...
Building modules...
Building module "sample"...
Constructing wrapper function "sample"...
ierr1,ierr2,aout = sample(ain)
Wrote C/API module "sample" to file
"/tmp/tmpZL8qAw/src.macosx-10.3-fat-2.5/samplemodule.c"
adding '/tmp/tmpZL8qAw/src.macosx-10.3-fat-2.5/fortranobject.c' to sources.
adding '/tmp/tmpZL8qAw/src.macosx-10.3-fat-2.5' to include_dirs.

.... Etc.

$ ipython
Activating auto-logging. Current session state plus future input saved.
Filename : /Users/rkern/.ipython/ipython.log
Mode : backup
Output logging : False
Raw input log : False
Timestamping : False
State : active

In [1]: import sample

In [2]: sample.sample([1, 2, 3])
Out[2]: (0, 0, array([ 4., 6., 0.]))
--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Apr 3 '07 #2

P: n/a
Robert,

Thanks for your prompt response. I think I got a lot closer but no
cigar yet.

This is the output

C:\fortrandll>f2py -c -m sample sample.pyf sample.for
numpy_info:
FOUND:
define_macros = [('NUMERIC_VERSION', '"\\"24.2\\""')]
include_dirs = ['C:\\Python24\\include']

running build
running config_fc
running build_src
building extension "sample" sources
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv\src
f2py: sample.pyf
Reading fortran codes...
Reading file 'sample.pyf'
Post-processing...
Block: sample
Block: sample
Post-processing (stage 2)...
Building modules...
Building module "sample"...
Constructing wrapper function "sample"...
ierr1,ierr2,aout = sample(ain)
Wrote C/API module "sample" to file "c:\docume~1\fb
\locals~1\temp\tmpcos
vgv\src/samplemodule.c"
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src\fortra nobject.c'
to sources
..
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src' to include_dirs.
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.c -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.h -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
running build_ext
No module named msvccompiler in scipy_distutils, trying from
distutils..
error: The .NET Framework SDK needs to be installed before building
extensions f
or Python.

I think I have a problem with distutils' msvccompiler.py. It may be
the MacroExpander in distutils guessing the visual studio path
incorrectly or something related to the registry keys. Is there a way
to specify the C compiler path to f2py so that it does not rely on the
distutils? Or maybe I am totally off base here, I don't know.

Any thoughts?
Apr 4 '07 #3

P: n/a
There may be a way to finish this without having to deal with
distutils.
F2py created three files so far

samplemodule.c
fortranobject.h
fortranobject.c

Is there a way to create the sample.pyd from these files?

Apr 4 '07 #4

P: n/a
Mangabasi wrote:
Robert,

Thanks for your prompt response. I think I got a lot closer but no
cigar yet.

This is the output

C:\fortrandll>f2py -c -m sample sample.pyf sample.for
numpy_info:
FOUND:
define_macros = [('NUMERIC_VERSION', '"\\"24.2\\""')]
include_dirs = ['C:\\Python24\\include']

running build
running config_fc
running build_src
building extension "sample" sources
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv\src
f2py: sample.pyf
Reading fortran codes...
Reading file 'sample.pyf'
Post-processing...
Block: sample
Block: sample
Post-processing (stage 2)...
Building modules...
Building module "sample"...
Constructing wrapper function "sample"...
ierr1,ierr2,aout = sample(ain)
Wrote C/API module "sample" to file "c:\docume~1\fb
\locals~1\temp\tmpcos
vgv\src/samplemodule.c"
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src\fortra nobject.c'
to sources
.
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src' to include_dirs.
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.c -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.h -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
running build_ext
No module named msvccompiler in scipy_distutils, trying from
distutils..
error: The .NET Framework SDK needs to be installed before building
extensions f
or Python.

I think I have a problem with distutils' msvccompiler.py. It may be
the MacroExpander in distutils guessing the visual studio path
incorrectly or something related to the registry keys. Is there a way
to specify the C compiler path to f2py so that it does not rely on the
distutils? Or maybe I am totally off base here, I don't know.
What C and Fortran compilers are you trying to use? You can look at f2py's help
for flags that you can use to help control where the compilers get picked up,
but you can't avoid distutils.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Apr 4 '07 #5

P: n/a
On Apr 4, 12:22 pm, Robert Kern <robert.k...@gmail.comwrote:
Mangabasi wrote:
Robert,
Thanks for your prompt response. I think I got a lot closer but no
cigar yet.
This is the output
C:\fortrandll>f2py -c -m sample sample.pyf sample.for
numpy_info:
FOUND:
define_macros = [('NUMERIC_VERSION', '"\\"24.2\\""')]
include_dirs = ['C:\\Python24\\include']
running build
running config_fc
running build_src
building extension "sample" sources
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv
creating c:\docume~1\fb\locals~1\temp\tmpcosvgv\src
f2py: sample.pyf
Reading fortran codes...
Reading file 'sample.pyf'
Post-processing...
Block: sample
Block: sample
Post-processing (stage 2)...
Building modules...
Building module "sample"...
Constructing wrapper function "sample"...
ierr1,ierr2,aout = sample(ain)
Wrote C/API module "sample" to file "c:\docume~1\fb
\locals~1\temp\tmpcos
vgv\src/samplemodule.c"
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src\fortra nobject.c'
to sources
.
adding 'c:\docume~1\fb\locals~1\temp\tmpcosvgv\src' to include_dirs.
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.c -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
copying C:\python24\lib\site-packages\f2py2e\src\fortranobject.h -c:
\docume~1\
fb\locals~1\temp\tmpcosvgv\src
running build_ext
No module named msvccompiler in scipy_distutils, trying from
distutils..
error: The .NET Framework SDK needs to be installed before building
extensions f
or Python.
I think I have a problem with distutils' msvccompiler.py. It may be
the MacroExpander in distutils guessing the visual studio path
incorrectly or something related to the registry keys. Is there a way
to specify the C compiler path to f2py so that it does not rely on the
distutils? Or maybe I am totally off base here, I don't know.

What C and Fortran compilers are you trying to use? You can look at f2py's help
for flags that you can use to help control where the compilers get picked up,
but you can't avoid distutils.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco- Hide quoted text -

- Show quoted text -
I am using Visual Studio 6.0 and Compaq Visual Fortran 6.6.

Apr 4 '07 #6

P: n/a
Mangabasi wrote:
I am using Visual Studio 6.0 and Compaq Visual Fortran 6.6.
Ah. You can't use VS6 with that version of Python. I believe you need the .NET
SDK 2003.

You could also use gcc, but I'm not sure if that will work well with Compaq
Visual Fortran; you might have to use gfortran.

http://www.develer.com/oss/GccWinBinaries

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Apr 4 '07 #7

P: n/a
On Apr 4, 4:39 pm, Robert Kern <robert.k...@gmail.comwrote:
Mangabasi wrote:
I am using Visual Studio 6.0 and Compaq Visual Fortran 6.6.

Ah. You can't use VS6 with that version of Python. I believe you need the .NET
SDK 2003.

You could also use gcc, but I'm not sure if that will work well with Compaq
Visual Fortran; you might have to use gfortran.

http://www.develer.com/oss/GccWinBinaries

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
Would Python 2.5 work with Visual Studio 6.6?

Apr 4 '07 #8

P: n/a
Mangabasi wrote:
Would Python 2.5 work with Visual Studio 6.6?
No.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

Apr 4 '07 #9

P: n/a
On Apr 4, 5:48 pm, Robert Kern <robert.k...@gmail.comwrote:
Mangabasi wrote:
Would Python 2.5 work with Visual Studio 6.6?

No.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
I will try the GCC then. It is a shame that I could not get calldll
to work. It was very simple to use. I think I am making a mistake
with the argument types but not sure.

Thanks for your help, it is greatly appreciated.

Apr 4 '07 #10

P: n/a
Mangabasi wrote:
On Apr 4, 5:48 pm, Robert Kern <robert.k...@gmail.comwrote:
>Mangabasi wrote:
>>Would Python 2.5 work with Visual Studio 6.6?
No.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

I will try the GCC then. It is a shame that I could not get calldll
to work. It was very simple to use. I think I am making a mistake
with the argument types but not sure.

Thanks for your help, it is greatly appreciated.
Did you try ctypes?
>>from ctypes import *
sample=cdll.sample.sample_
sample.restype=None
sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double),
POINTER(c_double)]
>>e1 = c_int(0)
e2 = c_int(0)
ain = (c_double*3)(2.0, 3.0, 4.0)
aout = (c_double*4)()
sample(e1, e2, ain, aout)
aout[:]
[6.0, 9.0, 8.0, 12.0]
>>e1.value
0
>>e2.value
0

I compile the SAMPLE example with mingw g77 3.4.5:

g77 -shared -o sample.dll sample.for

I had to take out the "INTENT(OUT)"s because g77 didn't like them. And
"SAMPLE" became "sample_" in the dll. Also note that argument passing to
Fortran subroutines is strictly pass-by-reference. Thus the ain pointer.

Lenard Lindstrom

Apr 5 '07 #11

P: n/a
On Apr 4, 10:10 pm, Lenard Lindstrom <l...@telus.netwrote:
Mangabasi wrote:
On Apr 4, 5:48 pm, Robert Kern <robert.k...@gmail.comwrote:
Mangabasi wrote:
Would Python 2.5 work with Visual Studio 6.6?
No.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
I will try the GCC then. It is a shame that I could not get calldll
to work. It was very simple to use. I think I am making a mistake
with the argument types but not sure.
Thanks for your help, it is greatly appreciated.

Did you try ctypes?
>>from ctypes import *
>>sample=cdll.sample.sample_
>>sample.restype=None
>>sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double),
POINTER(c_double)]
>>e1 = c_int(0)
>>e2 = c_int(0)
>>ain = (c_double*3)(2.0, 3.0, 4.0)
>>aout = (c_double*4)()
>>sample(e1, e2, ain, aout)
>>aout[:]
[6.0, 9.0, 8.0, 12.0]
>>e1.value
0
>>e2.value
0

I compile the SAMPLE example with mingw g77 3.4.5:

g77 -shared -o sample.dll sample.for

I had to take out the "INTENT(OUT)"s because g77 didn't like them. And
"SAMPLE" became "sample_" in the dll. Also note that argument passing to
Fortran subroutines is strictly pass-by-reference. Thus the ain pointer.

Lenard Lindstrom- Hide quoted text -

- Show quoted text -
Lenard,

Now I tried it as you suggested. I did not install G77 yet. I tried
it with the dll I already had. Something interesting happened:
>>from ctypes import *
sample=cdll.sample_dll.SAMPLE
sample.restype=None
sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double), POINTER(c_double)]
sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double), POINTER(c_double)]
e1 = c_int(-10)
e2 = c_int(-10)
ain = (c_double*3)(2.0, 3.0, 4.0)
ain = (c_double*3)(2.0, 3.0, 4.0)
aout = (c_double*4)()
aout = (c_double*4)()
sample(e1, e2, ain, aout)
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
ValueError: Procedure called with not enough arguments (16 bytes
missing) or wrong calling convention
>>aout[:]
[6.0, 9.0, 8.0, 12.0]

I got an error message and the expected answer! Any guesses?

Apr 5 '07 #12

P: n/a
On Apr 4, 10:10 pm, Lenard Lindstrom <l...@telus.netwrote:
Mangabasi wrote:
On Apr 4, 5:48 pm, Robert Kern <robert.k...@gmail.comwrote:
Mangabasi wrote:
Would Python 2.5 work with Visual Studio 6.6?
No.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
I will try the GCC then. It is a shame that I could not get calldll
to work. It was very simple to use. I think I am making a mistake
with the argument types but not sure.
Thanks for your help, it is greatly appreciated.

Did you try ctypes?
>>from ctypes import *
>>sample=cdll.sample.sample_
>>sample.restype=None
>>sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double),
POINTER(c_double)]
>>e1 = c_int(0)
>>e2 = c_int(0)
>>ain = (c_double*3)(2.0, 3.0, 4.0)
>>aout = (c_double*4)()
>>sample(e1, e2, ain, aout)
>>aout[:]
[6.0, 9.0, 8.0, 12.0]
>>e1.value
0
>>e2.value
0

I compile the SAMPLE example with mingw g77 3.4.5:

g77 -shared -o sample.dll sample.for

I had to take out the "INTENT(OUT)"s because g77 didn't like them. And
"SAMPLE" became "sample_" in the dll. Also note that argument passing to
Fortran subroutines is strictly pass-by-reference. Thus the ain pointer.

Lenard Lindstrom- Hide quoted text -

- Show quoted text -
A little bit of googling solved the problem. instead of
>>sample = cdll.sample_dll.SAMPLE
I used

>>sample = windll.sample_dll.SAMPLE
and now it seems to be working without error messages.

Thanks a lot.
Apr 5 '07 #13

P: n/a
Mangabasi wrote:
A little bit of googling solved the problem. instead of
>>>sample = cdll.sample_dll.SAMPLE

I used

>>>sample = windll.sample_dll.SAMPLE

and now it seems to be working without error messages.

Thanks a lot.

I remember someone on the ctypes mailing list mentioning that g77 uses
the C calling convention for exported functions. Other compilers might
default to standard calls. At least with ctypes one can tinker with
calling convention and function arguments to make a call work.

Lenard
Apr 5 '07 #14

This discussion thread is closed

Replies have been disabled for this discussion.