From 5670c73158ac2a8c8a3360819d881d3b76889d44 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Tue, 8 Jan 2019 10:28:19 +0000 Subject: [PATCH 01/17] improved cython wrapper python3 support --- cmake/FindCython.cmake | 4 ++-- cython/gtsam/__init__.py.in | 2 +- wrap/Module.cpp | 4 ++++ wrap/tests/expected-cython/geometry.pyx | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 23afb00e6..292d9d51e 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -32,7 +32,7 @@ find_package( PythonInterp ) if ( PYTHONINTERP_FOUND ) execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import Cython; print Cython.__path__" + "import Cython; print(Cython.__path__[0])" RESULT_VARIABLE RESULT OUTPUT_VARIABLE CYTHON_PATH OUTPUT_STRIP_TRAILING_WHITESPACE @@ -51,7 +51,7 @@ endif () # RESULT=0 means ok if ( NOT RESULT ) execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import Cython; print Cython.__version__" + "import Cython; print(Cython.__version__)" RESULT_VARIABLE RESULT OUTPUT_VARIABLE CYTHON_VAR_OUTPUT ERROR_VARIABLE CYTHON_VAR_OUTPUT diff --git a/cython/gtsam/__init__.py.in b/cython/gtsam/__init__.py.in index 7d456023f..85451c680 100644 --- a/cython/gtsam/__init__.py.in +++ b/cython/gtsam/__init__.py.in @@ -1,2 +1,2 @@ -from gtsam import * +from .gtsam import * ${GTSAM_UNSTABLE_IMPORT} diff --git a/wrap/Module.cpp b/wrap/Module.cpp index a3b8df630..b2b1dc1dc 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -394,6 +394,10 @@ void Module::emit_cython_pxd(FileWriter& pxdFile) const { /* ************************************************************************* */ void Module::emit_cython_pyx(FileWriter& pyxFile) const { + // directives... + // allow str to automatically coerce to std::string and back (for python3) + pyxFile.oss << "# cython: c_string_type=str, c_string_encoding=ascii\n\n"; + // headers... string pxdHeader = name; pyxFile.oss << "cimport numpy as np\n" diff --git a/wrap/tests/expected-cython/geometry.pyx b/wrap/tests/expected-cython/geometry.pyx index 4bd14b130..7c20a500d 100644 --- a/wrap/tests/expected-cython/geometry.pyx +++ b/wrap/tests/expected-cython/geometry.pyx @@ -1,3 +1,5 @@ +# cython: c_string_type=str, c_string_encoding=ascii + cimport numpy as np import numpy as npp cimport geometry From 56ef410276e6dd8fb7ab101b543500300314df6e Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Tue, 8 Jan 2019 10:44:49 +0000 Subject: [PATCH 02/17] adding MKL installation instructions to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e03c81f2..64b36878e 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Prerequisites: Optional prerequisites - used automatically if findable by CMake: - [Intel Threaded Building Blocks (TBB)](http://www.threadingbuildingblocks.org/) (Ubuntu: `sudo apt-get install libtbb-dev`) -- [Intel Math Kernel Library (MKL)](http://software.intel.com/en-us/intel-mkl) +- [Intel Math Kernel Library (MKL)](http://software.intel.com/en-us/intel-mkl) (Ubuntu: [installing using APT](https://software.intel.com/en-us/articles/installing-intel-free-libs-and-python-apt-repo)) GTSAM 4 Compatibility --------------------- From b63537a47c8f7952a49f8f05fa669de537ada913 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Mon, 28 Jan 2019 16:30:29 +0000 Subject: [PATCH 03/17] fixed cython import for gtsam_unstable --- cython/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cython/CMakeLists.txt b/cython/CMakeLists.txt index bc21b91d1..e53c0b73e 100644 --- a/cython/CMakeLists.txt +++ b/cython/CMakeLists.txt @@ -19,7 +19,7 @@ if (GTSAM_INSTALL_CYTHON_TOOLBOX) # wrap gtsam_unstable if(GTSAM_BUILD_UNSTABLE) add_custom_target(gtsam_unstable_header DEPENDS "../gtsam_unstable/gtsam_unstable.h") - set(GTSAM_UNSTABLE_IMPORT "from gtsam_unstable import *") + set(GTSAM_UNSTABLE_IMPORT "from .gtsam_unstable import *") wrap_and_install_library_cython("../gtsam_unstable/gtsam_unstable.h" # interface_header "from gtsam.gtsam cimport *" # extra imports "${GTSAM_CYTHON_INSTALL_PATH}/gtsam" # install path From e896ae1c43376b5fc576061ece1dbac79146d236 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 30 Jan 2019 09:41:28 +0000 Subject: [PATCH 04/17] compile cython compatible with the chosen python version --- cmake/GtsamCythonWrap.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index 73e2b63e0..520d72a32 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -35,6 +35,11 @@ function(set_up_required_cython_packages) include_directories(${NUMPY_INCLUDE_DIRS}) endfunction() +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "from __future__ import print_function;import sys;print(sys.version[0], end='')" + OUTPUT_VARIABLE PYTHON_MAJOR_VERSION +) + # Convert pyx to cpp by executing cython # This is the first step to compile cython from the command line # as described at: http://cython.readthedocs.io/en/latest/src/reference/compilation.html @@ -52,7 +57,7 @@ function(pyx_to_cpp target pyx_file generated_cpp include_dirs) add_custom_command( OUTPUT ${generated_cpp} COMMAND - ${CYTHON_EXECUTABLE} -X boundscheck=False -v --fast-fail --cplus ${includes_for_cython} ${pyx_file} -o ${generated_cpp} + ${CYTHON_EXECUTABLE} -X boundscheck=False -v --fast-fail --cplus -${PYTHON_MAJOR_VERSION} ${includes_for_cython} ${pyx_file} -o ${generated_cpp} VERBATIM) add_custom_target(${target} ALL DEPENDS ${generated_cpp}) endfunction() From 70470ff59ba9d1c318db506d7c1f023e627e42e5 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 30 Jan 2019 09:49:38 +0000 Subject: [PATCH 05/17] fixed more python 3 related import problems --- wrap/Module.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrap/Module.cpp b/wrap/Module.cpp index b2b1dc1dc..a7db9e1f6 100644 --- a/wrap/Module.cpp +++ b/wrap/Module.cpp @@ -403,9 +403,9 @@ void Module::emit_cython_pyx(FileWriter& pyxFile) const { pyxFile.oss << "cimport numpy as np\n" "import numpy as npp\n" "cimport " << pxdHeader << "\n" - "from "<< pxdHeader << " cimport shared_ptr\n" - "from "<< pxdHeader << " cimport dynamic_pointer_cast\n" - "from "<< pxdHeader << " cimport make_shared\n"; + "from ."<< pxdHeader << " cimport shared_ptr\n" + "from ."<< pxdHeader << " cimport dynamic_pointer_cast\n" + "from ."<< pxdHeader << " cimport make_shared\n"; pyxFile.oss << "# C helper function that copies all arguments into a positional list.\n" "cdef list process_args(list keywords, tuple args, dict kwargs):\n" From 8df2c0a9a10d295d6cf6d821016e91296fb1ce19 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 30 Jan 2019 10:03:40 +0000 Subject: [PATCH 06/17] updated wrap test expected output --- wrap/tests/expected-cython/geometry.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wrap/tests/expected-cython/geometry.pyx b/wrap/tests/expected-cython/geometry.pyx index 7c20a500d..cae19d600 100644 --- a/wrap/tests/expected-cython/geometry.pyx +++ b/wrap/tests/expected-cython/geometry.pyx @@ -3,9 +3,9 @@ cimport numpy as np import numpy as npp cimport geometry -from geometry cimport shared_ptr -from geometry cimport dynamic_pointer_cast -from geometry cimport make_shared +from .geometry cimport shared_ptr +from .geometry cimport dynamic_pointer_cast +from .geometry cimport make_shared # C helper function that copies all arguments into a positional list. cdef list process_args(list keywords, tuple args, dict kwargs): cdef str keyword From a79e8654757fa72260956d98967deef7309124a7 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Fri, 8 Feb 2019 14:48:24 +0000 Subject: [PATCH 07/17] added note about python interpreter version to README --- cython/README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cython/README.md b/cython/README.md index 368d2a76d..3a7f65bca 100644 --- a/cython/README.md +++ b/cython/README.md @@ -2,20 +2,22 @@ This is the Cython/Python wrapper around the GTSAM C++ library. INSTALL ======= +- if you want to build the gtsam python library for a specific python version, use the `-DPYTHON_EXECUTABLE:FILEPATH=/path/to/python_interpreter` option when running `cmake` otherwise the interpreter at `$ which python` will be used. + - If the interpreter is inside an environment (such as an anaconda environment or virtualenv environment) then the environment should be active while building gtsam. - This wrapper needs Cython(>=0.25.2), backports_abc>=0.5, and numpy. These can be installed as follows: ```bash pip install -r /cython/requirements.txt ``` -- For compatiblity with gtsam's Eigen version, it contains its own cloned version of [Eigency](https://github.com/wouterboomsma/eigency.git), +- For compatibility with gtsam's Eigen version, it contains its own cloned version of [Eigency](https://github.com/wouterboomsma/eigency.git), named **gtsam_eigency**, to interface between C++'s Eigen and Python's numpy. -- Build and install gtsam using cmake with GTSAM_INSTALL_CYTHON_TOOLBOX enabled. -The wrapped module will be installed to GTSAM_CYTHON_INSTALL_PATH, which is -by default: /cython +- Build and install gtsam using cmake with `GTSAM_INSTALL_CYTHON_TOOLBOX` enabled. +The wrapped module will be installed to `GTSAM_CYTHON_INSTALL_PATH`, which is +by default: `/cython` -- Modify your PYTHONPATH to include the GTSAM_CYTHON_INSTALL_PATH: +- Modify your `PYTHONPATH` to include the `GTSAM_CYTHON_INSTALL_PATH`: ```bash export PYTHONPATH=$PYTHONPATH: ``` From 43ac8ad3438d619764c3b2c010a6d1a6fe90c0c3 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Fri, 8 Feb 2019 15:54:33 +0000 Subject: [PATCH 08/17] made experiment script compatible with python 2 and 3 --- cython/gtsam/tests/experiments.py | 113 ++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 cython/gtsam/tests/experiments.py diff --git a/cython/gtsam/tests/experiments.py b/cython/gtsam/tests/experiments.py new file mode 100644 index 000000000..db3127a83 --- /dev/null +++ b/cython/gtsam/tests/experiments.py @@ -0,0 +1,113 @@ +""" +This file is not a real python unittest. It contains small experiments +to test the wrapper with gtsam_test, a short version of gtsam.h. +Its name convention is different from other tests so it won't be discovered. +""" +from __future__ import print_function +import gtsam +import numpy as np + +r = gtsam.Rot3() +print(r) +print(r.pitch()) +r2 = gtsam.Rot3() +r3 = r.compose(r2) +print("r3 pitch:", r3.pitch()) + +v = np.array([1, 1, 1]) +print("v = ", v) +r4 = r3.retract(v) +print("r4 pitch:", r4.pitch()) +r4.print_(b'r4: ') +r3.print_(b"r3: ") + +v = r3.localCoordinates(r4) +print("localCoordinates:", v) + +Rmat = np.array([ + [0.990074, -0.0942928, 0.104218], + [0.104218, 0.990074, -0.0942928], + [-0.0942928, 0.104218, 0.990074] + ]) +r5 = gtsam.Rot3(Rmat) +r5.print_(b"r5: ") + +l = gtsam.Rot3.Logmap(r5) +print("l = ", l) + + +noise = gtsam.noiseModel_Gaussian.Covariance(Rmat) +noise.print_(b"noise:") + +D = np.array([1.,2.,3.]) +diag = gtsam.noiseModel_Diagonal.Variances(D) +print("diag:", diag) +diag.print_(b"diag:") +print("diag R:", diag.R()) + +p = gtsam.Point3() +p.print_("p:") +factor = gtsam.BetweenFactorPoint3(1,2,p, noise) +factor.print_(b"factor:") + +vv = gtsam.VectorValues() +vv.print_(b"vv:") +vv.insert(1, np.array([1.,2.,3.])) +vv.insert(2, np.array([3.,4.])) +vv.insert(3, np.array([5.,6.,7.,8.])) +vv.print_(b"vv:") + +vv2 = gtsam.VectorValues(vv) +vv2.insert(4, np.array([4.,2.,1])) +vv2.print_(b"vv2:") +vv.print_(b"vv:") + +vv.insert(4, np.array([1.,2.,4.])) +vv.print_(b"vv:") +vv3 = vv.add(vv2) + +vv3.print_(b"vv3:") + +values = gtsam.Values() +values.insert(1, gtsam.Point3()) +values.insert(2, gtsam.Rot3()) +values.print_(b"values:") + +factor = gtsam.PriorFactorVector(1, np.array([1.,2.,3.]), diag) +print("Prior factor vector: ", factor) + + + +keys = gtsam.KeyVector() + +keys.push_back(1) +keys.push_back(2) +print('size: ', keys.size()) +print(keys.at(0)) +print(keys.at(1)) + +noise = gtsam.noiseModel_Isotropic.Precision(2, 3.0) +noise.print_('noise:') +print('noise print:', noise) +f = gtsam.JacobianFactor(7, np.ones([2,2]), model=noise, b=np.ones(2)) +print('JacobianFactor(7):\n', f) +print("A = ", f.getA()) +print("b = ", f.getb()) + +f = gtsam.JacobianFactor(np.ones(2)) +f.print_('jacoboian b_in:') + + +print("JacobianFactor initalized with b_in:", f) + +diag = gtsam.noiseModel_Diagonal.Sigmas(np.array([1.,2.,3.])) +fv = gtsam.PriorFactorVector(1, np.array([4.,5.,6.]), diag) +print("priorfactorvector: ", fv) + +print("base noise: ", fv.get_noiseModel()) +print("casted to gaussian2: ", gtsam.dynamic_cast_noiseModel_Diagonal_noiseModel_Base(fv.get_noiseModel())) + +X = gtsam.symbol(65, 19) +print(X) +print(gtsam.symbolChr(X)) +print(gtsam.symbolIndex(X)) From 46eed55448fb753b7afc8d9ef8613f410faea8f0 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 13 Feb 2019 09:17:55 +0000 Subject: [PATCH 09/17] removed MKL installation instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64b36878e..7e03c81f2 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Prerequisites: Optional prerequisites - used automatically if findable by CMake: - [Intel Threaded Building Blocks (TBB)](http://www.threadingbuildingblocks.org/) (Ubuntu: `sudo apt-get install libtbb-dev`) -- [Intel Math Kernel Library (MKL)](http://software.intel.com/en-us/intel-mkl) (Ubuntu: [installing using APT](https://software.intel.com/en-us/articles/installing-intel-free-libs-and-python-apt-repo)) +- [Intel Math Kernel Library (MKL)](http://software.intel.com/en-us/intel-mkl) GTSAM 4 Compatibility --------------------- From e251dbaebd95cae3463b62e7dcfbc4c33e8f589b Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 13 Feb 2019 09:27:09 +0000 Subject: [PATCH 10/17] re-adding flags to pass to cmake to use correct python version --- cython/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cython/README.md b/cython/README.md index 3a7f65bca..896025124 100644 --- a/cython/README.md +++ b/cython/README.md @@ -2,7 +2,7 @@ This is the Cython/Python wrapper around the GTSAM C++ library. INSTALL ======= -- if you want to build the gtsam python library for a specific python version, use the `-DPYTHON_EXECUTABLE:FILEPATH=/path/to/python_interpreter` option when running `cmake` otherwise the interpreter at `$ which python` will be used. +- if you want to build the gtsam python library for python 3, use the `-DPython_ADDITIONAL_VERSIONS=3` option when running `cmake` otherwise the interpreter at `$ which python` will be used. - If the interpreter is inside an environment (such as an anaconda environment or virtualenv environment) then the environment should be active while building gtsam. - This wrapper needs Cython(>=0.25.2), backports_abc>=0.5, and numpy. These can be installed as follows: From a1fba6a5b1e3f6627414b84201ca3d376cd7bcb4 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 13 Feb 2019 09:28:34 +0000 Subject: [PATCH 11/17] removed experiments.py --- cython/gtsam/tests/experiments.py | 113 ------------------------------ 1 file changed, 113 deletions(-) delete mode 100644 cython/gtsam/tests/experiments.py diff --git a/cython/gtsam/tests/experiments.py b/cython/gtsam/tests/experiments.py deleted file mode 100644 index db3127a83..000000000 --- a/cython/gtsam/tests/experiments.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -This file is not a real python unittest. It contains small experiments -to test the wrapper with gtsam_test, a short version of gtsam.h. -Its name convention is different from other tests so it won't be discovered. -""" -from __future__ import print_function -import gtsam -import numpy as np - -r = gtsam.Rot3() -print(r) -print(r.pitch()) -r2 = gtsam.Rot3() -r3 = r.compose(r2) -print("r3 pitch:", r3.pitch()) - -v = np.array([1, 1, 1]) -print("v = ", v) -r4 = r3.retract(v) -print("r4 pitch:", r4.pitch()) -r4.print_(b'r4: ') -r3.print_(b"r3: ") - -v = r3.localCoordinates(r4) -print("localCoordinates:", v) - -Rmat = np.array([ - [0.990074, -0.0942928, 0.104218], - [0.104218, 0.990074, -0.0942928], - [-0.0942928, 0.104218, 0.990074] - ]) -r5 = gtsam.Rot3(Rmat) -r5.print_(b"r5: ") - -l = gtsam.Rot3.Logmap(r5) -print("l = ", l) - - -noise = gtsam.noiseModel_Gaussian.Covariance(Rmat) -noise.print_(b"noise:") - -D = np.array([1.,2.,3.]) -diag = gtsam.noiseModel_Diagonal.Variances(D) -print("diag:", diag) -diag.print_(b"diag:") -print("diag R:", diag.R()) - -p = gtsam.Point3() -p.print_("p:") -factor = gtsam.BetweenFactorPoint3(1,2,p, noise) -factor.print_(b"factor:") - -vv = gtsam.VectorValues() -vv.print_(b"vv:") -vv.insert(1, np.array([1.,2.,3.])) -vv.insert(2, np.array([3.,4.])) -vv.insert(3, np.array([5.,6.,7.,8.])) -vv.print_(b"vv:") - -vv2 = gtsam.VectorValues(vv) -vv2.insert(4, np.array([4.,2.,1])) -vv2.print_(b"vv2:") -vv.print_(b"vv:") - -vv.insert(4, np.array([1.,2.,4.])) -vv.print_(b"vv:") -vv3 = vv.add(vv2) - -vv3.print_(b"vv3:") - -values = gtsam.Values() -values.insert(1, gtsam.Point3()) -values.insert(2, gtsam.Rot3()) -values.print_(b"values:") - -factor = gtsam.PriorFactorVector(1, np.array([1.,2.,3.]), diag) -print("Prior factor vector: ", factor) - - - -keys = gtsam.KeyVector() - -keys.push_back(1) -keys.push_back(2) -print('size: ', keys.size()) -print(keys.at(0)) -print(keys.at(1)) - -noise = gtsam.noiseModel_Isotropic.Precision(2, 3.0) -noise.print_('noise:') -print('noise print:', noise) -f = gtsam.JacobianFactor(7, np.ones([2,2]), model=noise, b=np.ones(2)) -print('JacobianFactor(7):\n', f) -print("A = ", f.getA()) -print("b = ", f.getb()) - -f = gtsam.JacobianFactor(np.ones(2)) -f.print_('jacoboian b_in:') - - -print("JacobianFactor initalized with b_in:", f) - -diag = gtsam.noiseModel_Diagonal.Sigmas(np.array([1.,2.,3.])) -fv = gtsam.PriorFactorVector(1, np.array([4.,5.,6.]), diag) -print("priorfactorvector: ", fv) - -print("base noise: ", fv.get_noiseModel()) -print("casted to gaussian2: ", gtsam.dynamic_cast_noiseModel_Diagonal_noiseModel_Base(fv.get_noiseModel())) - -X = gtsam.symbol(65, 19) -print(X) -print(gtsam.symbolChr(X)) -print(gtsam.symbolIndex(X)) From 27f87d340e1a24071c728a37c9a00eb5a837f41b Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 13 Feb 2019 09:45:06 +0000 Subject: [PATCH 12/17] caching cmake variables --- cmake/GtsamCythonWrap.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index 520d72a32..bc6f230b0 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -3,6 +3,8 @@ # in the current environment are different from the cached! unset(PYTHON_EXECUTABLE CACHE) unset(CYTHON_EXECUTABLE CACHE) +unset(PYTHON_INCLUDE_DIR CACHE) +unset(PYTHON_MAJOR_VERSION CACHE) find_package(Cython 0.25.2 REQUIRED) # User-friendly Cython wrapping and installing function. From 09ac7f7c069a0c5f6d53d98b87a3e36e8c65d5e9 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 13 Feb 2019 09:55:09 +0000 Subject: [PATCH 13/17] removed requirement for python 2.7 in cmake --- cmake/GtsamCythonWrap.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index bc6f230b0..0f4cb827e 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -31,7 +31,7 @@ endfunction() function(set_up_required_cython_packages) # Set up building of cython module - find_package(PythonLibs 2.7 REQUIRED) + find_package(PythonLibs REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS}) find_package(NumPy REQUIRED) include_directories(${NUMPY_INCLUDE_DIRS}) From e9e8ca39900c84b3c2e4c3986ff591cc494700c4 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Thu, 14 Feb 2019 09:45:48 +0000 Subject: [PATCH 14/17] added option to specify python version --- CMakeLists.txt | 2 ++ cmake/FindNumPy.cmake | 8 ++++++++ cmake/GtsamCythonWrap.cmake | 21 ++++++++++++++++----- cython/README.md | 2 +- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1a421a31..834ce732e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ endif() option(GTSAM_INSTALL_MATLAB_TOOLBOX "Enable/Disable installation of matlab toolbox" OFF) option(GTSAM_INSTALL_CYTHON_TOOLBOX "Enable/Disable installation of Cython toolbox" OFF) option(GTSAM_BUILD_WRAP "Enable/Disable building of matlab/cython wrap utility (necessary for matlab/cython interface)" ON) +set(GTSAM_PYTHON_VERSION "Default" CACHE STRING "The version of python to build the cython wrapper or python module for (or Default)") # Check / set dependent variables for MATLAB wrapper if((GTSAM_INSTALL_MATLAB_TOOLBOX OR GTSAM_INSTALL_CYTHON_TOOLBOX) AND NOT GTSAM_BUILD_WRAP) @@ -554,6 +555,7 @@ endif() message(STATUS "Cython toolbox flags ") print_config_flag(${GTSAM_INSTALL_CYTHON_TOOLBOX} "Install Cython toolbox ") +message(STATUS " Python version : ${GTSAM_PYTHON_VERSION}") print_config_flag(${GTSAM_BUILD_WRAP} "Build Wrap ") message(STATUS "===============================================================") diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake index eafed165e..4f5743aa6 100644 --- a/cmake/FindNumPy.cmake +++ b/cmake/FindNumPy.cmake @@ -40,9 +40,17 @@ # Finding NumPy involves calling the Python interpreter if(NumPy_FIND_REQUIRED) + if(GTSAM_PYTHON_VERSION STREQUAL "Default") find_package(PythonInterp REQUIRED) + else() + find_package(PythonInterp ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) + endif() else() + if(GTSAM_PYTHON_VERSION STREQUAL "Default") find_package(PythonInterp) + else() + find_package(PythonInterp ${GTSAM_PYTHON_VERSION} EXACT) + endif() endif() if(NOT PYTHONINTERP_FOUND) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index 0f4cb827e..f329d31ab 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -5,8 +5,19 @@ unset(PYTHON_EXECUTABLE CACHE) unset(CYTHON_EXECUTABLE CACHE) unset(PYTHON_INCLUDE_DIR CACHE) unset(PYTHON_MAJOR_VERSION CACHE) + +if(GTSAM_PYTHON_VERSION STREQUAL "Default") + find_package(PythonLibs REQUIRED) +else() + find_package(PythonLibs ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) +endif() find_package(Cython 0.25.2 REQUIRED) +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "from __future__ import print_function;import sys;print(sys.version[0], end='')" + OUTPUT_VARIABLE PYTHON_MAJOR_VERSION +) + # User-friendly Cython wrapping and installing function. # Builds a Cython module from the provided interface_header. # For example, for the interface header gtsam.h, @@ -31,16 +42,16 @@ endfunction() function(set_up_required_cython_packages) # Set up building of cython module - find_package(PythonLibs REQUIRED) + if(GTSAM_PYTHON_VERSION STREQUAL "Default") + find_package(PythonLibs REQUIRED) + else() + find_package(PythonLibs ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) + endif() include_directories(${PYTHON_INCLUDE_DIRS}) find_package(NumPy REQUIRED) include_directories(${NUMPY_INCLUDE_DIRS}) endfunction() -execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "from __future__ import print_function;import sys;print(sys.version[0], end='')" - OUTPUT_VARIABLE PYTHON_MAJOR_VERSION -) # Convert pyx to cpp by executing cython # This is the first step to compile cython from the command line diff --git a/cython/README.md b/cython/README.md index 896025124..8ba824f8d 100644 --- a/cython/README.md +++ b/cython/README.md @@ -2,7 +2,7 @@ This is the Cython/Python wrapper around the GTSAM C++ library. INSTALL ======= -- if you want to build the gtsam python library for python 3, use the `-DPython_ADDITIONAL_VERSIONS=3` option when running `cmake` otherwise the interpreter at `$ which python` will be used. +- if you want to build the gtsam python library for a specific python version (eg 2.7), use the `-DGTSAM_PYTHON_VERSION=2.7` option when running `cmake` otherwise the default interpreter will be used. - If the interpreter is inside an environment (such as an anaconda environment or virtualenv environment) then the environment should be active while building gtsam. - This wrapper needs Cython(>=0.25.2), backports_abc>=0.5, and numpy. These can be installed as follows: From 9c1dfd244f2bbab5f1a9038d545612768cd527c6 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Thu, 14 Feb 2019 10:55:16 +0000 Subject: [PATCH 15/17] fixed a bug where unsetting the cached python version leads to different numpy/cython/libraries being used --- cmake/GtsamCythonWrap.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index f329d31ab..374e00c46 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -7,8 +7,10 @@ unset(PYTHON_INCLUDE_DIR CACHE) unset(PYTHON_MAJOR_VERSION CACHE) if(GTSAM_PYTHON_VERSION STREQUAL "Default") + find_package(PythonInterp REQUIRED) find_package(PythonLibs REQUIRED) else() + find_package(PythonInterp ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) find_package(PythonLibs ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) endif() find_package(Cython 0.25.2 REQUIRED) From dc80bc07557dffa8ea95cbe87c432e759c9a680b Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Wed, 6 Mar 2019 10:00:13 +0000 Subject: [PATCH 16/17] find correct interpreter version before looking for cython --- cmake/FindCython.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 292d9d51e..e5a32c30d 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -29,7 +29,12 @@ # Use the Cython executable that lives next to the Python executable # if it is a local installation. -find_package( PythonInterp ) +if(GTSAM_PYTHON_VERSION STREQUAL "Default") + find_package(PythonInterp) +else() + find_package(PythonInterp ${GTSAM_PYTHON_VERSION} EXACT) +endif() + if ( PYTHONINTERP_FOUND ) execute_process( COMMAND "${PYTHON_EXECUTABLE}" "-c" "import Cython; print(Cython.__path__[0])" From 2f232fd4d467980a9dfeaddaf02fccbd398d3825 Mon Sep 17 00:00:00 2001 From: Matthew Broadway Date: Thu, 7 Mar 2019 15:58:05 +0000 Subject: [PATCH 17/17] removed redundant call to find_package --- cmake/GtsamCythonWrap.cmake | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cmake/GtsamCythonWrap.cmake b/cmake/GtsamCythonWrap.cmake index 374e00c46..6366c1508 100644 --- a/cmake/GtsamCythonWrap.cmake +++ b/cmake/GtsamCythonWrap.cmake @@ -44,11 +44,6 @@ endfunction() function(set_up_required_cython_packages) # Set up building of cython module - if(GTSAM_PYTHON_VERSION STREQUAL "Default") - find_package(PythonLibs REQUIRED) - else() - find_package(PythonLibs ${GTSAM_PYTHON_VERSION} EXACT REQUIRED) - endif() include_directories(${PYTHON_INCLUDE_DIRS}) find_package(NumPy REQUIRED) include_directories(${NUMPY_INCLUDE_DIRS})