Commit Graph

580 Commits (c5a0f1a8399f83919a1ce70f83a05f7f9b948e24)

Author SHA1 Message Date
dellaert c5a0f1a839 Undo unrelated changes 2017-08-06 17:42:20 -07:00
dellaert 3bbea0f301 Make pxd a bit nicer to read 2017-08-06 17:26:12 -07:00
dellaert 905aac29f8 Only define as many return values as needed 2017-08-06 17:15:47 -07:00
dellaert 81c15d950a Removed kwargs overhead for overloaded methods 2017-08-06 16:53:04 -07:00
dellaert d752c9e249 Re-wrote constructor overloading logic which saves a lot of overhead 2017-08-06 14:58:23 -07:00
dellaert 2374347e69 Make internal, overloaded static methods cdefs to avoid call code/overhead 2017-08-06 13:25:54 -07:00
dellaert 6068166d2b Moved wrapper class signature to Class.cpp 2017-08-06 12:21:26 -07:00
dellaert 74a33ff222 Re-structured argument overloading to call a common function 2017-08-06 11:07:13 -07:00
Duy-Nguyen Ta 82531c561f clonedEigency --> gtsam_eigency. Update readme. 2017-07-28 15:26:19 -04:00
Duy-Nguyen Ta 5ff6a4e397 update expected cython wrap test output 2017-07-27 22:32:53 -04:00
Duy-Nguyen Ta c0dd740d12 correct indentation for __str__ 2017-07-27 22:32:27 -04:00
Duy-Nguyen Ta 742097aed0 eigency --> clonedEigency. Fixing bugs and improve eigency build. 2017-07-27 22:26:53 -04:00
Duy-Nguyen Ta b1071b08a0 redirect stdcout to a stringstream so Python __str__() can properly return a string after calling the c++ print function
This is to avoid a printing issue in some Python's IDE when __str__() is called to update objects' values in Debug mode.
2017-07-25 16:32:26 -04:00
dellaert c8dec5d8dc Small changes in comments and docs 2017-05-20 12:23:41 -07:00
Duy-Nguyen Ta a8d363c347 update expected pyx 2017-03-21 03:52:01 -04:00
Duy-Nguyen Ta 869dc811b0 graceful dynamic cast failures 2017-03-21 02:34:04 -04:00
Duy-Nguyen Ta e624b6fe72 don't change matlab's generated filename (gtsam_wrapper), only cmake targets (to gtsam_matlab_wrapper) 2017-03-18 22:01:24 -04:00
Duy-Nguyen Ta 0da506b3a9 change gtsam_wrapper --> gtsam_matlab_wrapper 2017-03-18 20:32:25 -04:00
Duy-Nguyen Ta ee75faa0df test cython wrapper's generated files 2017-03-18 18:35:28 -04:00
Duy-Nguyen Ta e3918da95c update test to comply with a cython wrapper's requirement: need an include for every class. 2017-03-18 18:33:01 -04:00
Duy-Nguyen Ta 2146aa140c default value for cython extra imports 2017-03-18 18:30:44 -04:00
Duy-Nguyen Ta 07b1bbfe7f remove namespace requirement for cython wrapper
Only for unittesting wrap geometry.h, not yet tested in real python/cython
2017-03-18 18:29:53 -04:00
Duy-Nguyen Ta 42deeb7bf0 fix/update matlab wrapper tests when wrap serialization option is off 2017-03-18 18:26:21 -04:00
Duy-Nguyen Ta 16a1643d17 gracefully rasing exception when trying to create obj of a class with no constructor 2017-03-15 22:47:14 -04:00
Duy-Nguyen Ta 52f54d07bd remove blank lines 2017-03-15 22:45:48 -04:00
Duy-Nguyen Ta c52f54221e update testWrap to call new function names 2017-03-15 17:03:13 -04:00
Duy-Nguyen Ta 6bf7ea23cf convert numpy input params to dtype float and order 'F' automatically
using numpy.astype(...). No copy if the params are already in the correct dtype and storage order.

For a function
    f(Matrix A, Matrix B),
simply wrapping it to pyx as
   f(A.astype(float, order='F', copy=False), B.astype(float, order='F', copy=False))
won't work.
It produces a strange side-effect that the content of A is overwritten by B and the two inputs are the same (data address) inside the function!

This is because Cython decreases the ref count for the temporary variable resulted from A.astype(...) before generates the wrap for B.astype(...).
Hence, the A.astype temp var is probably reused for B.astype, and they were pointing to the same data address.

For that reason, we have to go a longer route and wrap it as:
  A = A.astype(float, order='F', copy=False)
  B = B.astype(float, order='F', copy=False)
  f(A, B)

For future ref., here is a sample of the wrongly generated code that wraps the JacobianFactor constructor:
Jacobian(Key i1, Matrix A1, Key i2, Matrix A2, Vector b, noiseModel::Diagonal model)

Wrongly wrapped pyx code:
self.shared_CJacobianFactor_ = shared_ptr[CJacobianFactor](new CJacobianFactor(i1, <MatrixXd>(Map[MatrixXd](A1.astype(float, order='F',copy=False)), i2, <MatrixXd>(Map[MatrixXd](A2.astype(float, order='F', copy=False)), <VectorXd>(Map[VectorXd](b.astype(float, order='F', copy=False))), model.shared_CnoiseModel_Diagonal_))

The problematic Cython generated CPP code with a comment on the problematic line:
/////////////////////////////////////////
// WRONG VERSION
/////////////////////////////////////////
  __pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A1), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_12);
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
  __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_13);
  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
  try {
    __pyx_t_14 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_13));
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 2107, __pyx_L1_error)
  }
///////////////////////////////////////////////
  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;  	//<------- Problematic line!!! Killing this will result in the correct result!
///////////////////////////////////////////////
  __pyx_t_13 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_A2), __pyx_n_s_astype); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_13);
  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
  __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)(&PyFloat_Type)));
  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_13, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_12);
  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
  try {
    __pyx_t_15 = eigency::Map<Eigen::MatrixXd> (((PyArrayObject *)__pyx_t_12));
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 2107, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
  __pyx_t_12 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_b), __pyx_n_s_astype); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_12);
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
  __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
  PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)(&PyFloat_Type)));
  __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_F) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) __PYX_ERR(0, 2107, __pyx_L1_error)
  __pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_12, __pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 2107, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_13);
  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (!(likely(((__pyx_t_13) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_13, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 2107, __pyx_L1_error)
  try {
    __pyx_t_16 = eigency::Map<Eigen::VectorXd> (((PyArrayObject *)__pyx_t_13));
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 2107, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
  try {
    __pyx_t_17 = new gtsam::JacobianFactor(__pyx_v_i1, ((Eigen::MatrixXd)__pyx_t_14), __pyx_v_i2, ((Eigen::MatrixXd)__pyx_t_15), ((Eigen::VectorXd)__pyx_t_16), __pyx_v_model->shared_CnoiseModel_Diagonal_);
  } catch(...) {
    __Pyx_CppExn2PyErr();
    __PYX_ERR(0, 2107, __pyx_L1_error)
  }
  __pyx_v_self->shared_CJacobianFactor_ = boost::shared_ptr<gtsam::JacobianFactor> (__pyx_t_17);
2017-03-15 13:47:11 -04:00
Duy-Nguyen Ta 0e278f81c6 remove Vectorize, simplify to just numpy.squeeze 2017-03-10 23:33:14 -05:00
Duy-Nguyen Ta 89bc31d703 fix comment 2017-03-10 23:28:26 -05:00
Duy-Nguyen Ta dc7792d350 unify/rename functions: matlab_code and cython_wrapper to generate_xxxxx_wrapper 2017-03-10 23:27:29 -05:00
Duy-Nguyen Ta b7efaf8c3f special ctor signature to be used with cyCreateFromShared
so that calling the default ctor by mistake on a class without the default ctor will respond nicely with an exception instead of a seg-fault
2017-03-08 15:22:16 -05:00
Duy-Nguyen Ta c9666a1b44 fix merge problem
Argument::isScalar() was moved to Qualified and should be checked via Argument::type
2017-03-08 15:15:37 -05:00
Duy-Nguyen Ta c3b11af61e remove unfinished cython-wrap test prototype 2017-03-08 10:05:35 -05:00
Duy-Nguyen Ta d8e9271dd1 fix test 2017-03-08 10:03:27 -05:00
Duy-Nguyen Ta 68e0defa49 Merge branch 'develop' into feature/cython_wrapper 2017-03-08 09:51:15 -05:00
Duy-Nguyen Ta 5a8bd5afda [cython] bypass a problem with no default constructor
Add this to support cyCreateFromShared, which needs to call the default Python constructor to construct the Python object before reassigning the internal shared ptr to the c++ object.
2017-03-06 01:18:19 -05:00
Duy-Nguyen Ta ed8f7c5f82 [cython] remove copy constructor requirement
Using make_shared[C](other) instead of shared_ptr[C](new C(other)) to leverage the implicit default constructor inside C++
2017-03-06 01:06:53 -05:00
Simon Julier 6a109aca9b Throw an exception rather than call exit. 2017-01-20 01:58:59 +00:00
Simon Julier d8d7c5618a Generate an error and exit if trying to wrap a non-const scalar reference. 2017-01-19 01:49:12 +00:00
Simon Julier 21aa7a2e85 Fixed unrwapping of scalar references. 2017-01-17 10:12:00 +00:00
Duy-Nguyen Ta 189ce33e1d Support exceptions so ipython/python can catch and doesn't crash. Trade constness with exception since Cython doesn't allow both.
See: http://stackoverflow.com/questions/26904268/cython-both-const-and-except-in-c-method-declaration
2016-12-19 17:53:14 -05:00
Duy-Nguyen Ta d9d97c4bc7 Forward declare not only classes but their inheritance
This is needed for wrapping to Cython another project based on gtsam. The current scheme requires information about all parent classes. See updated comments in gtsam.h.
2016-12-19 17:47:30 -05:00
Duy-Nguyen Ta b55f7b1fa4 remove unused argument 2016-12-19 17:30:29 -05:00
Duy-Nguyen Ta 05a76164d3 forward declaration of ForwardDeclaration 2016-12-16 19:26:40 -05:00
Duy-Nguyen Ta da8a8a3bb0 remove unused argument 2016-12-16 19:24:49 -05:00
Duy-Nguyen Ta 126de1b8a4 revert usage info: interfacePath must be absolute. 2016-12-16 00:34:07 -05:00
Duy-Nguyen Ta f154be176f Major update to generate proper Cython pxd header files which could be included in other projects/modules
All cdef (class, functions, variables) declarations are moved to pxd. Implementations of those cdefs and normal Python def are in pyx.
See: http://cython.readthedocs.io/en/latest/src/userguide/sharing_declarations.html#sharing-extension-types
2016-12-16 00:23:45 -05:00
Duy-Nguyen Ta 0cef864663 __cinit__ --> __init__ 2016-12-05 11:00:33 -05:00
Duy-Nguyen Ta 1e425536bb squeeze extra dims of numpy vectors so no need ravel. 2016-11-30 05:57:12 -05:00
Duy-Nguyen Ta 4439968f05 tabs to spaces 2016-11-30 05:56:07 -05:00