summaryrefslogtreecommitdiff
path: root/doc/CAPI.rst.txt
diff options
context:
space:
mode:
authorrgommers <ralf.gommers@googlemail.com>2010-11-11 21:29:56 +0800
committerrgommers <ralf.gommers@googlemail.com>2010-11-11 21:29:56 +0800
commit4a7de57448091ef02e50edf9d1e302c20a26ff0c (patch)
tree357de983a7ba4ff56e7800781f4619d70111a89f /doc/CAPI.rst.txt
parenta07ac0f4703cbac0e8747ac0e9e08f41cba9b896 (diff)
downloadnumpy-4a7de57448091ef02e50edf9d1e302c20a26ff0c.tar.gz
DOC: rename ReST files under doc/ from *.txt to *.rst.txt, so they render on github.
Diffstat (limited to 'doc/CAPI.rst.txt')
-rw-r--r--doc/CAPI.rst.txt313
1 files changed, 313 insertions, 0 deletions
diff --git a/doc/CAPI.rst.txt b/doc/CAPI.rst.txt
new file mode 100644
index 000000000..41241ce5a
--- /dev/null
+++ b/doc/CAPI.rst.txt
@@ -0,0 +1,313 @@
+===============
+C-API for NumPy
+===============
+
+:Author: Travis Oliphant
+:Discussions to: `numpy-discussion@scipy.org`__
+:Created: October 2005
+
+__ http://www.scipy.org/Mailing_Lists
+
+The C API of NumPy is (mostly) backward compatible with Numeric.
+
+There are a few non-standard Numeric usages (that were not really part
+of the API) that will need to be changed:
+
+* If you used any of the function pointers in the ``PyArray_Descr``
+ structure you will have to modify your usage of those. First,
+ the pointers are all under the member named ``f``. So ``descr->cast``
+ is now ``descr->f->cast``. In addition, the
+ casting functions have eliminated the strides argument (use
+ ``PyArray_CastTo`` if you need strided casting). All functions have
+ one or two ``PyArrayObject *`` arguments at the end. This allows the
+ flexible arrays and mis-behaved arrays to be handled.
+
+* The ``descr->zero`` and ``descr->one`` constants have been replaced with
+ function calls, ``PyArray_Zero``, and ``PyArray_One`` (be sure to read the
+ code and free the resulting memory if you use these calls).
+
+* If you passed ``array->dimensions`` and ``array->strides`` around
+ to functions, you will need to fix some code. These are now
+ ``npy_intp*`` pointers. On 32-bit systems there won't be a problem.
+ However, on 64-bit systems, you will need to make changes to avoid
+ errors and segfaults.
+
+
+The header files ``arrayobject.h`` and ``ufuncobject.h`` contain many defines
+that you may find useful. The files ``__ufunc_api.h`` and
+``__multiarray_api.h`` contain the available C-API function calls with
+their function signatures.
+
+All of these headers are installed to
+``<YOUR_PYTHON_LOCATION>/site-packages/numpy/core/include``
+
+
+Getting arrays in C-code
+=========================
+
+All new arrays can be created using ``PyArray_NewFromDescr``. A simple interface
+equivalent to ``PyArray_FromDims`` is ``PyArray_SimpleNew(nd, dims, typenum)``
+and to ``PyArray_FromDimsAndData`` is
+``PyArray_SimpleNewFromData(nd, dims, typenum, data)``.
+
+This is a very flexible function.
+
+::
+
+ PyObject * PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr,
+ int nd, npy_intp *dims,
+ npy_intp *strides, char *data,
+ int flags, PyObject *obj);
+
+``subtype`` : ``PyTypeObject *``
+ The subtype that should be created (either pass in
+ ``&PyArray_Type``, or ``obj->ob_type``,
+ where ``obj`` is a an instance of a subtype (or subclass) of
+ ``PyArray_Type``).
+
+``descr`` : ``PyArray_Descr *``
+ The type descriptor for the array. This is a Python object (this
+ function steals a reference to it). The easiest way to get one is
+ using ``PyArray_DescrFromType(<typenum>)``. If you want to use a
+ flexible size array, then you need to use
+ ``PyArray_DescrNewFromType(<flexible typenum>)`` and set its ``elsize``
+ paramter to the desired size. The typenum in both of these cases
+ is one of the ``PyArray_XXXX`` enumerated types.
+
+``nd`` : ``int``
+ The number of dimensions (<``MAX_DIMS``)
+
+``*dims`` : ``npy_intp *``
+ A pointer to the size in each dimension. Information will be
+ copied from here.
+
+``*strides`` : ``npy_intp *``
+ The strides this array should have. For new arrays created by this
+ routine, this should be ``NULL``. If you pass in memory for this array
+ to use, then you can pass in the strides information as well
+ (otherwise it will be created for you and default to C-contiguous
+ or Fortran contiguous). Any strides will be copied into the array
+ structure. Do not pass in bad strides information!!!!
+
+ ``PyArray_CheckStrides(...)`` can help but you must call it if you are
+ unsure. You cannot pass in strides information when data is ``NULL``
+ and this routine is creating its own memory.
+
+``*data`` : ``char *``
+ ``NULL`` for creating brand-new memory. If you want this array to wrap
+ another memory area, then pass the pointer here. You are
+ responsible for deleting the memory in that case, but do not do so
+ until the new array object has been deleted. The best way to
+ handle that is to get the memory from another Python object,
+ ``INCREF`` that Python object after passing it's data pointer to this
+ routine, and set the ``->base`` member of the returned array to the
+ Python object. *You are responsible for* setting ``PyArray_BASE(ret)``
+ to the base object. Failure to do so will create a memory leak.
+
+ If you pass in a data buffer, the ``flags`` argument will be the flags
+ of the new array. If you create a new array, a non-zero flags
+ argument indicates that you want the array to be in Fortran order.
+
+``flags`` : ``int``
+ Either the flags showing how to interpret the data buffer passed
+ in, or if a new array is created, nonzero to indicate a Fortran
+ order array. See below for an explanation of the flags.
+
+``obj`` : ``PyObject *``
+ If subtypes is ``&PyArray_Type``, this argument is
+ ignored. Otherwise, the ``__array_finalize__`` method of the subtype
+ is called (if present) and passed this object. This is usually an
+ array of the type to be created (so the ``__array_finalize__`` method
+ must handle an array argument. But, it can be anything...)
+
+Note: The returned array object will be unitialized unless the type is
+``PyArray_OBJECT`` in which case the memory will be set to ``NULL``.
+
+``PyArray_SimpleNew(nd, dims, typenum)`` is a drop-in replacement for
+``PyArray_FromDims`` (except it takes ``npy_intp*`` dims instead of ``int*`` dims
+which matters on 64-bit systems) and it does not initialize the memory
+to zero.
+
+``PyArray_SimpleNew`` is just a macro for ``PyArray_New`` with default arguments.
+Use ``PyArray_FILLWBYTE(arr, 0)`` to fill with zeros.
+
+The ``PyArray_FromDims`` and family of functions are still available and
+are loose wrappers around this function. These functions still take
+``int *`` arguments. This should be fine on 32-bit systems, but on 64-bit
+systems you may run into trouble if you frequently passed
+``PyArray_FromDims`` the dimensions member of the old ``PyArrayObject`` structure
+because ``sizeof(npy_intp) != sizeof(int)``.
+
+
+Getting an arrayobject from an arbitrary Python object
+======================================================
+
+``PyArray_FromAny(...)``
+
+This function replaces ``PyArray_ContiguousFromObject`` and friends (those
+function calls still remain but they are loose wrappers around the
+``PyArray_FromAny`` call).
+
+::
+
+ static PyObject *
+ PyArray_FromAny(PyObject *op, PyArray_Descr *dtype, int min_depth,
+ int max_depth, int requires, PyObject *context)
+
+
+``op`` : ``PyObject *``
+ The Python object to "convert" to an array object
+
+``dtype`` : ``PyArray_Descr *``
+ The desired data-type descriptor. This can be ``NULL``, if the
+ descriptor should be determined by the object. Unless ``FORCECAST`` is
+ present in ``flags``, this call will generate an error if the data
+ type cannot be safely obtained from the object.
+
+``min_depth`` : ``int``
+ The minimum depth of array needed or 0 if doesn't matter
+
+``max_depth`` : ``int``
+ The maximum depth of array allowed or 0 if doesn't matter
+
+``requires`` : ``int``
+ A flag indicating the "requirements" of the returned array. These
+ are the usual ndarray flags (see `NDArray flags`_ below). In
+ addition, there are three flags used only for the ``FromAny``
+ family of functions:
+
+ - ``ENSURECOPY``: always copy the array. Returned arrays always
+ have ``CONTIGUOUS``, ``ALIGNED``, and ``WRITEABLE`` set.
+ - ``ENSUREARRAY``: ensure the returned array is an ndarray (or a
+ bigndarray if ``op`` is one).
+ - ``FORCECAST``: cause a cast to occur regardless of whether or
+ not it is safe.
+
+``context`` : ``PyObject *``
+ If the Python object ``op`` is not an numpy array, but has an
+ ``__array__`` method, context is passed as the second argument to
+ that method (the first is the typecode). Almost always this
+ parameter is ``NULL``.
+
+
+``PyArray_ContiguousFromAny(op, typenum, min_depth, max_depth)`` is
+equivalent to ``PyArray_ContiguousFromObject(...)`` (which is still
+available), except it will return the subclass if op is already a
+subclass of the ndarray. The ``ContiguousFromObject`` version will
+always return an ndarray (or a bigndarray).
+
+Passing Data Type information to C-code
+=======================================
+
+All datatypes are handled using the ``PyArray_Descr *`` structure.
+This structure can be obtained from a Python object using
+``PyArray_DescrConverter`` and ``PyArray_DescrConverter2``. The former
+returns the default ``PyArray_LONG`` descriptor when the input object
+is None, while the latter returns ``NULL`` when the input object is ``None``.
+
+See the ``arraymethods.c`` and ``multiarraymodule.c`` files for many
+examples of usage.
+
+Getting at the structure of the array.
+--------------------------------------
+
+You should use the ``#defines`` provided to access array structure portions:
+
+- ``PyArray_DATA(obj)`` : returns a ``void *`` to the array data
+- ``PyArray_BYTES(obj)`` : return a ``char *`` to the array data
+- ``PyArray_ITEMSIZE(obj)``
+- ``PyArray_NDIM(obj)``
+- ``PyArray_DIMS(obj)``
+- ``PyArray_DIM(obj, n)``
+- ``PyArray_STRIDES(obj)``
+- ``PyArray_STRIDE(obj,n)``
+- ``PyArray_DESCR(obj)``
+- ``PyArray_BASE(obj)``
+
+see more in ``arrayobject.h``
+
+
+NDArray Flags
+=============
+
+The ``flags`` attribute of the ``PyArrayObject`` structure contains important
+information about the memory used by the array (pointed to by the data member)
+This flags information must be kept accurate or strange results and even
+segfaults may result.
+
+There are 6 (binary) flags that describe the memory area used by the
+data buffer. These constants are defined in ``arrayobject.h`` and
+determine the bit-position of the flag. Python exposes a nice attribute-
+based interface as well as a dictionary-like interface for getting
+(and, if appropriate, setting) these flags.
+
+Memory areas of all kinds can be pointed to by an ndarray, necessitating
+these flags. If you get an arbitrary ``PyArrayObject`` in C-code,
+you need to be aware of the flags that are set.
+If you need to guarantee a certain kind of array
+(like ``NPY_CONTIGUOUS`` and ``NPY_BEHAVED``), then pass these requirements into the
+PyArray_FromAny function.
+
+
+``NPY_CONTIGUOUS``
+ True if the array is (C-style) contiguous in memory.
+``NPY_FORTRAN``
+ True if the array is (Fortran-style) contiguous in memory.
+
+Notice that contiguous 1-d arrays are always both ``NPY_FORTRAN`` contiguous
+and C contiguous. Both of these flags can be checked and are convenience
+flags only as whether or not an array is ``NPY_CONTIGUOUS`` or ``NPY_FORTRAN``
+can be determined by the ``strides``, ``dimensions``, and ``itemsize``
+attributes.
+
+``NPY_OWNDATA``
+ True if the array owns the memory (it will try and free it using
+ ``PyDataMem_FREE()`` on deallocation --- so it better really own it).
+
+These three flags facilitate using a data pointer that is a memory-mapped
+array, or part of some larger record array. But, they may have other uses...
+
+``NPY_ALIGNED``
+ True if the data buffer is aligned for the type and the strides
+ are multiples of the alignment factor as well. This can be
+ checked.
+
+``NPY_WRITEABLE``
+ True only if the data buffer can be "written" to.
+
+``NPY_UPDATEIFCOPY``
+ This is a special flag that is set if this array represents a copy
+ made because a user required certain flags in ``PyArray_FromAny`` and
+ a copy had to be made of some other array (and the user asked for
+ this flag to be set in such a situation). The base attribute then
+ points to the "misbehaved" array (which is set read_only). When
+ the array with this flag set is deallocated, it will copy its
+ contents back to the "misbehaved" array (casting if necessary) and
+ will reset the "misbehaved" array to ``WRITEABLE``. If the
+ "misbehaved" array was not ``WRITEABLE`` to begin with then
+ ``PyArray_FromAny`` would have returned an error because ``UPDATEIFCOPY``
+ would not have been possible.
+
+
+``PyArray_UpdateFlags(obj, flags)`` will update the ``obj->flags`` for
+``flags`` which can be any of ``NPY_CONTIGUOUS``, ``NPY_FORTRAN``, ``NPY_ALIGNED``, or
+``NPY_WRITEABLE``.
+
+Some useful combinations of these flags:
+
+- ``NPY_BEHAVED = NPY_ALIGNED | NPY_WRITEABLE``
+- ``NPY_CARRAY = NPY_DEFAULT = NPY_CONTIGUOUS | NPY_BEHAVED``
+- ``NPY_CARRAY_RO = NPY_CONTIGUOUS | NPY_ALIGNED``
+- ``NPY_FARRAY = NPY_FORTRAN | NPY_BEHAVED``
+- ``NPY_FARRAY_RO = NPY_FORTRAN | NPY_ALIGNED``
+
+The macro ``PyArray_CHECKFLAGS(obj, flags)`` can test any combination of flags.
+There are several default combinations defined as macros already
+(see ``arrayobject.h``)
+
+In particular, there are ``ISBEHAVED``, ``ISBEHAVED_RO``, ``ISCARRAY``
+and ``ISFARRAY`` macros that also check to make sure the array is in
+native byte order (as determined) by the data-type descriptor.
+
+There are more C-API enhancements which you can discover in the code,
+or buy the book (http://www.trelgol.com)