Skip to content
Open
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
23 changes: 22 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,28 @@ if(USE_LIBINT)
endif()

if(ENABLE_PYTHON)
add_subdirectory(pyoqp)
# --- Python selection (optional but recommended) ---
# Let users request a specific Python version, e.g. -DOQP_PYTHON_VERSION=3.11
set(OQP_PYTHON_VERSION "" CACHE STRING "Request a specific Python version (e.g. 3.11)")

if(OQP_PYTHON_VERSION)
# EXACT locks to the requested minor, e.g. 3.11.x only
find_package(Python ${OQP_PYTHON_VERSION} EXACT
REQUIRED COMPONENTS Interpreter Development)
else()
# Fall back to the default active Python
find_package(Python REQUIRED COMPONENTS Interpreter Development)
endif()

# Expose the resolved interpreter/lib to subdirectories (like pyoqp)
# so that a second find_package(Python ...) in subdirs reuses this one.
set(Python_EXECUTABLE "${Python_EXECUTABLE}" CACHE FILEPATH "Chosen Python interpreter" FORCE)
set(Python_INCLUDE_DIRS "${Python_INCLUDE_DIRS}" CACHE PATH "Chosen Python include dirs" FORCE)
set(Python_LIBRARIES "${Python_LIBRARIES}" CACHE FILEPATH "Chosen Python libraries" FORCE)

# You can also export convenient imported targets in subdirs:
# Python::Interpreter, Python::Python, Python::Module, Python::NumPy (if found)
add_subdirectory(pyoqp)
endif()

install(
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ git clone https://github.com/Open-Quantum-Platform/openqp.git

```bash
cd openqp
cmake -B build -G Ninja -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF
cmake -B build -G Ninja -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=gfortran -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF -DOQP_PYTHON_VERSION=3.11
ninja -C build install
cd pyoqp
pip install .
Expand All @@ -62,7 +62,7 @@ pip install .

```bash
cd openqp
cmake -B build -G Ninja -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=mpif90 -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF -DENABLE_MPI=ON
cmake -B build -G Ninja -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=mpif90 -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF -DOQP_PYTHON_VERSION=3.11 -DENABLE_MPI=ON
ninja -C build install
cd pyoqp
pip install .
Expand All @@ -72,14 +72,15 @@ pip install .

```bash
cd openqp
cmake -B build -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=mpif90 -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF -DENABLE_MPI=ON
cmake -B build -DUSE_LIBINT=OFF -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_Fortran_COMPILER=mpif90 -DCMAKE_INSTALL_PREFIX=. -DENABLE_OPENMP=ON -DLINALG_LIB_INT64=OFF -DOQP_PYTHON_VERSION=3.11 -DENABLE_MPI=ON
make -C build install
cd pyoqp
pip install .
```

- Use `-DUSE_LIBINT=ON` to replace the default ERI based on Rys Quadrature with `libint`.
- Use `-DLINALG_LIB_INT64=OFF` to ensure compatibility with third-party software like libdlfind compiled with 32-bit BLAS.
- Use `-DOQP_PYTHON_VERSION=3.11` to select the right Python version. Currently, 3.11 is chosen.

#### Environmental Settings

Expand Down
131 changes: 54 additions & 77 deletions pyoqp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,104 +1,81 @@
project(pyoqp)

find_package(Python3
REQUIRED
COMPONENTS
Interpreter Development
)
#find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED)
#find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT REQUIRED)
# Reuse the parent's Python. Fail early if parent forgot to provide it.
if(NOT TARGET Python::Interpreter OR NOT DEFINED Python_EXECUTABLE)
message(FATAL_ERROR
"pyoqp expects the top-level CMake to call find_package(Python ...).")
endif()

# --- Detect Python’s extension suffix, e.g. ".cpython-311-darwin.so"
execute_process(
COMMAND
${Python3_EXECUTABLE} "-c" "import re, cffi; print(re.compile('/__init__.py.*').sub('',cffi.__file__))"
RESULT_VARIABLE _cffi_status
OUTPUT_VARIABLE _cffi_location
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND "${Python_EXECUTABLE}" "-c"
"import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX') or '')"
OUTPUT_VARIABLE _cffi_ext_suffix
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _cffi_ext_suffix)
set(_cffi_ext_suffix ".so")
endif()

if(NOT _cffi_status)
set(CFFI ${_cffi_location} CACHE STRING "Location of Python CFFI")
# --- Decide abi3 alias suffix by platform (Python modules are .so on macOS)
if(WIN32)
set(OQP_ABI3_SUFFIX ".pyd")
elseif(APPLE)
set(OQP_ABI3_SUFFIX ".so")
else()
set(OQP_ABI3_SUFFIX ".so")
endif()

# --- CFFI discovery using the chosen interpreter
execute_process(
COMMAND
${Python3_EXECUTABLE} "-c" "import cffi; print(cffi.__version__)"
OUTPUT_VARIABLE _cffi_version
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND "${Python_EXECUTABLE}" "-c"
"import re, cffi; print(re.compile('/__init__.py.*').sub('', cffi.__file__))"
RESULT_VARIABLE _cffi_status
OUTPUT_VARIABLE _cffi_location
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _cffi_status)
set(CFFI "${_cffi_location}" CACHE STRING "Location of Python CFFI")
endif()

execute_process(
COMMAND
${Python3_EXECUTABLE} "-c" "from distutils.sysconfig import get_config_var; print(get_config_var('EXT_SUFFIX'))"
OUTPUT_VARIABLE _cffi_ext_suffix
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND "${Python_EXECUTABLE}" "-c" "import cffi; print(cffi.__version__)"
OUTPUT_VARIABLE _cffi_version
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

#include(FindPackageHandleStandardArgs)
#find_package_handle_standard_args(CFFI
# FOUND_VAR CFFI_FOUND
# REQUIRED_VARS CFFI
# VERSION_VAR _cffi_version
# )

# --- Build the CFFI extension (OUTPUT must match the real filename)
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}
COMMAND
${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/oqp_cffi_build.py -I ${CMAKE_CURRENT_SOURCE_DIR}/../include
-L ${CMAKE_CURRENT_BINARY_DIR}/../source
-loqp
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/oqp_cffi_build.py
${CMAKE_CURRENT_SOURCE_DIR}/../include/oqp.h
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}"
COMMAND "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/oqp_cffi_build.py"
-I "${CMAKE_CURRENT_SOURCE_DIR}/../include"
-L "${CMAKE_CURRENT_BINARY_DIR}/../source"
-loqp
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/oqp_cffi_build.py"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/oqp.h"
)

if (WIN32)
set(OQP_ABI3_SUFFIX ".dll")
elseif(UNIX)
set(OQP_ABI3_SUFFIX ".so")
endif()

# --- Copy from the built filename to the abi3 alias once
add_custom_target(liboqp
ALL
COMMAND
${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}
${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${OQP_ABI3_SUFFIX}
#${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${CMAKE_SHARED_LIBRARY_SUFFIX}
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}
ALL
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}"
"${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${OQP_ABI3_SUFFIX}"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}"
)

# Ensure the core library is built before the Python module copy
add_dependencies(liboqp oqp)

get_filename_component(OQP_INSTALL ${CMAKE_INSTALL_PREFIX} ABSOLUTE)
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/oqp.sh ${CMAKE_CURRENT_BINARY_DIR}/oqp.sh @ONLY)
#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/oqp_dl-find.sh ${CMAKE_CURRENT_BINARY_DIR}/oqp_dl-find.sh @ONLY)

# --- Install the abi3 alias
install(
#FILES ${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${CMAKE_SHARED_LIBRARY_SUFFIX}
FILES ${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${OQP_ABI3_SUFFIX}
#FILES ${CMAKE_CURRENT_BINARY_DIR}/_oqp${_cffi_ext_suffix}
DESTINATION lib
FILES "${CMAKE_CURRENT_BINARY_DIR}/_oqp.abi3${OQP_ABI3_SUFFIX}"
DESTINATION lib
)

#install(
#PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/oqp/oqp_runner.py ${CMAKE_CURRENT_SOURCE_DIR}/oqp_nac.py
# DESTINATION bin
#)

#install(
# PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/oqp_runner.py ${CMAKE_CURRENT_SOURCE_DIR}/oqp_dl-find.py ${CMAKE_CURRENT_BINARY_DIR}/oqp.sh ${CMAKE_CURRENT_BINARY_DIR}/oqp_dl-find.sh
# DESTINATION bin
#)

#install(
# DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
# DESTINATION lib/oqp
#)

INSTALL(
DIRECTORY ${CMAKE_SOURCE_DIR}/basis_sets/
DESTINATION share/basis_sets
Expand Down
2 changes: 1 addition & 1 deletion pyoqp/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
'numpy>=1.20.0',
'scipy>=1.10.0',
'libdlfind>=0.0.3',
# 'dftd4>=3.5.0',
'dftd4>=3.5.0',
'cffi>=1.16.0',
'mpi4py>=4.0.0',
'basis_set_exchange'
Expand Down
Loading