Mailing List Archive

sharing variables in fortran
I am wondering if it is possible to coerce python to use
memory addresses corresponding to a fortran common block (by way of a c
extension)
for storage of certain variables.

I am looking (still) at converting a large fortran program to use
python/tkinter/pyOpenGL with an
intermediate C-interface to the more numerically intensive fortran
OpenGL rendering routines.
Currently it looks like there are around 500 variables controlling
various aspects of the rendering
which need to be set and adjusted in python/tkinter routines, and whose
values are needed by the
fortran code. If it is possible to avoid using 500 Py_PassTuple() etc.
C routines every time the user
moves the mouse, it would be very useful to know.

I am sure it is possible to get the tkinter widgets to read current
state before being invoked and then
call another C function to copy it back, but if there was a way to share
the fortran/C variable address space
so that the tkinter widgets changed them directly ....

Thanks in advance for any info.
Doug
(still a python beginner)

P.S. if you are interested to see what a beast the gui really is take a
look at part of it here:
http://www.crystal.uwa.edu.au/~ddb/panels.py
(it doesn't actually do anything constructive yet)
sharing variables in fortran [ In reply to ]
> I am wondering if it is possible to coerce python to use
> memory addresses corresponding to a fortran common block (by way of a c
> extension)
> for storage of certain variables.

Yes, but you won't find a ton of information about it. Be prepared to
experiment a little.

I would suggest using the Numeric module with it's C-API.

There is an exported function you can call from C called
PyArray_FromDimsAndData that creates a NumPy array from some dimension
information and a pointer to already allocated memory. There is some
improving documentation on the C-API to Numeric in the documentation
recently released for NumPy. See the scientific computing topic section
of www.python.org

I'm not sure how to access a Fortran common block from C at the moment.

Have you heard about the PyOpenGL interface?

Good luck.

Travis
sharing variables in fortran [ In reply to ]
Douglas du Boulay wrote:
>
> I am wondering if it is possible to coerce python to use
> memory addresses corresponding to a fortran common block (by way of a c
> extension)
> for storage of certain variables.

I can't speak to the python part of things, but there is a dirty
way to allow a C program to access fortran common blocks. I imagine
that this would allow you to solve your python problem fairly easily
by having your C wrapper muck around with the common blocks.

Before I tell you how to do it, I want to emphasize strongly that
this may not work with every compiler/OS combination. I figured
this out a while ago by playing around with the output of nm,
but I've never seen it written down anywhere. I've made this work
under AIX, Linux, HPUX, and IRIX, but that's no guarantee
that it'll go with everything.

Now that I have fired a healthy salvo of disclaimers, here's
the unpleasant method of solving the problem.

Here's a fragment of fortran code which uses a common block:
subroutine test_mod
real var1
integer var2
common /testblock/ var1,var2

print *, var1, var2
end
You can get at the contents of testblock by defining a global structure
in your C program which has exactly the same contents as testblock.
So, for example, this C program:
#include <stdio.h>

typedef struct {
float var1;
int var2;
} common1;

common1 testblock;

void main()
{
testblock.var1 = 1.034;
testblock.var2 = 2;

test_mod();
}

sets the members of the common block, then calls the fortran subroutine
which prints out its members.

Of course this repellant bit of magic doesn't work "as is" on every
system. Some f77 compilers like to stick one or more underscores after
subroutine and common block names. On those, you will have to change
the names of the common blocks in order to match. For example, g77
(at least my version) produces a .o file which has these symbols:

00000000 T test_mod__
00000008 C testblock_

(that's output from nm), so I have to change the call to test_mod
in the C part from test_mod() -> test_mod__().
Correspondingly, the name of testblock needs to be changed to
testblock_. It just can't be too easy.

Anyway, I hope that this type of trickery allows you to solve
your problems.

<hating-having-to-play-these-tricks>ly yours, [1]
-greg
[1] okay, okay, I haven't been following the group long enough
to have earned the right to do that, but I need to do *something*
to relieve the tension after thinking about these foul things
again.

---------------------
Dr. Greg Landrum (landrumSPAM@foreman.ac.rwth-aachen.de)
Institute of Inorganic Chemistry
Aachen University of Technology
Prof.-Pirlet-Str. 1, D-52074 Aachen, Germany
sharing variables in fortran [ In reply to ]
Travis Oliphant wrote:

> > I am wondering if it is possible to coerce python to use
> > memory addresses corresponding to a fortran common block (by way of a c
> > extension)
> > for storage of certain variables.

> There is an exported function you can call from C called
> PyArray_FromDimsAndData that creates a NumPy array from some dimension
> information and a pointer to already allocated memory. There is some
> improving documentation on the C-API to Numeric in the documentation
> recently released for NumPy. See the scientific computing topic section
> of www.python.org
>
> I'm not sure how to access a Fortran common block from C at the moment.
>

Thanks Travis, that at least gets me started

If I can borrow from Greg Landrums reply:

if testblock is my fortran common block,
the equivalent in C is

typedef struct {
float var1;
int var2;
} common1;
common1 testblock; /* a global block that exists for the entire
period of module use */

so if I have a testmodule.c file with:

typedef struct {
PyObject_HEAD
/* something is missing here */
} TestObject;

What do I have to put in the TestObject struct to be able to read and write
the var1 and var2 variables
directly in a python script with something along the lines of
self.testblock.var1=2.0 ?

Thanks again.
Doug