diff options
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/cmake/modules/FindGMPXX.cmake | 4 | ||||
-rw-r--r-- | src/cython/CMakeLists.txt | 82 | ||||
-rw-r--r-- | src/cython/Makefile | 29 | ||||
-rw-r--r-- | src/cython/cythonize_gudhi.py.in (renamed from src/cython/setup.py) | 8 | ||||
-rw-r--r-- | src/cython/gudhi.pyx.in (renamed from src/cython/gudhi.pyx) | 4 | ||||
-rw-r--r-- | src/cython/src/cython/cubical_complex.pyx | 2 | ||||
-rwxr-xr-x | src/cython/test/test_cubical_complex.py | 16 |
9 files changed, 117 insertions, 45 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e85be8a..c6736519 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,15 +74,14 @@ else() if (GCOVR_PATH) message("gcovr found in ${GCOVR_PATH}") endif() - # Required programs for unitary tests purpose FIND_PROGRAM( GPROF_PATH gprof ) if (GPROF_PATH) message("gprof found in ${GPROF_PATH}") endif() -FIND_PROGRAM( DIFF_PATH diff ) -if (DIFF_PATH) - message("diff found in ${DIFF_PATH}") -endif() + FIND_PROGRAM( DIFF_PATH diff ) + if (DIFF_PATH) + message("diff found in ${DIFF_PATH}") + endif() # BOOST ISSUE result_of vs C++11 add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE) @@ -135,6 +134,10 @@ endif() # GudhUI add_subdirectory(src/GudhUI) + # This variable is used by Cython CMakeLists.txt to know its path + set(GUDHI_CYTHON_PATH "src/cython") + add_subdirectory(${GUDHI_CYTHON_PATH}) + endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e55e4395..f0b24f63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -99,6 +99,10 @@ else() # Please let GudhUI in last compilation position as QT is known to modify CMAKE_CXX_FLAGS # GudhUI add_subdirectory(GudhUI) + + # This variable is used by Cython CMakeLists.txt to know its path + set(GUDHI_CYTHON_PATH "cython") + add_subdirectory(${GUDHI_CYTHON_PATH}) #--------------------------------------------------------------------------------------- #--------------------------------------------------------------------------------------- diff --git a/src/cmake/modules/FindGMPXX.cmake b/src/cmake/modules/FindGMPXX.cmake index 277e4b19..dda302c0 100644 --- a/src/cmake/modules/FindGMPXX.cmake +++ b/src/cmake/modules/FindGMPXX.cmake @@ -33,6 +33,10 @@ if(GMP_FOUND) DOC "Path to the GMPXX library" ) + if ( GMPXX_LIBRARIES ) + get_filename_component(GMPXX_LIBRARIES_DIR ${GMPXX_LIBRARIES} PATH CACHE ) + endif() + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GMPXX "DEFAULT_MSG" GMPXX_LIBRARIES GMPXX_INCLUDE_DIR ) diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt new file mode 100644 index 00000000..23305e63 --- /dev/null +++ b/src/cython/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 2.8) +project(Cython) + +FIND_PROGRAM( PYTHON_PATH python ) +FIND_PROGRAM( CYTHON_PATH cython ) + +if(PYTHON_PATH AND CYTHON_PATH) + if(MSVC) + message("++ MSVC") + else() + message("++ NOT MSVC") + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-std=c++11', ") + endif() + + find_package(Eigen3 3.1.0) + + if (EIGEN3_FOUND) + message("++ EIGEN3_FOUND") + # No problem, even if no CGAL found + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_EIGEN3_ENABLED', ") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${EIGEN3_INCLUDE_DIR}', ") + endif (EIGEN3_FOUND) + + # Copy recursively src and test repositories before packages finding + # Some tests files are removed in case some packages are not found + file(COPY src DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY test DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + if (CGAL_FOUND) + if (NOT CGAL_VERSION VERSION_LESS 4.7.0) + # If CGAL_VERSION >= 4.7.0, include alpha complex + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'CGAL', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${CGAL_LIBRARIES_DIR}', ") + # GMP and GMPXX are not required, but if present, CGAL will link with them. + if(GMP_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMP', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmp', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMP_LIBRARIES_DIR}', ") + if(GMPXX_FOUND) + set(GUDHI_CYTHON_EXTRA_COMPILE_ARGS "${GUDHI_CYTHON_EXTRA_COMPILE_ARGS}'-DCGAL_USE_GMPXX', ") + set(GUDHI_CYTHON_LIBRARIES "${GUDHI_CYTHON_LIBRARIES}'gmpxx', ") + set(GUDHI_CYTHON_LIBRARY_DIRS "${GUDHI_CYTHON_LIBRARY_DIRS}'${GMPXX_LIBRARIES_DIR}', ") + endif(GMPXX_FOUND) + endif(GMP_FOUND) + + set(GUDHI_CYTHON_ALPHA_COMPLEX "include 'src/cython/alpha_complex.pyx'") + else (NOT CGAL_VERSION VERSION_LESS 4.7.0) + # Remove alpha complex unitary tests + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/test/test_alpha_complex.py) + endif (NOT CGAL_VERSION VERSION_LESS 4.7.0) + endif (CGAL_FOUND) + + # Loop on INCLUDE_DIRECTORIES PROPERTY + get_property(GUDHI_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + foreach(GUDHI_INCLUDE_DIRECTORY ${GUDHI_INCLUDE_DIRECTORIES}) + message(STATUS "dir='${GUDHI_INCLUDE_DIRECTORY}'") + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${GUDHI_INCLUDE_DIRECTORY}', ") + endforeach() + set(GUDHI_CYTHON_INCLUDE_DIRS "${GUDHI_CYTHON_INCLUDE_DIRS}'${CMAKE_SOURCE_DIR}/${GUDHI_CYTHON_PATH}/src/cpp', ") + + # Generate cythonize_gudhi.py file to cythonize Gudhi + configure_file(cythonize_gudhi.py.in "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" @ONLY) + + # Generate gudhi.pyx - Gudhi cython file + configure_file(gudhi.pyx.in "${CMAKE_CURRENT_BINARY_DIR}/gudhi.pyx" @ONLY) + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND python "${CMAKE_CURRENT_BINARY_DIR}/cythonize_gudhi.py" "build_ext" "--inplace") + + add_custom_target(cythonize_gudhi ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gudhi.so") + + FIND_PROGRAM( PYTEST_PATH py.test ) + if(PYTEST_PATH) + add_test( + NAME gudhi_cython_py_test + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${PYTEST_PATH}) + endif(PYTEST_PATH) + +endif(PYTHON_PATH AND CYTHON_PATH) diff --git a/src/cython/Makefile b/src/cython/Makefile deleted file mode 100644 index 406f59ae..00000000 --- a/src/cython/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -ext: - python setup.py build_ext --inplace - -test: - python -m pytest test/test_simplex_tree.py - python -m pytest test/test_mini_simplex_tree.py - python -m pytest test/test_rips_complex.py - python -m pytest test/test_alpha_complex.py - python -m pytest test/test_witness_complex.py - python -m pytest test/test_cubical_complex.py - -example: - python example/simplex_tree_example.py - python example/mini_simplex_tree_example.py - python example/rips_complex_example.py - python example/alpha_complex_example.py - python example/random_cubical_complex_example.py 10 10 - python example/cubical_complex_from_perseus_file_example.py -f ../data/bitmap/CubicalTwoSphere.txt - python example/witness_complex_from_file_example.py data/500_random_points_on_3D_Torus.csv - # python example/gudhi_graphical_tools_example.py - # python example/rips_persistence_diagram.py - # python example/alpha_complex_from_file_example.py data/500_random_points_on_3D_Torus.csv - # python example/rips_complex_from_file_example.py data/2000_random_points_on_3D_Torus.csv - -clean: - rm -rf build/ *.o *.so *.cpp - -# For not Makefile to take into account example and test directories -.PHONY: example test diff --git a/src/cython/setup.py b/src/cython/cythonize_gudhi.py.in index 5b99ba5f..fb9a381e 100644 --- a/src/cython/setup.py +++ b/src/cython/cythonize_gudhi.py.in @@ -31,10 +31,10 @@ gudhi = Extension( "gudhi", sources = ['gudhi.pyx',], language = 'c++', - extra_compile_args=['-frounding-math','-std=c++11','-DCGAL_EIGEN3_ENABLED','-DCGAL_USE_GMP','-DCGAL_USE_GMPXX','-DCGAL_USE_MPFR'], - libraries=['mpfr','gmpxx','gmp','CGAL'], - library_dirs=['/usr/local/lib/'], - include_dirs = ['../include','./src/cpp','/usr/local/include/eigen3'], + extra_compile_args=[@GUDHI_CYTHON_EXTRA_COMPILE_ARGS@], + libraries=[@GUDHI_CYTHON_LIBRARIES@], + library_dirs=[@GUDHI_CYTHON_LIBRARY_DIRS@], + include_dirs = [@GUDHI_CYTHON_INCLUDE_DIRS@], ) setup( diff --git a/src/cython/gudhi.pyx b/src/cython/gudhi.pyx.in index c16852b8..a67c8a21 100644 --- a/src/cython/gudhi.pyx +++ b/src/cython/gudhi.pyx.in @@ -27,7 +27,7 @@ __license__ = "GPL v3" include "src/cython/simplex_tree.pyx" include "src/cython/mini_simplex_tree.pyx" include "src/cython/rips_complex.pyx" -include "src/cython/alpha_complex.pyx" include "src/cython/cubical_complex.pyx" -include "src/cython/witness_complex.pyx" include "src/cython/persistence_graphical_tools.py" +include "src/cython/witness_complex.pyx" +@GUDHI_CYTHON_ALPHA_COMPLEX@ diff --git a/src/cython/src/cython/cubical_complex.pyx b/src/cython/src/cython/cubical_complex.pyx index 4192b195..402d264c 100644 --- a/src/cython/src/cython/cubical_complex.pyx +++ b/src/cython/src/cython/cubical_complex.pyx @@ -63,7 +63,7 @@ cdef class CubicalComplex: top_dimensional_cells (list): A list of top dimensional cells. perseus_file (string): A perseus file style name. """ - if (((dimensions is not None) or (top_dimensional_cells is not None)) and + if ((dimensions is not None) or (top_dimensional_cells is not None) and (perseus_file is not '')): print("CubicalComplex can be constructed from dimensions and " "top_dimensional_cells or from a perseus file style name.") diff --git a/src/cython/test/test_cubical_complex.py b/src/cython/test/test_cubical_complex.py index 9f5847f9..af4c34ef 100755 --- a/src/cython/test/test_cubical_complex.py +++ b/src/cython/test/test_cubical_complex.py @@ -40,21 +40,25 @@ def test_non_existing_perseus_file_constructor(): assert cub.__is_persistence_defined() == False def test_dimension_or_perseus_file_constructor(): + # Create test file + test_file = open('CubicalOneSphere.txt', 'w') + test_file.write('2\n3\n3\n0\n0\n0\n0\n100\n0\n0\n0\n0\n') + test_file.close() # CubicalComplex can be constructed from dimensions and # top_dimensional_cells OR from a perseus file style name. cub = CubicalComplex(dimensions=[3, 3], top_dimensional_cells = [1,2,3,4,5,6,7,8,9], - perseus_file='../data/bitmap/CubicalOneSphere.txt') + perseus_file='CubicalOneSphere.txt') assert cub.__is_defined() == False assert cub.__is_persistence_defined() == False cub = CubicalComplex(top_dimensional_cells = [1,2,3,4,5,6,7,8,9], - perseus_file='../data/bitmap/CubicalOneSphere.txt') + perseus_file='CubicalOneSphere.txt') assert cub.__is_defined() == False assert cub.__is_persistence_defined() == False cub = CubicalComplex(dimensions=[3, 3], - perseus_file='../data/bitmap/CubicalOneSphere.txt') + perseus_file='CubicalOneSphere.txt') assert cub.__is_defined() == False assert cub.__is_persistence_defined() == False @@ -69,7 +73,11 @@ def test_dimension_constructor(): assert cub.persistent_betti_numbers(0, 1000) == [0, 0] def test_dimension_constructor(): - cub = CubicalComplex(perseus_file='../data/bitmap/CubicalOneSphere.txt') + # Create test file + test_file = open('CubicalOneSphere.txt', 'w') + test_file.write('2\n3\n3\n0\n0\n0\n0\n100\n0\n0\n0\n0\n') + test_file.close() + cub = CubicalComplex(perseus_file='CubicalOneSphere.txt') assert cub.__is_defined() == True assert cub.__is_persistence_defined() == False assert cub.persistence() == [(1, (0.0, 100.0)), (0, (0.0, 1.8446744073709552e+19))] |