[Numpy-svn] r5631 - in trunk/numpy/doc/swig: . test
numpy-svn at scipy.org
numpy-svn at scipy.org
Tue Aug 12 14:46:32 EDT 2008
Author: stefan
Date: 2008-08-12 13:46:31 -0500 (Tue, 12 Aug 2008)
New Revision: 5631
Added:
trunk/numpy/doc/swig/test/Fortran.cxx
trunk/numpy/doc/swig/test/Fortran.h
trunk/numpy/doc/swig/test/Fortran.i
trunk/numpy/doc/swig/test/testFortran.py
Modified:
trunk/numpy/doc/swig/numpy.i
trunk/numpy/doc/swig/test/Makefile
trunk/numpy/doc/swig/test/setup.py
trunk/numpy/doc/swig/test/testArray.py
trunk/numpy/doc/swig/test/testMatrix.py
trunk/numpy/doc/swig/test/testTensor.py
trunk/numpy/doc/swig/test/testVector.py
Log:
Correctly handle Fortran-contiguous arrays in SWIG wrappers.
Modified: trunk/numpy/doc/swig/numpy.i
===================================================================
--- trunk/numpy/doc/swig/numpy.i 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/numpy.i 2008-08-12 18:46:31 UTC (rev 5631)
@@ -196,7 +196,7 @@
}
else
{
- py_obj = PyArray_FromObject(input, typecode, 0, 0);
+ py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_DEFAULT);
/* If NULL, PyArray_FromObject will have set python error value.*/
ary = (PyArrayObject*) py_obj;
*is_new_object = 1;
@@ -229,6 +229,30 @@
return result;
}
+ /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+ * If so, return the input pointer, but do not flag it as not a new
+ * object. If it is not Fortran-contiguous, create a new
+ * PyArrayObject using the original data, flag it as a new object
+ * and return the pointer.
+ */
+ PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object,
+ int min_dims, int max_dims)
+ {
+ PyArrayObject* result;
+ if (array_is_fortran(ary))
+ {
+ result = ary;
+ *is_new_object = 0;
+ }
+ else
+ {
+ Py_INCREF(ary->descr);
+ result = (PyArrayObject*) PyArray_FromArray(ary, ary->descr, NPY_FORTRAN);
+ *is_new_object = 1;
+ }
+ return result;
+ }
+
/* Convert a given PyObject to a contiguous PyArrayObject of the
* specified type. If the input object is not a contiguous
* PyArrayObject, a new one will be created and the new object flag
@@ -255,8 +279,37 @@
*is_new_object = is_new1 || is_new2;
return ary1;
}
-}
+ /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+ * specified type. If the input object is not a Fortran-ordered
+ * PyArrayObject, a new one will be created and the new object flag
+ * will be set.
+ */
+ PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+ int typecode,
+ int* is_new_object)
+ {
+ int is_new1 = 0;
+ int is_new2 = 0;
+ PyArrayObject* ary2;
+ PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+ &is_new1);
+ if (ary1)
+ {
+ ary2 = make_fortran(ary1, &is_new2, 0, 0);
+ if (is_new1 && is_new2)
+ {
+ Py_DECREF(ary1);
+ }
+ ary1 = ary2;
+ }
+ *is_new_object = is_new1 || is_new2;
+ return ary1;
+ }
+
+} /* end fragment */
+
+
/**********************************************************************/
%fragment("NumPy_Array_Requirements", "header",
@@ -716,8 +769,8 @@
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[2] = { -1, -1 };
- array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
- &is_new_object);
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
if (!array || !require_dimensions(array, 2) ||
!require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
@@ -864,8 +917,8 @@
(PyArrayObject* array=NULL, int is_new_object=0)
{
npy_intp size[3] = { -1, -1, -1 };
- array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
- &is_new_object);
+ array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+ &is_new_object);
if (!array || !require_dimensions(array, 3) ||
!require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
$1 = (DATA_TYPE*) array_data(array);
Added: trunk/numpy/doc/swig/test/Fortran.cxx
===================================================================
--- trunk/numpy/doc/swig/test/Fortran.cxx 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/Fortran.cxx 2008-08-12 18:46:31 UTC (rev 5631)
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <math.h>
+#include <iostream>
+#include "Fortran.h"
+
+#define TEST_FUNCS(TYPE, SNAME) \
+\
+TYPE SNAME ## SecondElement(TYPE * matrix, int rows, int cols) { \
+ TYPE result = matrix[1]; \
+ return result; \
+} \
+
+TEST_FUNCS(signed char , schar )
+TEST_FUNCS(unsigned char , uchar )
+TEST_FUNCS(short , short )
+TEST_FUNCS(unsigned short , ushort )
+TEST_FUNCS(int , int )
+TEST_FUNCS(unsigned int , uint )
+TEST_FUNCS(long , long )
+TEST_FUNCS(unsigned long , ulong )
+TEST_FUNCS(long long , longLong )
+TEST_FUNCS(unsigned long long, ulongLong)
+TEST_FUNCS(float , float )
+TEST_FUNCS(double , double )
Added: trunk/numpy/doc/swig/test/Fortran.h
===================================================================
--- trunk/numpy/doc/swig/test/Fortran.h 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/Fortran.h 2008-08-12 18:46:31 UTC (rev 5631)
@@ -0,0 +1,21 @@
+#ifndef FORTRAN_H
+#define FORTRAN_H
+
+#define TEST_FUNC_PROTOS(TYPE, SNAME) \
+\
+TYPE SNAME ## SecondElement( TYPE * matrix, int rows, int cols); \
+
+TEST_FUNC_PROTOS(signed char , schar )
+TEST_FUNC_PROTOS(unsigned char , uchar )
+TEST_FUNC_PROTOS(short , short )
+TEST_FUNC_PROTOS(unsigned short , ushort )
+TEST_FUNC_PROTOS(int , int )
+TEST_FUNC_PROTOS(unsigned int , uint )
+TEST_FUNC_PROTOS(long , long )
+TEST_FUNC_PROTOS(unsigned long , ulong )
+TEST_FUNC_PROTOS(long long , longLong )
+TEST_FUNC_PROTOS(unsigned long long, ulongLong)
+TEST_FUNC_PROTOS(float , float )
+TEST_FUNC_PROTOS(double , double )
+
+#endif
Added: trunk/numpy/doc/swig/test/Fortran.i
===================================================================
--- trunk/numpy/doc/swig/test/Fortran.i 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/Fortran.i 2008-08-12 18:46:31 UTC (rev 5631)
@@ -0,0 +1,36 @@
+// -*- c++ -*-
+%module Fortran
+
+%{
+#define SWIG_FILE_WITH_INIT
+#include "Fortran.h"
+%}
+
+// Get the NumPy typemaps
+%include "../numpy.i"
+
+%init %{
+ import_array();
+%}
+
+%define %apply_numpy_typemaps(TYPE)
+
+%apply (TYPE* IN_FARRAY2, int DIM1, int DIM2) {(TYPE* matrix, int rows, int cols)};
+
+%enddef /* %apply_numpy_typemaps() macro */
+
+%apply_numpy_typemaps(signed char )
+%apply_numpy_typemaps(unsigned char )
+%apply_numpy_typemaps(short )
+%apply_numpy_typemaps(unsigned short )
+%apply_numpy_typemaps(int )
+%apply_numpy_typemaps(unsigned int )
+%apply_numpy_typemaps(long )
+%apply_numpy_typemaps(unsigned long )
+%apply_numpy_typemaps(long long )
+%apply_numpy_typemaps(unsigned long long)
+%apply_numpy_typemaps(float )
+%apply_numpy_typemaps(double )
+
+// Include the header file to be wrapped
+%include "Fortran.h"
Modified: trunk/numpy/doc/swig/test/Makefile
===================================================================
--- trunk/numpy/doc/swig/test/Makefile 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/Makefile 2008-08-12 18:46:31 UTC (rev 5631)
@@ -1,13 +1,13 @@
# SWIG
-INTERFACES = Array.i Farray.i Vector.i Matrix.i Tensor.i
+INTERFACES = Array.i Farray.i Vector.i Matrix.i Tensor.i Fortran.i
WRAPPERS = $(INTERFACES:.i=_wrap.cxx)
PROXIES = $(INTERFACES:.i=.py )
# Default target: build the tests
.PHONY : all
all: $(WRAPPERS) Array1.cxx Array1.h Farray.cxx Farray.h Vector.cxx Vector.h \
- Matrix.cxx Matrix.h Tensor.cxx Tensor.h
- ./setup.py build
+ Matrix.cxx Matrix.h Tensor.cxx Tensor.h Fortran.h Fortran.cxx
+ ./setup.py build_ext -i
# Test target: run the tests
.PHONY : test
@@ -17,6 +17,7 @@
python testTensor.py
python testArray.py
python testFarray.py
+ python testFortran.py
# Rule: %.i -> %_wrap.cxx
%_wrap.cxx: %.i %.h ../numpy.i
@@ -28,5 +29,6 @@
.PHONY : clean
clean:
$(RM) -r build
+ $(RM) *.so
$(RM) $(WRAPPERS)
$(RM) $(PROXIES)
Modified: trunk/numpy/doc/swig/test/setup.py
===================================================================
--- trunk/numpy/doc/swig/test/setup.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/setup.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -49,10 +49,18 @@
include_dirs = [numpy_include],
)
+_Fortran = Extension("_Fortran",
+ ["Fortran_wrap.cxx",
+ "Fortran.cxx"],
+ include_dirs = [numpy_include],
+ )
+
# NumyTypemapTests setup
setup(name = "NumpyTypemapTests",
description = "Functions that work on arrays",
author = "Bill Spotz",
- py_modules = ["Array", "Farray", "Vector", "Matrix", "Tensor"],
- ext_modules = [_Array , _Farray , _Vector , _Matrix , _Tensor ]
+ py_modules = ["Array", "Farray", "Vector", "Matrix", "Tensor",
+ "Fortran"],
+ ext_modules = [_Array , _Farray , _Vector , _Matrix , _Tensor,
+ _Fortran]
)
Modified: trunk/numpy/doc/swig/test/testArray.py
===================================================================
--- trunk/numpy/doc/swig/test/testArray.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/testArray.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -14,10 +14,6 @@
else:
BadListError = ValueError
-# Add the distutils-generated build directory to the python search path and then
-# import the extension module
-libDir = "lib.%s-%s" % (get_platform(), sys.version[:3])
-sys.path.insert(0,os.path.join("build", libDir))
import Array
######################################################################
Added: trunk/numpy/doc/swig/test/testFortran.py
===================================================================
--- trunk/numpy/doc/swig/test/testFortran.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/testFortran.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -0,0 +1,169 @@
+#! /usr/bin/env python
+
+# System imports
+from distutils.util import get_platform
+import os
+import sys
+import unittest
+
+# Import NumPy
+import numpy as np
+major, minor = [ int(d) for d in np.__version__.split(".")[:2] ]
+if major == 0: BadListError = TypeError
+else: BadListError = ValueError
+
+import Fortran
+
+######################################################################
+
+class FortranTestCase(unittest.TestCase):
+
+ def __init__(self, methodName="runTests"):
+ unittest.TestCase.__init__(self, methodName)
+ self.typeStr = "double"
+ self.typeCode = "d"
+
+ # Test (type* IN_FARRAY2, int DIM1, int DIM2) typemap
+ def testSecondElementContiguous(self):
+ "Test luSplit function with a Fortran-array"
+ print >>sys.stderr, self.typeStr, "... ",
+ second = Fortran.__dict__[self.typeStr + "SecondElement"]
+ matrix = np.arange(9).reshape(3, 3).astype(self.typeCode)
+ self.assertEquals(second(matrix), 3)
+
+ def testSecondElementFortran(self):
+ "Test luSplit function with a Fortran-array"
+ print >>sys.stderr, self.typeStr, "... ",
+ second = Fortran.__dict__[self.typeStr + "SecondElement"]
+ matrix = np.asfortranarray(np.arange(9).reshape(3, 3),
+ self.typeCode)
+ self.assertEquals(second(matrix), 3)
+
+ def testSecondElementObject(self):
+ "Test luSplit function with a Fortran-array"
+ print >>sys.stderr, self.typeStr, "... ",
+ second = Fortran.__dict__[self.typeStr + "SecondElement"]
+ matrix = np.asfortranarray([[0,1,2],[3,4,5],[6,7,8]], self.typeCode)
+ self.assertEquals(second(matrix), 3)
+
+######################################################################
+
+class scharTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "schar"
+ self.typeCode = "b"
+
+######################################################################
+
+class ucharTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "uchar"
+ self.typeCode = "B"
+
+######################################################################
+
+class shortTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "short"
+ self.typeCode = "h"
+
+######################################################################
+
+class ushortTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "ushort"
+ self.typeCode = "H"
+
+######################################################################
+
+class intTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "int"
+ self.typeCode = "i"
+
+######################################################################
+
+class uintTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "uint"
+ self.typeCode = "I"
+
+######################################################################
+
+class longTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "long"
+ self.typeCode = "l"
+
+######################################################################
+
+class ulongTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "ulong"
+ self.typeCode = "L"
+
+######################################################################
+
+class longLongTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "longLong"
+ self.typeCode = "q"
+
+######################################################################
+
+class ulongLongTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "ulongLong"
+ self.typeCode = "Q"
+
+######################################################################
+
+class floatTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "float"
+ self.typeCode = "f"
+
+######################################################################
+
+class doubleTestCase(FortranTestCase):
+ def __init__(self, methodName="runTest"):
+ FortranTestCase.__init__(self, methodName)
+ self.typeStr = "double"
+ self.typeCode = "d"
+
+######################################################################
+
+if __name__ == "__main__":
+
+ # Build the test suite
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite( scharTestCase))
+ suite.addTest(unittest.makeSuite( ucharTestCase))
+ suite.addTest(unittest.makeSuite( shortTestCase))
+ suite.addTest(unittest.makeSuite( ushortTestCase))
+ suite.addTest(unittest.makeSuite( intTestCase))
+ suite.addTest(unittest.makeSuite( uintTestCase))
+ suite.addTest(unittest.makeSuite( longTestCase))
+ suite.addTest(unittest.makeSuite( ulongTestCase))
+ suite.addTest(unittest.makeSuite( longLongTestCase))
+ suite.addTest(unittest.makeSuite(ulongLongTestCase))
+ suite.addTest(unittest.makeSuite( floatTestCase))
+ suite.addTest(unittest.makeSuite( doubleTestCase))
+
+ # Execute the test suite
+ print "Testing 2D Functions of Module Matrix"
+ print "NumPy version", np.__version__
+ print
+ result = unittest.TextTestRunner(verbosity=2).run(suite)
+ sys.exit(len(result.errors) + len(result.failures))
Modified: trunk/numpy/doc/swig/test/testMatrix.py
===================================================================
--- trunk/numpy/doc/swig/test/testMatrix.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/testMatrix.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -12,10 +12,6 @@
if major == 0: BadListError = TypeError
else: BadListError = ValueError
-# Add the distutils-generated build directory to the python search path and then
-# import the extension module
-libDir = "lib.%s-%s" % (get_platform(), sys.version[:3])
-sys.path.insert(0,os.path.join("build", libDir))
import Matrix
######################################################################
Modified: trunk/numpy/doc/swig/test/testTensor.py
===================================================================
--- trunk/numpy/doc/swig/test/testTensor.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/testTensor.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -13,10 +13,6 @@
if major == 0: BadListError = TypeError
else: BadListError = ValueError
-# Add the distutils-generated build directory to the python search path and then
-# import the extension module
-libDir = "lib.%s-%s" % (get_platform(), sys.version[:3])
-sys.path.insert(0,os.path.join("build", libDir))
import Tensor
######################################################################
Modified: trunk/numpy/doc/swig/test/testVector.py
===================================================================
--- trunk/numpy/doc/swig/test/testVector.py 2008-08-12 06:56:11 UTC (rev 5630)
+++ trunk/numpy/doc/swig/test/testVector.py 2008-08-12 18:46:31 UTC (rev 5631)
@@ -12,10 +12,6 @@
if major == 0: BadListError = TypeError
else: BadListError = ValueError
-# Add the distutils-generated build directory to the python search path and then
-# import the extension module
-libDir = "lib.%s-%s" % (get_platform(), sys.version[:3])
-sys.path.insert(0,os.path.join("build", libDir))
import Vector
######################################################################
More information about the Numpy-svn
mailing list