Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get python modules installed from 'pip list' for cmake #1025

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 64 additions & 61 deletions src/cmake/modules/GUDHI_third_party_libraries.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -129,70 +129,73 @@ if (WITH_GUDHI_PYTHON)
# Can be set with -DPYTHON_EXECUTABLE=/usr/bin/python3 or -DPython_ADDITIONAL_VERSIONS=3 for instance.
find_package( PythonInterp )

# find_python_module tries to import module in Python interpreter and to retrieve its version number
# returns ${PYTHON_MODULE_NAME_UP}_VERSION and ${PYTHON_MODULE_NAME_UP}_FOUND
function( find_python_module PYTHON_MODULE_NAME )
string(TOUPPER ${PYTHON_MODULE_NAME} PYTHON_MODULE_NAME_UP)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import ${PYTHON_MODULE_NAME}; print(${PYTHON_MODULE_NAME}.__version__)"
RESULT_VARIABLE PYTHON_MODULE_RESULT
OUTPUT_VARIABLE PYTHON_MODULE_VERSION
ERROR_VARIABLE PYTHON_MODULE_ERROR)
if(PYTHON_MODULE_RESULT EQUAL 0)
# Remove all carriage returns as it can be multiline
string(REGEX REPLACE "\n" " " PYTHON_MODULE_VERSION "${PYTHON_MODULE_VERSION}")
message ("++ Python module ${PYTHON_MODULE_NAME} - Version ${PYTHON_MODULE_VERSION} found")

set(${PYTHON_MODULE_NAME_UP}_VERSION ${PYTHON_MODULE_VERSION} PARENT_SCOPE)
set(${PYTHON_MODULE_NAME_UP}_FOUND TRUE PARENT_SCOPE)
else()
message ("PYTHON_MODULE_NAME = ${PYTHON_MODULE_NAME}
- PYTHON_MODULE_RESULT = ${PYTHON_MODULE_RESULT}
- PYTHON_MODULE_VERSION = ${PYTHON_MODULE_VERSION}
- PYTHON_MODULE_ERROR = ${PYTHON_MODULE_ERROR}")
unset(${PYTHON_MODULE_NAME_UP}_VERSION PARENT_SCOPE)
set(${PYTHON_MODULE_NAME_UP}_FOUND FALSE PARENT_SCOPE)
endif()
endfunction( find_python_module )

# For modules that do not define module.__version__
function( find_python_module_no_version PYTHON_MODULE_NAME )
string(TOUPPER ${PYTHON_MODULE_NAME} PYTHON_MODULE_NAME_UP)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import ${PYTHON_MODULE_NAME}"
RESULT_VARIABLE PYTHON_MODULE_RESULT
ERROR_VARIABLE PYTHON_MODULE_ERROR)
if(PYTHON_MODULE_RESULT EQUAL 0)
# Remove carriage return
message ("++ Python module ${PYTHON_MODULE_NAME} found")
set(${PYTHON_MODULE_NAME_UP}_FOUND TRUE PARENT_SCOPE)
if( PYTHONINTERP_FOUND )
# GUDHI python run time third parties list, same syntax as detected by 'pip list', but in upper case
set(GUDHI_RUN_TIME_DEPENDENCIES "CYTHON;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "PYTEST;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "MATPLOTLIB;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "NUMPY;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "SCIPY;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "SPHINX;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "SCIKIT-LEARN;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "POT;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "PYBIND11;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "TORCH;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "PYKEOPS;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "EAGERPY;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "HNSWLIB;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "TENSORFLOW;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "SPHINX-PARAMLINKS;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "PYDATA-SPHINX-THEME;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "SPHINXCONTRIB-BIBTEX;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "NETWORKX;${GUDHI_RUN_TIME_DEPENDENCIES}")
set(GUDHI_RUN_TIME_DEPENDENCIES "POUET;${GUDHI_RUN_TIME_DEPENDENCIES}")

# Get list of installed packages with 'python -m pip freeze'
execute_process(COMMAND ${PYTHON_EXECUTABLE} -m "pip" "freeze"
RESULT_VARIABLE PYTHON_MODULES_RESULT
OUTPUT_VARIABLE PYTHON_MODULES_LIST
ERROR_VARIABLE PYTHON_MODULES_ERROR)
if(PYTHON_MODULES_RESULT EQUAL 0)
string(REPLACE "\n" ";" PYTHON_MODULES_LIST ${PYTHON_MODULES_LIST})
else()
message ("PYTHON_MODULE_NAME = ${PYTHON_MODULE_NAME}
- PYTHON_MODULE_RESULT = ${PYTHON_MODULE_RESULT}
- PYTHON_MODULE_ERROR = ${PYTHON_MODULE_ERROR}")
set(${PYTHON_MODULE_NAME_UP}_FOUND FALSE PARENT_SCOPE)
message ("No pip installed")
endif()
endfunction( find_python_module_no_version )

if( PYTHONINTERP_FOUND )
find_python_module("cython")
find_python_module("pytest")
find_python_module("matplotlib")
find_python_module("numpy")
find_python_module("scipy")
find_python_module("sphinx")
find_python_module("sklearn")
find_python_module("ot")
find_python_module("pybind11")
find_python_module("torch")
find_python_module("pykeops")
find_python_module("eagerpy")
find_python_module_no_version("hnswlib")
find_python_module("tensorflow")
find_python_module("sphinx_paramlinks")
find_python_module("pydata_sphinx_theme")
find_python_module_no_version("sphinxcontrib.bibtex")
find_python_module("networkx")
# Set Cmake variables ${PYTHON_MODULE}_FOUND and ${PYTHON_MODULE}_VERSION
# of GUDHI_RUN_TIME_DEPENDENCIES found in 'pip list'
foreach(PYTHON_MODULE_LIST ${PYTHON_MODULES_LIST})
string(REPLACE "==" ";" PYTHON_MODULE ${PYTHON_MODULE_LIST})
list(POP_FRONT PYTHON_MODULE PYTHON_MODULE_NAME PYTHON_MODULE_VERSION)
string(TOUPPER ${PYTHON_MODULE_NAME} PYTHON_MODULE_NAME_UP)
string(TOLOWER ${PYTHON_MODULE_NAME} PYTHON_MODULE_NAME_LOW)
if(PYTHON_MODULE_NAME_UP IN_LIST GUDHI_RUN_TIME_DEPENDENCIES)
message("++ Python module ${PYTHON_MODULE_NAME_LOW} - Version ${PYTHON_MODULE_VERSION} found")
set(${PYTHON_MODULE_NAME_UP}_FOUND TRUE)
set(${PYTHON_MODULE_NAME_UP}_VERSION ${PYTHON_MODULE_VERSION})
else()
# message(" ## ${PYTHON_MODULE_NAME_UP} not found")
endif()
endforeach()

# Set gudhi.__debug_info__
# WARNING : to be done before setup.py.in configure_file
function( add_gudhi_debug_info DEBUG_INFO )
set(GUDHI_PYTHON_DEBUG_INFO "${GUDHI_PYTHON_DEBUG_INFO} \"${DEBUG_INFO}\\n\" \\\n" PARENT_SCOPE)
endfunction( add_gudhi_debug_info )

add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}")
foreach(GUDHI_RUN_TIME_DEPENDENCY ${GUDHI_RUN_TIME_DEPENDENCIES})
string(TOLOWER ${GUDHI_RUN_TIME_DEPENDENCY} GUDHI_RUN_TIME_DEPENDENCY_LOW)
if(${GUDHI_RUN_TIME_DEPENDENCY}_FOUND)
set(GUDHI_RUN_TIME_DEPENDENCY_VERSION "${${GUDHI_RUN_TIME_DEPENDENCY}_VERSION}")
add_gudhi_debug_info("${GUDHI_RUN_TIME_DEPENDENCY_LOW} version ${GUDHI_RUN_TIME_DEPENDENCY_VERSION}")
else()
# Output GUDHI_RUN_TIME_DEPENDENCIES not found in 'pip list'
message("++ Python module ${GUDHI_RUN_TIME_DEPENDENCY_LOW} not found")
endif()
endforeach()

endif()

if(NOT GUDHI_PYTHON_PATH)
Expand Down
110 changes: 25 additions & 85 deletions src/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,8 @@ function( add_gudhi_py_test THE_TEST )
endif()
endfunction( add_gudhi_py_test )

# Set gudhi.__debug_info__
# WARNING : to be done before setup.py.in configure_file
function( add_gudhi_debug_info DEBUG_INFO )
set(GUDHI_PYTHON_DEBUG_INFO "${GUDHI_PYTHON_DEBUG_INFO} \"${DEBUG_INFO}\\n\" \\\n" PARENT_SCOPE)
endfunction( add_gudhi_debug_info )

if(PYTHONINTERP_FOUND)
if(NUMPY_FOUND AND PYBIND11_FOUND AND CYTHON_FOUND)
add_gudhi_debug_info("Pybind11 version ${PYBIND11_VERSION}")
# PyBind11 modules
set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'bottleneck', ")
set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'hera', ")
Expand Down Expand Up @@ -79,59 +72,6 @@ if(PYTHONINTERP_FOUND)
set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'cover_complex', ")
set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'flag_filtration', ")

add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}")
add_gudhi_debug_info("Cython version ${CYTHON_VERSION}")
if(PYTEST_FOUND)
add_gudhi_debug_info("Pytest version ${PYTEST_VERSION}")
endif()
if(MATPLOTLIB_FOUND)
add_gudhi_debug_info("Matplotlib version ${MATPLOTLIB_VERSION}")
endif()
if(NUMPY_FOUND)
add_gudhi_debug_info("Numpy version ${NUMPY_VERSION}")
endif()
if(SCIPY_FOUND)
add_gudhi_debug_info("Scipy version ${SCIPY_VERSION}")
endif()
if(SKLEARN_FOUND)
add_gudhi_debug_info("Scikit-learn version ${SKLEARN_VERSION}")
endif()
if(OT_FOUND)
add_gudhi_debug_info("POT version ${OT_VERSION}")
endif()
if(HNSWLIB_FOUND)
# Does not have a version number...
add_gudhi_debug_info("HNSWlib found")
endif()
if(TORCH_FOUND)
add_gudhi_debug_info("PyTorch version ${TORCH_VERSION}")
endif()
if(PYKEOPS_FOUND)
add_gudhi_debug_info("PyKeOps version ${PYKEOPS_VERSION}")
endif()
if(EAGERPY_FOUND)
add_gudhi_debug_info("EagerPy version ${EAGERPY_VERSION}")
endif()
if(TENSORFLOW_FOUND)
add_gudhi_debug_info("TensorFlow version ${TENSORFLOW_VERSION}")
endif()
if(SPHINX_FOUND)
add_gudhi_debug_info("Sphinx version ${SPHINX_VERSION}")
endif()
if(SPHINX_PARAMLINKS_FOUND)
add_gudhi_debug_info("Sphinx-paramlinks version ${SPHINX_PARAMLINKS_VERSION}")
endif()
if(PYDATA_SPHINX_THEME_FOUND)
add_gudhi_debug_info("pydata_sphinx_theme version ${PYDATA_SPHINX_THEME_VERSION}")
endif()
if(SPHINXCONTRIB.BIBTEX_FOUND)
# Does not have a version number...
add_gudhi_debug_info("sphinxcontrib-bibtex found")
endif()
if(NETWORKX_FOUND)
add_gudhi_debug_info("NetworkX version ${NETWORKX_VERSION}")
endif()

set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_RESULT_OF_USE_DECLTYPE', ")
set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_ALL_NO_LIB', ")
set(GUDHI_PYTHON_EXTRA_COMPILE_ARGS "${GUDHI_PYTHON_EXTRA_COMPILE_ARGS}'-DBOOST_SYSTEM_NO_DEPRECATED', ")
Expand Down Expand Up @@ -353,14 +293,14 @@ if(PYTHONINTERP_FOUND)
# Documentation generation is available through sphinx - requires all modules
# Make it first as sphinx test is by far the longest test which is nice when testing in parallel
if(SPHINX_PATH)
if(SPHINX_PARAMLINKS_FOUND)
if(SPHINXCONTRIB.BIBTEX_FOUND)
if(PYDATA_SPHINX_THEME_FOUND)
if(SPHINX-PARAMLINKS_FOUND)
if(SPHINXCONTRIB-BIBTEX_FOUND)
if(PYDATA-SPHINX-THEME_FOUND)
if(MATPLOTLIB_FOUND)
if(NUMPY_FOUND)
if(SCIPY_FOUND)
if(SKLEARN_FOUND)
if(OT_FOUND)
if(SCIKIT-LEARN_FOUND)
if(POT_FOUND)
if(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 5.1.0)
set (GUDHI_SPHINX_MESSAGE "Generating API documentation with Sphinx in ${CMAKE_CURRENT_BINARY_DIR}/sphinx/")
# User warning - Sphinx is a static pages generator, and configured to work fine with user_version
Expand All @@ -385,14 +325,14 @@ if(PYTHONINTERP_FOUND)
message("++ Python documentation module will not be compiled because it requires a Eigen3 and CGAL version >= 5.1.0")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 5.1.0)
else(OT_FOUND)
else(POT_FOUND)
message("++ Python documentation module will not be compiled because POT was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(OT_FOUND)
else(SKLEARN_FOUND)
endif(POT_FOUND)
else(SCIKIT-LEARN_FOUND)
message("++ Python documentation module will not be compiled because scikit-learn was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(SKLEARN_FOUND)
endif(SCIKIT-LEARN_FOUND)
else(SCIPY_FOUND)
message("++ Python documentation module will not be compiled because scipy was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
Expand All @@ -405,18 +345,18 @@ if(PYTHONINTERP_FOUND)
message("++ Python documentation module will not be compiled because matplotlib was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(MATPLOTLIB_FOUND)
else(PYDATA_SPHINX_THEME_FOUND)
else(PYDATA-SPHINX-THEME_FOUND)
message("++ Python documentation module will not be compiled because pydata_sphinx_theme was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(PYDATA_SPHINX_THEME_FOUND)
else(SPHINXCONTRIB.BIBTEX_FOUND)
endif(PYDATA-SPHINX-THEME_FOUND)
else(SPHINXCONTRIB-BIBTEX_FOUND)
message("++ Python documentation module will not be compiled because sphinxcontrib-bibtex was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(SPHINXCONTRIB.BIBTEX_FOUND)
else(SPHINX_PARAMLINKS_FOUND)
endif(SPHINXCONTRIB-BIBTEX_FOUND)
else(SPHINX-PARAMLINKS_FOUND)
message("++ Python documentation module will not be compiled because sphinxcontrib-paramlinks was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
endif(SPHINX_PARAMLINKS_FOUND)
endif(SPHINX-PARAMLINKS_FOUND)
else(SPHINX_PATH)
message("++ Python documentation module will not be compiled because sphinx was not found")
set(GUDHI_MISSING_MODULES ${GUDHI_MISSING_MODULES} "python-documentation" CACHE INTERNAL "GUDHI_MISSING_MODULES")
Expand All @@ -438,7 +378,7 @@ if(PYTHONINTERP_FOUND)
add_gudhi_py_test(test_cubical_complex)

# Datasets are fetched for these tests
if(SKLEARN_FOUND AND WITH_GUDHI_REMOTE_TEST)
if(SCIKIT-LEARN_FOUND AND WITH_GUDHI_REMOTE_TEST)
add_gudhi_py_test(test_sklearn_cubical_persistence)

add_test(NAME cubical_complex_sklearn_itf_py_test
Expand Down Expand Up @@ -566,7 +506,7 @@ if(PYTHONINTERP_FOUND)

add_gudhi_py_test(test_rips_complex)

if(SKLEARN_FOUND)
if(SCIKIT-LEARN_FOUND)
# test_sklearn_rips_persistence is using gudhi.datasets.generators
if (NOT CGAL_WITH_EIGEN3_VERSION VERSION_LESS 4.11.0)
add_gudhi_py_test(test_sklearn_rips_persistence)
Expand Down Expand Up @@ -612,7 +552,7 @@ if(PYTHONINTERP_FOUND)
add_gudhi_py_test(test_off)

# Wasserstein
if(OT_FOUND)
if(POT_FOUND)
# EagerPy dependency because of enable_autodiff=True
if(EAGERPY_FOUND)
add_gudhi_py_test(test_wasserstein_distance)
Expand All @@ -626,7 +566,7 @@ if(PYTHONINTERP_FOUND)
endif()

# Representations
if(SKLEARN_FOUND AND MATPLOTLIB_FOUND AND OT_FOUND AND NOT CGAL_VERSION VERSION_LESS 4.11.0)
if(SCIKIT-LEARN_FOUND AND MATPLOTLIB_FOUND AND POT_FOUND AND NOT CGAL_VERSION VERSION_LESS 4.11.0)
add_gudhi_py_test(test_representations)
endif()

Expand All @@ -636,31 +576,31 @@ if(PYTHONINTERP_FOUND)
endif()

# Perslay
if(TENSORFLOW_FOUND AND SKLEARN_FOUND)
if(TENSORFLOW_FOUND AND SCIKIT-LEARN_FOUND)
add_gudhi_py_test(test_perslay)
endif()

# Betti curves
if(SKLEARN_FOUND AND SCIPY_FOUND)
if(SCIKIT-LEARN_FOUND AND SCIPY_FOUND)
add_gudhi_py_test(test_betti_curve_representations)
endif()

# Representations preprocessing
if(SKLEARN_FOUND)
if(SCIKIT-LEARN_FOUND)
add_gudhi_py_test(test_representations_preprocessing)
endif()

# Time Delay
add_gudhi_py_test(test_time_delay)

# DTM
if(SCIPY_FOUND AND SKLEARN_FOUND AND TORCH_FOUND AND HNSWLIB_FOUND AND PYKEOPS_FOUND AND EAGERPY_FOUND)
if(SCIPY_FOUND AND SCIKIT-LEARN_FOUND AND TORCH_FOUND AND HNSWLIB_FOUND AND PYKEOPS_FOUND AND EAGERPY_FOUND)
add_gudhi_py_test(test_knn)
add_gudhi_py_test(test_dtm)
endif()

# Tomato
if(SCIPY_FOUND AND SKLEARN_FOUND)
if(SCIPY_FOUND AND SCIKIT-LEARN_FOUND)
add_gudhi_py_test(test_tomato)
endif()

Expand All @@ -675,7 +615,7 @@ if(PYTHONINTERP_FOUND)
endif()

# Cover complex
if(SKLEARN_FOUND)
if(SCIKIT-LEARN_FOUND)
add_gudhi_py_test(test_cover_complex)
endif()

Expand Down
Loading
Loading