Friday, 28 June 2013

I get requests about using NAG from python from time to
time, and NAG strives to make its algorithms as accessible as possible from a
wide variety of languages and platforms. Python is no exception.

While we don’t yet provide a fully documented python API
replete with examples and so on, there is a quick but dirty way to get
NAG C Library python bindings covering every library algorithm, struct, and
enum.

My starting point was the old PyNAG, which is
excellent as far as it goes. It is also for the older Mark 8 library -- which
none of you out there in userland should be using.

PyNAG also looks a bit labor-intensive to produce for the
whole library, which would entirely disrupt my Maynard G. Krebs Cycle. There
has to be better way, I thought.

And there is! At least on Linux. For this exercise I used
our NAG C Library Mark 23 implementation for Linux and gcc, LP64 model,
hereafter abbreviated as cll6a23dgl.

Here is the method that I used:

Step 1 --
Get the Tools

For this exercise we'll need two tools. The first is gccxml,
the extension to gcc that produces an xml description of the gcc compiler's
internal representation of a compiled code. The second tool is the python
extension ctypeslib. Both are available from the Ubuntu repositories
(for example.)

Then with very minor modifcations the PyNAG examples will
run. For many the only change needed is to change the import, from “PyNAG” to
“nag4py”.

Another necessary change is that Numpy arrays must be passed
slightly differently than with PyNAG, e.g.

g01alc(n,
x.ctypes.data_as(POINTER(c_double)), …

instead of

g01alc(n,
x.ctypes.data_as(c_void_p), …

Nag C Library enum types are translated nicely and may be
used like one normally would, e.g.

f07aac(Nag_RowMajor,n,nrhs,…

and callback function typing is taken care of for us, e.g.

def
py_obj_func(n,xc,objf,comm):

objf[0] = exp(xc[0]) * (xc[0]
* 4.0 * (xc[0]+xc[1])
+ …

return

c_obj_func
= NAG_E04CCC_FUN(py_obj_func)

While the module nag4py.py generated in this way is
immediately usable on Linux, it is specific to the local installation. To get
it working on anything else a small amount of work remains to be done. First,
we have to remove the extraneous debris from gcc that finds its way into
nag4py.py. Second, we must omit some symbols exposed by the NAG C Library on
Linux that are not exposed by all NAG C Library Mark 23 implementations.

Once that’s done, we get a module suitable for Linux,
Windows, and OS X, available here. Updated PyNAG
examples are here.

On Windows, I tested with the 64-bit Anaconda python
distribution, which comes with all of the python bits needed to run the
examples, including the graphical Rosenbrock example. An applicable NAG C
Library implementation is CLW6I23DA.
I found I had to add the folder containing the NAG DLLs to the system PATH
environment variable.

About NAG

The Numerical Algorithms Group (NAG) is dedicated to applying its unique expertise in numerical engineering to delivering high-quality computational software and high performance computing services. For 40 years NAG experts have worked closely with world-leading researchers in academia and industry to create powerful, reliable and flexible software which today is relied on by tens of thousands of individual users, as well as numerous independent software vendors. NAG serves its customers from offices in Oxford, Manchester, Chicago, Tokyo and Taipei, through local staff in France and Germany, as well as via a global network of distributors.