User guide
CHAPTER
FIVE
USING NUMPY C-API
5.1 How to extend NumPy
That which is static and repetitive is boring. That which is dynamic
and random is confusing. In between lies art.
— John A. Locke
Science is a differential equation. Religion is a boundary condition.
— Alan Turing
5.1.1 Writing an extension module
While the ndarray object is designed to allow rapid computation in Python, it is also designed to be general-purpose
and satisfy a wide- variety of computational needs. As a result, if absolute speed is essential, there is no replacement
for a well-crafted, compiled loop specific to your application and hardware. This is one of the reasons that numpy
includes f2py so that an easy-to-use mechanisms for linking (simple) C/C++ and (arbitrary) Fortran code directly into
Python are available. You are encouraged to use and improve this mechanism. The purpose of this section is not to
document this tool but to document the more basic steps to writing an extension module that this tool depends on.
When an extension module is written, compiled, and installed to somewhere in the Python path (sys.path), the code
can then be imported into Python as if it were a standard python file. It will contain objects and methods that have
been defined and compiled in C code. The basic steps for doing this in Python are well-documented and you can find
more information in the documentation for Python itself available online at www.python.org .
In addition to the Python C-API, there is a full and rich C-API for NumPy allowing sophisticated manipulations on a
C-level. However, for most applications, only a few API calls will typically be used. If all you need to do is extract a
pointer to memory along with some shape information to pass to another calculation routine, then you will use very
different calls, then if you are trying to create a new array- like type or add a new data type for ndarrays. This chapter
documents the API calls and macros that are most commonly used.
5.1.2 Required subroutine
There is exactly one function that must be defined in your C-code in order for Python to use it as an extension module.
The function must be called init{name} where {name} is the name of the module from Python. This function must
be declared so that it is visible to code outside of the routine. Besides adding the methods and constants you desire,
this subroutine must also contain calls to import_array() and/or import_ufunc() depending on which C-API is needed.
Forgetting to place these commands will show itself as an ugly segmentation fault (crash) as soon as any C-API
subroutine is actually called. It is actually possible to have multiple init{name} functions in a single file in which case
53