Permalink
Browse files

weave: Make sure blitz converters don't issue undef code

  • Loading branch information...
1 parent ee8744a commit 0912c59124cb8ea7a5469397e84b45de96fd8884 Travis Oliphant committed Jun 29, 2006
Showing with 33 additions and 94 deletions.
  1. +22 −90 Lib/weave/doc/tutorial.html
  2. +11 −4 Lib/weave/standard_array_spec.py
View
112 Lib/weave/doc/tutorial.html
@@ -1233,7 +1233,8 @@
<p> The example is available in <code>examples/tuple_return.py</code>.
It also
has the dubious honor of demonstrating how much <code>inline()</code>
-can slow things down. The C version here is about 10 times slower than
+can slow things down. The C version here is about 7-10 times slower
+than
the Python
version. Of course, something so trivial has no reason to be written in
C anyway.
@@ -1285,44 +1286,7 @@
And here is the extension function generated by <code>inline</code>:
<blockquote>
<pre><code>
- static PyObject* compiled_func(PyObject*self, PyObject* args)
- {
- // The Py_None needs an incref before returning
- PyObject *return_val = NULL;
- int exception_occured = 0;
- PyObject *py__locals = NULL;
- PyObject *py__globals = NULL;
- PyObject *py_a;
- py_a = NULL;
-
- if(!PyArg_ParseTuple(args,"OO:compiled_func",&amp;py__locals,&amp;py__globals))
- return NULL;
- try
- {
- PyObject* raw_locals = py_to_raw_dict(py__locals,"_locals");
- PyObject* raw_globals = py_to_raw_dict(py__globals,"_globals");
- int a = py_to_int (get_variable("a",raw_locals,raw_globals),"a");
- /* Here is the inline code */
- printf("%d\n",a);
- /* I would like to fill in changed locals and globals here... */
- }
- catch( Py::Exception&amp; e)
- {
- return_val = Py::Null();
- exception_occured = 1;
- }
- if(!return_val &amp;&amp; !exception_occured)
- {
-
- Py_INCREF(Py_None);
- return_val = Py_None;
- }
- /* clean up code */
-
- /* return */
- return return_val;
- }
- </code></pre>
+static PyObject* compiled_func(PyObject*self, PyObject* args)<br>{<br> py::object return_val;<br> int exception_occured = 0;<br> PyObject *py__locals = NULL;<br> PyObject *py__globals = NULL;<br> PyObject *py_a;<br> py_a = NULL;<br><br> if(!PyArg_ParseTuple(args,"OO:compiled_func",&amp;py__locals,&amp;py__globals))<br> return NULL;<br> try<br> {<br> PyObject* raw_locals = py_to_raw_dict(py__locals,"_locals");<br> PyObject* raw_globals = py_to_raw_dict(py__globals,"_globals");<br> /* argument conversion code */<br> py_a = get_variable("a",raw_locals,raw_globals);<br> int a = convert_to_int(py_a,"a");<br> /* inline code */<br> /* NDARRAY API VERSION 90907 */<br> printf("%d\n",a); /*I would like to fill in changed locals and globals here...*/<br><br> }<br> catch(...)<br> {<br> return_val = py::object();<br> exception_occured = 1;<br> }<br> /* cleanup code */<br> if(!(PyObject*)return_val &amp;&amp; !exception_occured)<br> {<br><br> return_val = Py_None;<br> }<br><br> return return_val.disown();<br>}<br> </code><br></pre>
</blockquote>
Every inline function takes exactly two arguments -- the local and
global
@@ -1333,7 +1297,8 @@
variables
aren't found, or there is an error converting a Python variable to the
appropriate type in C++, an exception is raised. The C++ exception
-is automatically converted to a Python exception by CXX and returned to
+is automatically converted to a Python exception by SCXX and returned
+to
Python.
The <code>py_to_int()</code> function illustrates how the conversions
and
@@ -1345,7 +1310,8 @@
calls
<code>handle_bad_type()</code> which gathers information about what
went wrong
-and then raises a CXX TypeError which returns to Python as a TypeError.
+and then raises a SCXX TypeError which returns to Python as a
+TypeError.
<blockquote>
<pre><code>
int py_to_int(PyObject* py_obj,char* name)
@@ -1473,34 +1439,34 @@
</tr>
<tr>
<td>&nbsp;&nbsp; string</td>
- <td>&nbsp;&nbsp; Py::String</td>
+ <td>&nbsp;&nbsp; py::string</td>
</tr>
<tr>
<td>&nbsp;&nbsp; list</td>
- <td>&nbsp;&nbsp; Py::List</td>
+ <td>&nbsp;&nbsp; py::list</td>
</tr>
<tr>
<td>&nbsp;&nbsp; dict</td>
- <td>&nbsp;&nbsp; Py::Dict</td>
+ <td>&nbsp;&nbsp; py::dict</td>
</tr>
<tr>
<td>&nbsp;&nbsp; tuple</td>
- <td>&nbsp;&nbsp; Py::Tuple</td>
+ <td>&nbsp;&nbsp; py::tuple</td>
</tr>
<tr>
<td>&nbsp;&nbsp; file</td>
<td>&nbsp;&nbsp; FILE*</td>
</tr>
<tr>
<td>&nbsp;&nbsp; callable</td>
- <td>&nbsp;&nbsp; PyObject*</td>
+ <td>&nbsp;&nbsp; py::object</td>
</tr>
<tr>
<td>&nbsp;&nbsp; instance</td>
- <td>&nbsp;&nbsp; PyObject*</td>
+ <td>&nbsp;&nbsp; py::object</td>
</tr>
<tr>
- <td>&nbsp;&nbsp; NumPy.array</td>
+ <td>&nbsp;&nbsp; numpy.ndarray</td>
<td>&nbsp;&nbsp; PyArrayObject*</td>
</tr>
<tr>
@@ -1511,8 +1477,8 @@
</table>
</center>
<p>
-The <code>Py::</code> namespace is defined by the <a
- href="http://cxx.sourceforge.net/">CXX</a> library which has C++ class
+The <code>Py::</code> namespace is defined by the SCXX library which
+has C++ class
equivalents for many Python types. <code>std::</code> is the namespace
of the
standard library in C++.
@@ -1534,42 +1500,7 @@
<code>weave.inline("")</code>. </p>
<blockquote>
<pre><code>
- static PyObject* compiled_func(PyObject*self, PyObject* args)
- {
- PyObject *return_val = NULL;
- int exception_occured = 0;
- PyObject *py__locals = NULL;
- PyObject *py__globals = NULL;
- PyObject *py_a;
- py_a = NULL;
-
- if(!PyArg_ParseTuple(args,"OO:compiled_func",&amp;py__locals,&amp;py__globals))
- return NULL;
- try
- {
- PyObject* raw_locals = py_to_raw_dict(py__locals,"_locals");
- PyObject* raw_globals = py_to_raw_dict(py__globals,"_globals");
- /* argument conversion code */
- /* inline code */
- /*I would like to fill in changed locals and globals here...*/
-
- }
- catch( Py::Exception&amp; e)
- {
- return_val = Py::Null();
- exception_occured = 1;
- }
- /* cleanup code */
- if(!return_val &amp;&amp; !exception_occured)
- {
-
- Py_INCREF(Py_None);
- return_val = Py_None;
- }
-
- return return_val;
- }
- </code></pre>
+</code></pre>
</blockquote>
The <code>/* inline code */</code> section is filled with the code
passed to
@@ -1627,7 +1558,7 @@
<a name="inline_python_argument_conversion"></a>
<h3> String, List, Tuple, and Dictionary Conversion </h3>
Strings, Lists, Tuples and Dictionary conversions are all converted to
-CXX types by default.
+SCXX types by default.
For the following code,
<blockquote>
<pre><code>
@@ -1649,7 +1580,7 @@
<blockquote>
<pre><code> <br> static Py::List py_to_list(PyObject* py_obj,char* name)<br> {<br> if (!py_obj || !PyList_Check(py_obj))<br> handle_bad_type(py_obj,"list", name);<br> return Py::List(py_obj);<br> }<br> <br> static Py::String py_to_string(PyObject* py_obj,char* name)<br> {<br> if (!PyString_Check(py_obj))<br> handle_bad_type(py_obj,"string", name);<br> return Py::String(py_obj);<br> }<br><br> static Py::Dict py_to_dict(PyObject* py_obj,char* name)<br> {<br> if (!py_obj || !PyDict_Check(py_obj))<br> handle_bad_type(py_obj,"dict", name);<br> return Py::Dict(py_obj);<br> }<br> <br> static Py::Tuple py_to_tuple(PyObject* py_obj,char* name)<br> {<br> if (!py_obj || !PyTuple_Check(py_obj))<br> handle_bad_type(py_obj,"tuple", name);<br> return Py::Tuple(py_obj);<br> }<br> </code></pre>
</blockquote>
-CXX handles reference counts on for strings, lists, tuples, and
+SCXX handles reference counts on for strings, lists, tuples, and
dictionaries,
so clean up code isn't necessary.
<a name="#inline_file_argument_conversion"></a>
@@ -2242,7 +2173,8 @@
<h2>The Tools</h2>
<code>weave.blitz</code> relies heavily on several remarkable tools. On
the Python side, the main facilitators are Jermey Hylton's parser
-module and Jim Huginin's NumPy module. On the compiled language side,
+module and Travis Oliphant's NumPy module. On the compiled language
+side,
Todd Veldhuizen's blitz++ array library, written in C++ (shhhh. don't
tell David Beazley), does the heavy lifting. Don't assume that, because
it's C++, it's much slower than C or Fortran. Blitz++ uses a jaw
@@ -2330,7 +2262,7 @@
other than that, they are the same. Further, most of the concept and
capabilities of the two libraries are remarkably similar. It is
satisfying that two completely different implementations solved the
-problem with similar basic architectures. It is also fortitous. The
+problem with similar basic architectures. It is also fortuitous. The
work involved in converting NumPy expressions to blitz expressions was
greatly diminished.
As an example, consider the code for slicing an array in Python with a
View
15 Lib/weave/standard_array_spec.py
@@ -174,12 +174,19 @@ def declaration_code(self,templatize = 0,inline=0):
'int D%(name)s = %(array_name)s->nd;\n' \
'%(num_type)s* %(name)s = (%(num_type)s*) %(array_name)s->data;\n'
code = code % res
+ self.__doundef=1
return code
def cleanup_code(self):
code = common_base_converter.cleanup_code(self)
- cap_name = self.name.upper()
- newcode = "#undef %(cap_name)s1\n#undef %(cap_name)s2\n"\
- "#undef %(cap_name)s3\n#undef %(cap_name)s4\n" % {'cap_name':cap_name}
- code = "%s%s" % (code, newcode)
+ try:
+ if self.__doundef != 1:
+ return code
+ cap_name = self.name.upper()
+ newcode = "#undef %(cap_name)s1\n#undef %(cap_name)s2\n"\
+ "#undef %(cap_name)s3\n#undef %(cap_name)s4\n"\
+ % {'cap_name':cap_name}
+ code = "%s%s" % (code, newcode)
+ except AttributeError:
+ pass
return code

0 comments on commit 0912c59

Please sign in to comment.