diff options
| author | wfspotz@sandia.gov <wfspotz@sandia.gov@localhost> | 2007-04-04 16:11:49 +0000 |
|---|---|---|
| committer | wfspotz@sandia.gov <wfspotz@sandia.gov@localhost> | 2007-04-04 16:11:49 +0000 |
| commit | 498186f2f1c11a2ae6f7f070af963bc4e4571b9f (patch) | |
| tree | 70434e54dfc445cd2ff15bdc261db1d2613b5403 /numpy | |
| parent | d31dac0cf53677d62db2f4bbfae4e2ddfaa29ba7 (diff) | |
| download | numpy-498186f2f1c11a2ae6f7f070af963bc4e4571b9f.tar.gz | |
Updated documentation to include a Summary, as well as a sample of the code generated by swig
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/doc/swig/numpy_swig.html | 125 | ||||
| -rw-r--r-- | numpy/doc/swig/numpy_swig.pdf | bin | 127496 -> 138056 bytes | |||
| -rw-r--r-- | numpy/doc/swig/numpy_swig.txt | 120 |
3 files changed, 232 insertions, 13 deletions
diff --git a/numpy/doc/swig/numpy_swig.html b/numpy/doc/swig/numpy_swig.html index def567e5c..c975ce417 100644 --- a/numpy/doc/swig/numpy_swig.html +++ b/numpy/doc/swig/numpy_swig.html @@ -330,7 +330,8 @@ ul.auto-toc { <li><a class="reference" href="#a-final-note" id="id16" name="id16">A Final Note</a></li> </ul> </li> -<li><a class="reference" href="#acknowledgements" id="id17" name="id17">Acknowledgements</a></li> +<li><a class="reference" href="#summary" id="id17" name="id17">Summary</a></li> +<li><a class="reference" href="#acknowledgements" id="id18" name="id18">Acknowledgements</a></li> </ul> </div> <div class="section"> @@ -357,9 +358,15 @@ language in the way the C routine was intended.</p> contiguous (or technically, <em>strided</em>) blocks of homogeneous data is with the module <a class="reference" href="http://numpy.scipy.org">NumPy</a>, which provides full object-oriented access to arrays of data. Therefore, the most logical -<a class="reference" href="http://www.python.org">python</a> interface for the <tt class="docutils literal"><span class="pre">rms</span></tt> function would be:</p> +<a class="reference" href="http://www.python.org">python</a> interface for the <tt class="docutils literal"><span class="pre">rms</span></tt> function would be (including doc +string):</p> <pre class="literal-block"> def rms(seq): + """ + rms(numpy.ndarray) -> double + rms(list) -> double + rms(tuple) -> double + """ </pre> <p>where <tt class="docutils literal"><span class="pre">seq</span></tt> would be a <a class="reference" href="http://numpy.scipy.org">NumPy</a> array of <tt class="docutils literal"><span class="pre">double</span></tt> values, and its length <tt class="docutils literal"><span class="pre">n</span></tt> would be extracted from <tt class="docutils literal"><span class="pre">seq</span></tt> internally before being @@ -406,6 +413,66 @@ apply the typemap for one-dimensional input arrays of type <tt class="docutils l to the actual prototype used by <tt class="docutils literal"><span class="pre">rms</span></tt>. Using <tt class="docutils literal"><span class="pre">numpy.i</span></tt> effectively, therefore, requires knowing what typemaps are available and what they do.</p> +<p>A <a class="reference" href="http://www.swig.org">SWIG</a> interface file that includes the <a class="reference" href="http://www.swig.org">SWIG</a> directives given +above will produce wrapper code that looks something like:</p> +<pre class="literal-block"> + 1 PyObject *_wrap_rms(PyObject *args) { + 2 PyObject *resultobj = 0; + 3 double *arg1 = (double *) 0 ; + 4 int arg2 ; + 5 double result; + 6 PyArrayObject *array1 = NULL ; + 7 int is_new_object1 = 0 ; + 8 PyObject * obj0 = 0 ; + 9 +10 if (!PyArg_ParseTuple(args,(char *)"O:rms",&obj0)) SWIG_fail; +11 { +12 array1 = obj_to_array_contiguous_allow_conversion( +13 obj0, NPY_DOUBLE, &is_new_object1); +14 npy_intp size[1] = { +15 -1 +16 }; +17 if (!array1 || !require_dimensions(array1, 1) || +18 !require_size(array1, size, 1)) SWIG_fail; +19 arg1 = (double*) array1->data; +20 arg2 = (int) array1->dimensions[0]; +21 } +22 result = (double)rms(arg1,arg2); +23 resultobj = SWIG_From_double((double)(result)); +24 { +25 if (is_new_object1 && array1) Py_DECREF(array1); +26 } +27 return resultobj; +28 fail: +29 { +30 if (is_new_object1 && array1) Py_DECREF(array1); +31 } +32 return NULL; +33 } +</pre> +<p>The typemaps from <tt class="docutils literal"><span class="pre">numpy.i</span></tt> are responsible for the following lines +of code: 12--20, 25 and 30. Line 10 parses the input to the <tt class="docutils literal"><span class="pre">rms</span></tt> +function. From the format string <tt class="docutils literal"><span class="pre">"O:rms"</span></tt>, we can see that the +argument list is expected to be a single python object (specified by +the <tt class="docutils literal"><span class="pre">O</span></tt> before the colon) and whose pointer is stored in <tt class="docutils literal"><span class="pre">obj0</span></tt>. +A number of functions, supplied by <tt class="docutils literal"><span class="pre">numpy.i</span></tt>, are called to make and +check the (possible) conversion from a generic python object to a +<a class="reference" href="http://numpy.scipy.org">NumPy</a> array. These functions are explained in the section <a class="reference" href="#helper-functions">Helper +Functions</a>, but hopefully their names are self-explanatory. At line +12 we use <tt class="docutils literal"><span class="pre">obj0</span></tt> to construct a <a class="reference" href="http://numpy.scipy.org">NumPy</a> array. At line 17, we +check the validity of the result: that it is non-null and that it has +a single dimension of arbitrary length. Once these states are +verified, we extract the data buffer and length in lines 19 and 20 so +that we can call the underlying C function at line 22. Line 25 +performs memory management for the case where we have created a new +array that is no longer needed.</p> +<p>This code has a significant amount of error handling. Note the +<tt class="docutils literal"><span class="pre">SWIG_fail</span></tt> is a macro for <tt class="docutils literal"><span class="pre">goto</span> <span class="pre">fail</span></tt>, refering to the label at +line 28. If the user provides the wrong number of arguments, this +will be caught at line 10. If construction of the <a class="reference" href="http://numpy.scipy.org">NumPy</a> array +fails or produces an array with the wrong number of dimensions, these +errors are caught at line 17. And finally, if an error is detected, +memory is still managed correctly at line 30.</p> <p>Note that if the C function signature was in a different order:</p> <pre class="literal-block"> double rms(int n, double* seq); @@ -416,6 +483,9 @@ typemaps with the data pointer given last:</p> <pre class="literal-block"> %apply (int DIM1, double* IN_ARRAY1) {(int n, double* seq)}; </pre> +<p>This simply has the effect of switching the definitions of <tt class="docutils literal"><span class="pre">arg1</span></tt> +and <tt class="docutils literal"><span class="pre">arg2</span></tt> in lines 3 and 4 of the generated code above, and their +assignments in lines 19 and 20.</p> </div> <div class="section"> <h1><a class="toc-backref" href="#id2" id="using-numpy-i" name="using-numpy-i">Using numpy.i</a></h1> @@ -731,6 +801,9 @@ double dot(int len, double* vec1, double* vec2); <p>The python interface that we want is:</p> <pre class="literal-block"> def dot(vec1, vec2): + """ + dot(PyObject,PyObject) -> double + """ </pre> <p>The problem here is that there is one dimension argument and two array arguments, and our typemaps are set up for dimensions that apply to a @@ -753,11 +826,13 @@ double my_dot(int len1, double* vec1, int len2, double* vec2) { } %} </pre> -<p>If the header file that contains the prototype for <tt class="docutils literal"><span class="pre">dot()</span></tt> also -contains other prototypes that you want to wrap, so that you need to -<tt class="docutils literal"><span class="pre">%include</span></tt> this header file, then you will also need a <tt class="docutils literal"><span class="pre">%ignore</span> +<p>If the header file that contains the prototype for <tt class="docutils literal"><span class="pre">double</span> <span class="pre">dot()</span></tt> +also contains other prototypes that you want to wrap, so that you need +to <tt class="docutils literal"><span class="pre">%include</span></tt> this header file, then you will also need a <tt class="docutils literal"><span class="pre">%ignore</span> <span class="pre">dot;</span></tt> directive, placed after the <tt class="docutils literal"><span class="pre">%rename</span></tt> and before the -<tt class="docutils literal"><span class="pre">%include</span></tt> directives.</p> +<tt class="docutils literal"><span class="pre">%include</span></tt> directives. Or, if the function in question is a class +method, you will want to use <tt class="docutils literal"><span class="pre">%extend</span></tt> rather than <tt class="docutils literal"><span class="pre">%inline</span></tt> in +addition to <tt class="docutils literal"><span class="pre">%ignore</span></tt>.</p> </div> <div class="section"> <h2><a class="toc-backref" href="#id15" id="other-situations" name="other-situations">Other Situations</a></h2> @@ -815,7 +890,41 @@ where you want them, and then clear them after you are done.</p> </div> </div> <div class="section"> -<h1><a class="toc-backref" href="#id17" id="acknowledgements" name="acknowledgements">Acknowledgements</a></h1> +<h1><a class="toc-backref" href="#id17" id="summary" name="summary">Summary</a></h1> +<p>Out of the box, <tt class="docutils literal"><span class="pre">numpy.i</span></tt> provides typemaps that support conversion +between <a class="reference" href="http://numpy.scipy.org">NumPy</a> arrays and C arrays:</p> +<blockquote> +<ul class="simple"> +<li>That can be one of 12 different scalar types: <tt class="docutils literal"><span class="pre">signed</span> <span class="pre">char</span></tt>, +<tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">int</span></tt>, +<tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">long</span> <span class="pre">long</span></tt>, +<tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">float</span></tt> and <tt class="docutils literal"><span class="pre">double</span></tt>.</li> +<li>That support 16 different argument signatures for each data type, +including:<ul> +<li>One-dimensional and two-dimensional arrays.</li> +<li>Input-only, in-place, and argout behavior.</li> +<li>Hard-coded dimensions, data-buffer-then-dimensions +specification, and dimensions-then-data-buffer specification.</li> +</ul> +</li> +</ul> +</blockquote> +<p>The <tt class="docutils literal"><span class="pre">numpy.i</span></tt> interface file also provides additional tools for +wrapper developers, including:</p> +<blockquote> +<ul class="simple"> +<li>A <a class="reference" href="http://www.swig.org">SWIG</a> macro (<tt class="docutils literal"><span class="pre">%numpy_typemaps</span></tt>) with three arguments for +implementing the 16 argument signatures for the user's choice of +(1) C data type, (2) <a class="reference" href="http://numpy.scipy.org">NumPy</a> data type (assuming they match), and +(3) dimension type.</li> +<li>Seven C macros and eleven C functions that can be used to write +specialized typemaps, extensions, or inlined functions that handle +cases not covered by the provided typemaps.</li> +</ul> +</blockquote> +</div> +<div class="section"> +<h1><a class="toc-backref" href="#id18" id="acknowledgements" name="acknowledgements">Acknowledgements</a></h1> <p>Many people have worked to glue <a class="reference" href="http://www.swig.org">SWIG</a> and <a class="reference" href="http://numpy.scipy.org">NumPy</a> together (as well as <a class="reference" href="http://www.swig.org">SWIG</a> and the predecessors of <a class="reference" href="http://numpy.scipy.org">NumPy</a>, Numeric and numarray). The effort to standardize this work into <tt class="docutils literal"><span class="pre">numpy.i</span></tt> began at the 2005 @@ -829,7 +938,7 @@ possible.</p> </div> <div class="footer"> <hr class="footer" /> -Generated on: 2007-04-03 21:50 UTC. +Generated on: 2007-04-04 16:10 UTC. Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/numpy/doc/swig/numpy_swig.pdf b/numpy/doc/swig/numpy_swig.pdf Binary files differindex a24f98965..615130c38 100644 --- a/numpy/doc/swig/numpy_swig.pdf +++ b/numpy/doc/swig/numpy_swig.pdf diff --git a/numpy/doc/swig/numpy_swig.txt b/numpy/doc/swig/numpy_swig.txt index 0339a1baa..ce42bbc9e 100644 --- a/numpy/doc/swig/numpy_swig.txt +++ b/numpy/doc/swig/numpy_swig.txt @@ -36,9 +36,15 @@ For `python <http://www.python.org>`_, the preferred way of handling contiguous (or technically, *strided*) blocks of homogeneous data is with the module `NumPy <http://numpy.scipy.org>`_, which provides full object-oriented access to arrays of data. Therefore, the most logical -`python`_ interface for the ``rms`` function would be:: +`python`_ interface for the ``rms`` function would be (including doc +string):: def rms(seq): + """ + rms(numpy.ndarray) -> double + rms(list) -> double + rms(tuple) -> double + """ where ``seq`` would be a `NumPy`_ array of ``double`` values, and its length ``n`` would be extracted from ``seq`` internally before being @@ -88,6 +94,68 @@ to the actual prototype used by ``rms``. Using ``numpy.i`` effectively, therefore, requires knowing what typemaps are available and what they do. +A `SWIG`_ interface file that includes the `SWIG`_ directives given +above will produce wrapper code that looks something like:: + + 1 PyObject *_wrap_rms(PyObject *args) { + 2 PyObject *resultobj = 0; + 3 double *arg1 = (double *) 0 ; + 4 int arg2 ; + 5 double result; + 6 PyArrayObject *array1 = NULL ; + 7 int is_new_object1 = 0 ; + 8 PyObject * obj0 = 0 ; + 9 + 10 if (!PyArg_ParseTuple(args,(char *)"O:rms",&obj0)) SWIG_fail; + 11 { + 12 array1 = obj_to_array_contiguous_allow_conversion( + 13 obj0, NPY_DOUBLE, &is_new_object1); + 14 npy_intp size[1] = { + 15 -1 + 16 }; + 17 if (!array1 || !require_dimensions(array1, 1) || + 18 !require_size(array1, size, 1)) SWIG_fail; + 19 arg1 = (double*) array1->data; + 20 arg2 = (int) array1->dimensions[0]; + 21 } + 22 result = (double)rms(arg1,arg2); + 23 resultobj = SWIG_From_double((double)(result)); + 24 { + 25 if (is_new_object1 && array1) Py_DECREF(array1); + 26 } + 27 return resultobj; + 28 fail: + 29 { + 30 if (is_new_object1 && array1) Py_DECREF(array1); + 31 } + 32 return NULL; + 33 } + +The typemaps from ``numpy.i`` are responsible for the following lines +of code: 12--20, 25 and 30. Line 10 parses the input to the ``rms`` +function. From the format string ``"O:rms"``, we can see that the +argument list is expected to be a single python object (specified by +the ``O`` before the colon) and whose pointer is stored in ``obj0``. +A number of functions, supplied by ``numpy.i``, are called to make and +check the (possible) conversion from a generic python object to a +`NumPy`_ array. These functions are explained in the section `Helper +Functions`_, but hopefully their names are self-explanatory. At line +12 we use ``obj0`` to construct a `NumPy`_ array. At line 17, we +check the validity of the result: that it is non-null and that it has +a single dimension of arbitrary length. Once these states are +verified, we extract the data buffer and length in lines 19 and 20 so +that we can call the underlying C function at line 22. Line 25 +performs memory management for the case where we have created a new +array that is no longer needed. + +This code has a significant amount of error handling. Note the +``SWIG_fail`` is a macro for ``goto fail``, refering to the label at +line 28. If the user provides the wrong number of arguments, this +will be caught at line 10. If construction of the `NumPy`_ array +fails or produces an array with the wrong number of dimensions, these +errors are caught at line 17. And finally, if an error is detected, +memory is still managed correctly at line 30. + Note that if the C function signature was in a different order:: double rms(int n, double* seq); @@ -98,6 +166,10 @@ typemaps with the data pointer given last:: %apply (int DIM1, double* IN_ARRAY1) {(int n, double* seq)}; +This simply has the effect of switching the definitions of ``arg1`` +and ``arg2`` in lines 3 and 4 of the generated code above, and their +assignments in lines 19 and 20. + Using numpy.i ============= @@ -440,6 +512,9 @@ Consider a reasonable prototype for a dot product function:: The python interface that we want is:: def dot(vec1, vec2): + """ + dot(PyObject,PyObject) -> double + """ The problem here is that there is one dimension argument and two array arguments, and our typemaps are set up for dimensions that apply to a @@ -462,11 +537,13 @@ arguments). The recommended solution is the following:: } %} -If the header file that contains the prototype for ``dot()`` also -contains other prototypes that you want to wrap, so that you need to -``%include`` this header file, then you will also need a ``%ignore +If the header file that contains the prototype for ``double dot()`` +also contains other prototypes that you want to wrap, so that you need +to ``%include`` this header file, then you will also need a ``%ignore dot;`` directive, placed after the ``%rename`` and before the -``%include`` directives. +``%include`` directives. Or, if the function in question is a class +method, you will want to use ``%extend`` rather than ``%inline`` in +addition to ``%ignore``. Other Situations ---------------- @@ -519,6 +596,39 @@ directive after you are done with a specific typemap:: In general, you should target these typemap signatures specifically where you want them, and then clear them after you are done. +Summary +======= + +Out of the box, ``numpy.i`` provides typemaps that support conversion +between `NumPy`_ arrays and C arrays: + + * That can be one of 12 different scalar types: ``signed char``, + ``unsigned char``, ``short``, ``unsigned short``, ``int``, + ``unsigned int``, ``long``, ``unsigned long``, ``long long``, + ``unsigned long long``, ``float`` and ``double``. + + * That support 16 different argument signatures for each data type, + including: + + + One-dimensional and two-dimensional arrays. + + + Input-only, in-place, and argout behavior. + + + Hard-coded dimensions, data-buffer-then-dimensions + specification, and dimensions-then-data-buffer specification. + +The ``numpy.i`` interface file also provides additional tools for +wrapper developers, including: + + * A `SWIG`_ macro (``%numpy_typemaps``) with three arguments for + implementing the 16 argument signatures for the user's choice of + (1) C data type, (2) `NumPy`_ data type (assuming they match), and + (3) dimension type. + + * Seven C macros and eleven C functions that can be used to write + specialized typemaps, extensions, or inlined functions that handle + cases not covered by the provided typemaps. + Acknowledgements ================ |
