Skip to content

make psi4 --version faster (#3064) #1

make psi4 --version faster (#3064)

make psi4 --version faster (#3064) #1

Workflow file for this run

name: Eco
on:
push:
branches:
- master
pull_request:
merge_group:
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
ecosystem:
strategy:
fail-fast: true
matrix:
cfg:
- runs-on: ubuntu-latest
python-version: "3.10"
mkl-version: ""
base-channel: "conda-forge"
pytest-marker-expr: "addon and not long"
cmargs: >
-D CMAKE_VERBOSE_MAKEFILE=OFF
-D BUILD_SHARED_LIBS=ON
- runs-on: macos-latest
python-version: "3.9"
mkl-version: ""
base-channel: "conda-forge"
pytest-marker-expr: "addon and not long"
target-sdk: "10.10"
cmargs: >
-D CMAKE_VERBOSE_MAKEFILE=OFF
-D BUILD_SHARED_LIBS=ON
-D OpenMP_C_FLAG="-fopenmp=libiomp5"
-D OpenMP_CXX_FLAG="-fopenmp=libiomp5"
# Notes:
# * libiomp5 is picking up naturally but left explicit as guide
- runs-on: windows-latest
python-version: "3.9"
mkl-version: "=2022.1"
base-channel: "conda-forge"
pytest-marker-expr: "addon and not long and not d2ints"
cmargs: >
-D CMAKE_VERBOSE_MAKEFILE=OFF
-D BUILD_SHARED_LIBS=OFF
-D CMAKE_CXX_FLAGS="/arch:AVX /wd4018 /wd4101 /wd4996"
-D OpenMP_LIBRARY_DIRS="D:\a\psi4\psi4\iomp5md\conda\win\2019.1"
-D psi4_SKIP_ENABLE_Fortran=ON
# Notes:
# * See mkl-version notes at end
# * "not d2ints" allows Windows accessing c-f L2 to pass
name: "Eco • 🐍 ${{ matrix.cfg.python-version }} • ${{ matrix.cfg.runs-on }}"
runs-on: ${{ matrix.cfg.runs-on }}
defaults:
run:
shell: bash -l {0}
steps:
# fetch-depth: 0 gets git history so Psi4 version is computable
- name: Checkout Psi4
uses: actions/checkout@v2
with:
fetch-depth: 0
# see CMAKE_OSX_SYSROOT and CMAKE_Fortran_FLAGS for use
# mac_ver line returns, e.g., "10.15" for Catalina & "11.6" for Big Sur. but phracker doesn't support all minor, so some logic to hardcode.
- name: Prepare compiler environment, SDK (M)
if: runner.os == 'macOS'
run: |
macos_Mm=$(SYSTEM_VERSION_COMPAT=0 python -c "import platform; Mmp = platform.mac_ver()[0]; Mm = '.'.join(Mmp.split('.')[:2]); print(Mm)")
macos_M=$(SYSTEM_VERSION_COMPAT=0 python -c "import platform; Mmp = platform.mac_ver()[0]; M = '.'.join(Mmp.split('.')[:1]); print(M)")
echo $macos_Mm $macos_M
if [[ "${macos_M}" == "11" ]]; then
macos_Mm=11.3
elif [[ "${macos_M}" == "12" ]]; then
# until phracker merges and releases 12 via https://github.com/phracker/MacOSX-SDKs/pull/44
macos_Mm=11.3
fi
echo $macos_Mm
curl -L https://github.com/phracker/MacOSX-SDKs/releases/download/${macos_Mm}/MacOSX${{ matrix.cfg.target-sdk }}.sdk.tar.xz | sudo tar xf - -C /opt/
# equivalent to `call vcvarsall.bat x64`. see Azure script to follow cmdline.
- name: Prepare compiler environment, vcvarsall (W)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
# see OpenMP_LIBRARY_DIRS for use
- name: Prepare OpenMP build environment, libiomp5md.lib (W)
if: runner.os == 'Windows'
run: git clone https://github.com/psi4/iomp5md.git
- name: Write Conda environment files
run: |
#
# Buildtime (L, M, W)
#
cat > build.yaml <<EOF
name: baseenv
channels:
- ${{ matrix.cfg.base-channel }}
- nodefaults
dependencies:
- libblas=*=*mkl
- python=${{ matrix.cfg.python-version }}
# build
- boost-cpp
- cmake
- c-compiler
- cxx-compiler
- eigen
- fortran-compiler
- llvm-openmp
- mkl-devel${{ matrix.cfg.mkl-version }}
- ninja
- numpy
- pybind11
- pydantic<2.0
# qc req'd
- gau2grid
- conda-forge/label/libint_dev::libint=2.7.3dev1
- optking
- qcelemental
- qcengine
- libxc-c
# qc opt'l
# - psi4/label/dev::ambit
# - psi4/label/dev::chemps2
# - psi4/label/dev::libecpint
- dkh
- pygdma
# - psi4/label/dev::pcmsolver
# - psi4/label/dev::simint
# runtime
# pip
# * note that this is the reliable way to patch in dev versions of py deps,
# as internal builds need path adjustments, force removals of conda version,
# and can still be insufficient for qcfractal.
#- pip
#- pip:
# - git+https://github.com/loriab/[email protected]
EOF
if [[ "${{ runner.os }}" == "Linux" ]]; then
:
# sed -i "s;;;g" build.yaml
fi
if [[ "${{ runner.os }}" == "macOS" ]]; then
:
# sed -E -i.bak "s;;;g" build.yaml
fi
if [[ "${{ runner.os }}" == "Windows" ]]; then
sed -i "s;- fortran-compiler;;g" build.yaml
sed -i "s;- llvm-openmp;- intel-openmp;g" build.yaml
fi
#
# Runtime for single-channel (L, M, W)
#
cat > run.yaml <<EOF
name: baseenv
channels:
- ${{ matrix.cfg.base-channel }}
- nodefaults
dependencies:
# non-qc req'd
- libblas=*=*mkl
- mkl${{ matrix.cfg.mkl-version }}
- msgpack-python
- networkx
- numpy
- python=${{ matrix.cfg.python-version }}
- scipy
- toml
- pydantic<2.0
# non-qc opt'l
- memory_profiler
# qc req'd
- gau2grid
- conda-forge/label/libint_dev::libint=2.7.3dev1
- optking
- qcelemental
- qcengine
- libxc-c
# qc req'd from buildtime
#- psi4/label/dev::ambit
#- psi4/label/dev::chemps2
- dkh
#- psi4/label/dev::libecpint
- pygdma
#- psi4/label/dev::pcmsolver
#- psi4/label/dev::simint
# qc opt'l
- adcc
- basis_set_exchange
- cppe
- dftd3-python
- dftd4-python
- pylibefp
#- psi4/label/dev::fockci
- gcp-correction
- geometric
#- psi4/label/dev::mp2d
- openfermion>=1.0
- openfermionpsi4
- pyddx
- pymdi
- qcfractal
- qcportal
#- psi4/label/dev::resp
#- psi4/label/dev::snsmp2
- tomli
# test
- pytest
- pytest-xdist
# pip
- pip
- pip:
- git+https://github.com/i-pi/i-pi.git@master-py3
#- git+https://github.com/loriab/[email protected]
# toml needed for psi4 to load parameters from dftd4-python
# one of mkl=${{ matrix.cfg.mkl-version }} or mkl-devel=${{ matrix.cfg.mkl-version }} needed to avoid DLL runtime error
EOF
if [[ "${{ runner.os }}" == "Linux" ]]; then
sed -i "s;- qcfractal;- qcarchive/label/next::qcfractal;g" run.yaml # >=0.50b10
sed -i "s;- qcportal;- postgresql;g" run.yaml
fi
if [[ "${{ runner.os }}" == "macOS" ]]; then
sed -E -i.bak "s;- qcfractal;- qcfractal=0.15.8.1;g" run.yaml
sed -E -i.bak "s;- qcportal;- qcportal=0.15.8;g" run.yaml
fi
if [[ "${{ runner.os }}" == "Windows" ]]; then
# nyi
sed -i "s;- adcc;;g" run.yaml
sed -i "s;- pyddx;;g" run.yaml
sed -i "s;- cppe;;g" run.yaml
sed -i "s;- qcfractal;;g" run.yaml
sed -i "s;- qcportal;;g" run.yaml
sed -i "s;- openfermion>=1.0;;g" run.yaml
sed -i "s;- openfermionpsi4;;g" run.yaml
sed -i "s;- memory_profiler;;g" run.yaml
fi
printf "\n<<< build.yaml >>>\n"
cat build.yaml
printf "\n<<< run.yaml >>>\n"
cat run.yaml
- name: Setup Conda
uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: baseenv
environment-file: build.yaml
show-channel-urls: true
python-version: ${{ matrix.cfg.python-version }}
auto-activate-base: false
miniforge-variant: Mambaforge
use-mamba: true
add-pip-as-python-dependency: true
channels: conda-forge
- name: Buildtime Conda environment
run: |
mamba info
mamba list
#- name: Switch to Mamba solver (L, M)
# if: matrix.cfg.base-channel != 'conda-forge'
# run: |
# conda install -n base conda-libmamba-solver
# conda config --set solver libmamba
- name: Configure Psi4, Conda defaults GNU (L)
if: runner.os == 'Linux'
run: |
cmake \
-S. \
-B objdir \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=./install \
-D CMAKE_C_COMPILER=${CC} \
-D CMAKE_CXX_COMPILER=${CXX} \
-D CMAKE_Fortran_COMPILER=${FC} \
-D CMAKE_PREFIX_PATH="${CONDA_PREFIX}" \
-D CMAKE_INSIST_FIND_PACKAGE_pybind11=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gau2grid=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libint2=ON \
-D CMAKE_INSIST_FIND_PACKAGE_optking=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcelemental=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcengine=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libxc=ON \
-D ENABLE_ambit=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_ambit=ON \
-D ENABLE_CheMPS2=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_CheMPS2=ON \
-D ENABLE_dkh=ON \
-D CMAKE_INSIST_FIND_PACKAGE_dkh=ON \
-D ENABLE_ecpint=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_ecpint=ON \
-D ENABLE_gdma=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gdma=ON \
-D ENABLE_PCMSolver=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_PCMSolver=OFF \
-D ENABLE_simint=OFF \
-D SIMINT_VECTOR=sse \
-D CMAKE_INSIST_FIND_PACKAGE_simint=ON \
-D ENABLE_v2rdm_casscf=ON \
-D CMAKE_DISABLE_FIND_PACKAGE_v2rdm_casscf=ON \
-D ENABLE_OPENMP=ON \
-D ENABLE_XHOST=OFF \
${{ matrix.cfg.cmargs }}
- name: Configure Psi4, Conda defaults Clang (M)
if: runner.os == 'macOS'
run: |
cmake \
-S. \
-B objdir \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=./install \
-D CMAKE_C_COMPILER=${CC} \
-D CMAKE_CXX_COMPILER=${CXX} \
-D CMAKE_Fortran_COMPILER=${FC} \
-D CMAKE_PREFIX_PATH="${CONDA_PREFIX}" \
-D CMAKE_INSIST_FIND_PACKAGE_pybind11=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gau2grid=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libint2=ON \
-D CMAKE_INSIST_FIND_PACKAGE_optking=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcelemental=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcengine=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libxc=ON \
-D ENABLE_ambit=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_ambit=ON \
-D ENABLE_CheMPS2=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_CheMPS2=ON \
-D ENABLE_dkh=ON \
-D CMAKE_INSIST_FIND_PACKAGE_dkh=ON \
-D ENABLE_ecpint=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_ecpint=ON \
-D ENABLE_gdma=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gdma=ON \
-D ENABLE_PCMSolver=OFF \
-D CMAKE_INSIST_FIND_PACKAGE_PCMSolver=OFF \
-D ENABLE_simint=OFF \
-D SIMINT_VECTOR=sse \
-D CMAKE_INSIST_FIND_PACKAGE_simint=ON \
-D ENABLE_v2rdm_casscf=ON \
-D CMAKE_DISABLE_FIND_PACKAGE_v2rdm_casscf=ON \
-D ENABLE_OPENMP=ON \
-D ENABLE_XHOST=OFF \
-D CMAKE_Fortran_FLAGS="-isysroot /opt/MacOSX${{ matrix.cfg.target-sdk }}.sdk" \
-D CMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.cfg.target-sdk }} \
-D CMAKE_OSX_SYSROOT="/opt/MacOSX${{ matrix.cfg.target-sdk }}.sdk" \
${{ matrix.cfg.cmargs }}
- name: Configure Psi4, LLVM clang-cl (W)
if: runner.os == 'Windows'
run: |
cmake \
-S . \
-B objdir \
-G Ninja \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=./install \
-D CMAKE_C_COMPILER=clang-cl \
-D CMAKE_CXX_COMPILER=clang-cl \
-D CMAKE_PREFIX_PATH="${CONDA_PREFIX}" \
-D CMAKE_INSIST_FIND_PACKAGE_pybind11=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gau2grid=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libint2=ON \
-D CMAKE_INSIST_FIND_PACKAGE_optking=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcelemental=ON \
-D CMAKE_INSIST_FIND_PACKAGE_qcengine=ON \
-D CMAKE_INSIST_FIND_PACKAGE_Libxc=ON \
-D ENABLE_dkh=ON \
-D CMAKE_INSIST_FIND_PACKAGE_dkh=ON \
-D ENABLE_gdma=ON \
-D CMAKE_INSIST_FIND_PACKAGE_gdma=ON \
-D ENABLE_OPENMP=ON \
-D ENABLE_XHOST=OFF \
${{ matrix.cfg.cmargs }}
- name: Compile & Install Psi4
run: cmake --build objdir --config Release --target install -j
- name: Linked dependencies, ldd (L)
if: runner.os == 'Linux'
run: ldd objdir/stage/lib/psi4/core.*.so
- name: Linked dependencies, otool (M)
if: runner.os == 'macOS'
run: otool -L objdir/stage/lib/psi4/core.*.so
- name: Linked dependencies, objdump (W)
if: runner.os == 'Windows'
shell: cmd /C CALL {0}
run: objdump.exe -p objdir\stage\lib\psi4\core.*.pyd | grep dll
# Notes: This is clearing away the whole build environment (to make explicit the build and
# runtime dependencies and addons). Then it's creating a new runtime environment based on
# psi4 and base channel dependencies and addons. This is created at the same environment
# name (so same location on disk as the build env) for non-relocatability reasons.
- name: Runtime Conda environment(s)
run: |
echo "::group::Prepare Environment"
conda deactivate
mamba remove -n baseenv --all
mamba env create --file run.yaml
#if [[ "${{ matrix.cfg.base-channel }}" != "conda-forge" ]]; then
#conda env create --file aux.yaml
#fi
conda activate baseenv
echo "::endgroup::"
mamba info
mamba list -n baseenv
#if [[ "${{ matrix.cfg.base-channel }}" != "conda-forge" ]]; then
#conda list -n auxenv
if [[ "${{ runner.os }}" != "Windows" ]]; then
# on Windows, cmd varies: `qcengine.exe`
qcengine info
fi
- name: Patch QCFractal for Python
if: runner.os == 'macOS'
run: |
cat /Users/runner/miniconda3/envs/baseenv/lib/python${{ matrix.cfg.python-version }}/site-packages/qcfractal/queue/executor_adapter.py
sed -E -i.bak "s;for result in self.queue.values\(\);for result in list(self.queue.values());g" /Users/runner/miniconda3/envs/baseenv/lib/python${{ matrix.cfg.python-version }}/site-packages/qcfractal/queue/executor_adapter.py
cat /Users/runner/miniconda3/envs/baseenv/lib/python${{ matrix.cfg.python-version }}/site-packages/qcfractal/queue/executor_adapter.py
- name: Test OpenMP
working-directory: ./install/lib
run: python -c "from psi4 import core; core.set_num_threads(42); assert core.get_num_threads() == 42"
- name: Test Run, Spot, Run
working-directory: ./objdir
run: |
export PATH=../install/bin:$PATH
#export KMP_DUPLICATE_LIB_OK=TRUE
psi4 ../tests/tu1-h2o-energy/input.dat -o stdout
# step works but is redundant with next two; enable for debugging
- name: Test Addons with CTest
if: false
working-directory: ./objdir
run: ctest -L addon -j2 --output-on-failure
- name: "Test Addons with Pytest, base channel only `-c ${{ matrix.cfg.base-channel }} -c psi4/label/dev` (L, M, W)"
if: matrix.cfg.base-channel == 'conda-forge'
working-directory: ./objdir
# (1st entry PYTHONPATH) need to find the Psi4 module
run: PYTHONPATH=stage/lib pytest --cache-clear -v -rws --durations=50 --durations-min=40 --strict-markers --color yes -n auto -m "${{ matrix.cfg.pytest-marker-expr }}" stage/lib/psi4/tests/
#run: PYTHONPATH=stage/lib pytest --cache-clear -v -rws --durations=50 --durations-min=40 --strict-markers --color yes -n auto -m "addon and not long and not d2ints" stage/lib/psi4/tests/
#- name: "Test Addons with Pytest, base + community channel `-c ${{ matrix.cfg.base-channel }} -c psi4/label/dev -c conda-forge` (L, M)"
# if: matrix.cfg.base-channel != 'conda-forge'
# working-directory: ./objdir
# run: |
# conda activate --stack auxenv
# printenv | grep CONDA_PREFIX
# if [[ "${{ runner.os }}" == "Linux" ]]; then
# # (1st entry) need to find the Psi4 module
# # (2nd entry) Linux needs the baseenv (CONDA_PREFIX_1) to avoid dual OpenMP init since defaults mkl are intel/iomp5 and c-f mkl is llvm/omp
# # (3rd entry) need to find the new addon modules in the auxenv (CONDA_PREFIX; stack activation only merges bin/)
# export PYTHONPATH=stage/lib/:$CONDA_PREFIX_1/lib/python${{ matrix.cfg.python-version }}/site-packages:$CONDA_PREFIX/lib/python${{ matrix.cfg.python-version }}/site-packages
# fi
# if [[ "${{ runner.os }}" == "macOS" ]]; then
# # (1st entry) need to find the Psi4 module
# # (2nd entry) need to find the new addon modules in the auxenv (CONDA_PREFIX; stack activation only merges bin/)
# export PYTHONPATH=stage/lib/:$CONDA_PREFIX/lib/python${{ matrix.cfg.python-version }}/site-packages
# fi
# echo $PYTHONPATH
# pytest --cache-clear -v -rws --durations=50 --durations-min=40 --strict-markers --color yes -n auto -m "addon and not long" stage/lib/psi4/tests/
- name: Write user Conda environment files
run: |
echo "::group::Prepare Environment"
mamba install ruamel_yaml -c ${{ matrix.cfg.base-channel }}
echo "::endgroup::"
cat > userenvs.py <<EOF
from pathlib import Path
from ruamel_yaml import YAML
file1 = Path("build.yaml")
yaml1 = YAML(typ="rt")
yaml1.indent(mapping=2, sequence=4, offset=2)
data1 = yaml1.load(file1)
file2 = Path("run.yaml")
yaml2 = YAML(typ="rt")
data2 = yaml2.load(file2)
for dep in data2["dependencies"]:
if dep not in data1["dependencies"]:
data1["dependencies"].append(dep)
outfile = Path("devtools") / "conda-envs" / "${{ runner.os }}-buildrun-maxeco.yaml"
yaml1.dump(data1, outfile)
EOF
python userenvs.py
cat devtools/conda-envs/${{ runner.os }}-buildrun-maxeco.yaml
#if [[ "${{ matrix.cfg.base-channel }}" != "conda-forge" ]]; then
#cp aux.yaml devtools/conda-envs/${{ runner.os }}-aux-maxeco.yaml
#fi
git diff --color-words
# Notes
# -----
# Error: (W) "OMP: Error #15: Initializing libiomp5md.dll, but found libomp.dll already initialized." or analysis shows linked to libomp.dll
# Soln: feed OpenMP_LIBRARY_DIRS so selects correct libiomp5md.lib so analysis shows linked to libiomp5md.dll
# Error (W) " File "D:\a\psi4\psi4\objdir\stage\lib\psi4\__init__.py", line 55, in <module>
# from . import core
# ImportError: DLL load failed while importing core: The specified module could not be found."
# Soln:
# Have mkl-devel=<mkl-version> -or- mkl=<mkl-version> in runtime environment to match mkl-devel=<mkl-version> in build env.
# Having intel-openmp=<mkl-version> in build and run seems fine but not necessary.
# Error: (W) "DLL load failed while importing _multiarray_umath: The specified module could not be found."
# Soln: Add `C:\tools\miniconda3\Library\mingw-w64\bin` to PATH
# Using Intel's OpenMP on Windows needs libiomp5md.lib (import library) and libiomp5md.dll at buildtime and libiomp5md.dll at runtime.
# No conda package provides libiomp5md.lib, so we stashed one from 2019.1 on GH and clone it here for the build.
# We feed the cloned path to the build via OpenMP_LIBRARY_DIRS. 2019.1 has been the iomp5 version for a long time.
# But by now, only defaults conda channel has a complementary intel-openmp=2019.1 package with the dll.
# In order to update the version and to allow a single channel base, conda-forge, using mkl-version=2021.4 still with that
# same 2019.1 iomp5, and it seems to work fine. Is all this really necessary? I don't know.
# There is another libiomp5md.lib that comes with llvm and lives at "C:\Program Files\LLVM\lib\libiomp5md.lib".
# Attempts to use it quickly fell off the narrow path-of-compilability-and-runability but should be explored again.