Commit Graph

596 Commits (c1b048020ee99ee209abe1d35fb0a9aaba3d6ec7)

Author SHA1 Message Date
Matthew Broadway 8df2c0a9a1 updated wrap test expected output 2019-02-28 09:14:39 +00:00
Matthew Broadway 70470ff59b fixed more python 3 related import problems 2019-02-28 09:14:39 +00:00
Matthew Broadway 5670c73158 improved cython wrapper python3 support 2019-02-28 09:14:39 +00:00
jlblancoc 7625c21777
Various fixes to cmake exported targets
List of changes:
 * -I boost is no longer required
   (Since the use of Boost::xxx imported targets)
 * fix missing Boost deps in imported gtsam by
   searching for Boost inside GTSAMConfig.cmake
 * Including the dirs for Eigen/MKL/SuiteSparse/Metis
   into exported targets public interface.
 * Fix missing cmake changes in wrap/*
 * Split build flags into private/public, not to
   expose to users flags that may be invasive.
 * Removed now useless include_dirs in "extra cmake"
 * Update cmake/example_project
 * Make cppunitlite to find boost headers via Boost::boost
 * Update README / INSTALL to reflect the updated minimum CMake >= 3.0
2019-02-15 22:04:04 +01:00
Frank Dellaert edb94a6e93 Better error message. 2019-01-20 16:52:44 -05:00
Frank Dellaert fbcfbf0cdd Made naming convention in wrapper uniform.
2D means Pose2 + Point2
3D means Pose3 + Point3
2018-12-31 11:19:46 -05:00
Frank Dellaert fe1daec086 Changed include error as in http://boost.2283326.n4.nabble.com/boost-serialization-Serializing-Dynamically-Loaded-Libraries-quot-Unregistered-Void-Cast-quot-td2570981.html 2018-12-30 16:24:19 -05:00
Frank Dellaert 70a9bbc404 Fix testWrap failure after Duy change 2018-10-31 12:51:30 +00:00
Duy-Nguyen Ta d802255eb3 support pythonic print for gtsam objects. 2018-10-17 05:40:57 -04:00
Frank Dellaert b9f080456c Catch exception by value 2018-10-08 22:54:48 -04:00
Frank Dellaert 9c3949f738 Added virtual destructors 2018-09-27 00:23:17 -04:00
Frank Dellaert 61241ee9ff fixed expected wrapper file 2017-12-02 22:14:56 -08:00
Frank Dellaert 4188a739ec Fixed overloaded methods/constructors 2017-12-02 18:43:18 -08:00
Duy-Nguyen Ta 7ecdbd5908 update expected result for cython wrap test 2017-08-28 14:12:15 -04:00
Duy-Nguyen Ta d23b5e4cfd only catch AssertionError exceptions when handling overloads, so that other C++ exceptions can be raised correctly 2017-08-25 11:18:16 -07:00
Duy-Nguyen Ta da5d3e303c update expected outputs for cython wrapper unittests 2017-08-15 13:46:32 -04:00
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