[Numpy-discussion] Building f2py extensions on AMD64 with Python 2.7 Numpy 1.5, MSVC 2008 Pro and gfortran
Sturla Molden
sturla at molden.no
Mon Aug 16 21:59:30 EDT 2010
> I don't really see how to make that works (that is running gfortran
> code in a spawned process), but if you know how to, please go ahead.
I didn't debug this code examples so there might be typos, but this is
just to illustrate the general idea:
Say we have a Fortran function with this interface:
subroutine foobar(m, n, x, y)
integer :: m, n
real*8 :: x(n), y(n)
end subroutine
We could then proceed like this:
We can create a chunk of uniquely named shared memory like this:
tag = uuid.uuid4().hex
size = 1 << 20 # 1 MiB from the paging file
shm = mmap.mmap(0, size, tagname="Local\\%s"%(tag,))
shm = np.frombuffer(shm, dtype=np.uint8)
The we use views of shm to set up x and y, e.g.
m = 100
n = 100
nb = 8 * n * m
x = shm[:nb].view(dtype=float).reshape((n,m))
y = shm[nb:2*nb].view(dtype=float).reshape((n,m))
Then we can call a fortran program using subprocess module:
returnval = subprocess.call(['foobar.exe','%d'%n, '%d'%m, tag])
Then we need some boilerplate C to grab the shared memory and call Fortran:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
/* fortran: pass pointers, append underscore */
extern void foobar_(int *m, int *n, double *x, double *y)
static int openshm(const char *tag, size_t size,
HANDLE *phandle, void **pbuf)
{
*phandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, tag);
if (!h) return -1;
*pbuf = MapViewOfFile(*phandle, FILE_MAP_ALL_ACCESS, 0, 0, size);
if (*pbuf == NULL) {
CloseHandle(p);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
char tag[256];
HANDLE shmem;
int m, n;
double *x, *y;
m = atoi(argv[1]);
n = atoi(argv[2]);
ZeroMemory(tag, sizeof(tag));
sprintf(tag, "Local\\%s", argv[3]);
/* get arrays from shared memory */
if (openshm(tag, 2*m*n*sizeof(double), &shmem, &(void*)x)<0)
return -1;
y = x + m*n;
/* call fortran */
foobar_(&m, &n, x, y);
/* done */
CloseHandle(h);
return 0;
}
Blah... ugly.
On Linux we could use os.fork instead of subprocess, and only y would need
to be placed in (anonymous) shared memory (due to copy-on-write). But on
the other hand, we don't have run-time issues with gfortran on Linux
either. Just to illustrate why Windows sucks sometimes.
:-)
Sturla
More information about the NumPy-Discussion
mailing list