Inline Ccode

Probably the most widely-used method of employing weave is to "in-line" C/C++ code into Python in order to speed up a time-critical section of Python code. In this method of using weave, you define a string containing useful C-code and then pass it to the function weave.inline(code_string, variables), where codejstring is a string of valid C/C++ code and variables is a list of variables that should be passed in from Python. The C/C++ code should refer to the variables with the same names as they are defined with in Python. If weave.line should return anything the the special value return_val should be set to whatever object should be returned. The following example shows how to use weave on basic Python objects code = r""" int i;

py::tuple results(2); for (i = 0; i<a.length(); i + +) { a[i] = i;

results[0] =3.0; results[1] =4.0; return.val = results;

The C++ code shown in the code string uses the name 'a' to refer to the Python list that is passed in. Because the Python List is a mutable type, the elements of the list itself are modified by the C++ code. A set of C++ classes are used to access Python objects using simple syntax.

The main advantage of using C-code, however, is to speed up processing on an array of data. Accessing a NumPy array in C++ code using weave, depends on what kind of type converter is chosen in going from NumPy arrays to C++ code. The default converter creates 5 variables for the C-code for every NumPy array passed in to weave.inline. The following table shows these variables which can all be used in the C++ code. The table assumes that myvar is the name of the array in Python with data-type <dtype> (i.e. float64, float32, int8, etc.)

Variable

Type

Contents

myvar

<dtype>*

Pointer to the first element of the array

Nmyvar

npyJntp*

A pointer to the dimensions array

Smyvar

npyJntp*

A pointer to the strides array

D myvar

int

The number of dimensions

myvar_array

PyArrayObject*

The entire structure for the array

The in-lined code can contain references to any of these variables as well as to the standard macros MYVAR1(i), MYVAR2(i,j), MYVAR3(i,j,k), and MY-VAR4(i,j,k,l). These name-based macros (they are the Python name capitalized followed by the number of dimensions needed) will de-reference the memory for the array at the given location with no error checking (be-sure to use the correct macro and ensure the array is aligned and in correct byte-swap order in order to get useful results). The following code shows how you might use these variables and macros to code a loop in C that computes a simple 2-d weighted averaging filter.

for(i = 1;i<Na [0]-1;i + +) { for(j=1;j <Na [1] -1;j++) {

B2(i,j) = A2(i,j) + (A2(i-1,j) + A2(i+1,j)+A2(i,j-1) + A2(i,j+1))*0.5

+ (A2(i-1,j-1) + A2(i-1,j+1) + A2(i+1,j-1) + A2(i+1,j+1))*0.25

The above code doesn't have any error checking and so could fail with a Python crash if, a had the wrong number of dimensions, or b did not have the same shape as a. However, it could be placed inside a standard Python function with the necessary error checking to produce a robust but fast subroutine.

One final note about weave.inline: if you have additional code you want to include in the final extension module such as supporting function calls, include stat-ments, etc. you can pass this code in as a string using the keyword support_code: weave.inline(code, variables, support_code=support). If you need the extension module to link against an additional library then you can also pass in distutils-style keyword arguments such as library_dirs, libraries, and/or run-time_library_dirs which point to the appropriate libraries and directories.

0 0

Post a comment