Skip to content

Commit

Permalink
Add wheels
Browse files Browse the repository at this point in the history
  • Loading branch information
isuruf committed Mar 11, 2024
1 parent 8dfb41f commit 24c9018
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 26 deletions.
73 changes: 73 additions & 0 deletions recipe/0001-wheels.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
From 20d1d14ed17e5e6e2badfe94b08bac53a59fc5eb Mon Sep 17 00:00:00 2001
From: Isuru Fernando <[email protected]>
Date: Fri, 8 Mar 2024 08:56:04 -0600
Subject: [PATCH] wheels

---
wrappers/python/CMakeLists.txt | 2 ++
wrappers/python/openmm-cuda/setup.py | 12 ++++++++++++
wrappers/python/setup.py | 4 +++-
3 files changed, 17 insertions(+), 1 deletion(-)
create mode 100644 wrappers/python/openmm-cuda/setup.py

diff --git a/wrappers/python/CMakeLists.txt b/wrappers/python/CMakeLists.txt
index 5e8355cad..16ed4d4a6 100644
--- a/wrappers/python/CMakeLists.txt
+++ b/wrappers/python/CMakeLists.txt
@@ -294,6 +294,8 @@ else()
endif()
configure_file(pysetup.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/pysetupinstall.cmake" @ONLY)
+configure_file(openmm-cuda/setup.py
+ "${OPENMM_PYTHON_STAGING_DIR}/openmm-cuda/setup.py" @ONLY)
add_custom_target(PythonInstall
COMMAND ${CMAKE_COMMAND}
-P "${CMAKE_CURRENT_BINARY_DIR}/pysetupinstall.cmake"
diff --git a/wrappers/python/openmm-cuda/setup.py b/wrappers/python/openmm-cuda/setup.py
new file mode 100644
index 000000000..82d74ad7a
--- /dev/null
+++ b/wrappers/python/openmm-cuda/setup.py
@@ -0,0 +1,12 @@
+from setuptools import setup, find_packages
+
+cuda_ver = r"@CUDAToolkit_VERSION@"
+cuda_vers = cuda_ver.split(".")
+
+cuda_ver = cuda_vers[0] if int(cuda_vers[0]) > 11 else ".".join(cuda_vers[:2])
+
+setup(
+ name=f"openmm-cuda",
+ version=f"@OPENMM_VERSION@.{cuda_ver}",
+ packages=find_packages(),
+)
diff --git a/wrappers/python/setup.py b/wrappers/python/setup.py
index d2a147065..4cbac13a8 100644
--- a/wrappers/python/setup.py
+++ b/wrappers/python/setup.py
@@ -85,12 +85,13 @@ def writeVersionPy(filename="openmm/version.py", major_version_num=MAJOR_VERSION

cnt = """
# THIS FILE IS GENERATED FROM OPENMM SETUP.PY
+import os
short_version = '%(version)s'
version = '%(version)s'
full_version = '%(full_version)s'
git_revision = '%(git_revision)s'
release = %(isrelease)s
-openmm_library_path = r'%(path)s'
+openmm_library_path = os.path.join(os.path.dirname(__file__), "..", "OpenMM.libs", "lib")

if not release:
version = full_version
@@ -164,6 +165,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
(through custom forces and integrators), openness, and high performance
(especially on recent GPUs) that make it truly unique among simulation codes.
"""
+ setupKeywords["extras_require"] = {"cuda12": f"openmm-cuda=={__version__}.12", "cuda11.2": f"openmm-cuda=={__version__}.11.2"}

define_macros = [('MAJOR_VERSION', major_version_num),
('MINOR_VERSION', minor_version_num)]
--
2.42.0

98 changes: 73 additions & 25 deletions recipe/build_openmm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,40 +46,88 @@ elif [[ "$target_platform" == osx* ]]; then
# /System/Library/Frameworks/OpenCL.framework/OpenCL
fi

# Set location for FFTW3 on both linux and mac
CMAKE_FLAGS+=" -DFFTW_INCLUDES=${PREFIX}/include/"
CMAKE_FLAGS+=" -DFFTW_LIBRARY=${PREFIX}/lib/libfftw3f${SHLIB_EXT}"
CMAKE_FLAGS+=" -DFFTW_THREADS_LIBRARY=${PREFIX}/lib/libfftw3f_threads${SHLIB_EXT}"
# Disambiguate swig location
CMAKE_FLAGS+=" -DSWIG_EXECUTABLE=$(which swig)"

if [[ "$target_platform" == linux-* ]]; then
export LDFLAGS="$LDFLAGS -static-libstdc++ -Wl,--exclude-libs,ALL -Wl,-rpath,$ORIGIN/../OpenMM.libs/lib"
fi

# Build in subdirectory and install.
mkdir -p build
cd build
cmake ${CMAKE_FLAGS} ${SRC_DIR}
make -j$CPU_COUNT
make -j$CPU_COUNT install PythonInstall
make install

# Put examples into an appropriate subdirectory.
mkdir -p ${PREFIX}/share/openmm/
mv ${PREFIX}/examples ${PREFIX}/share/openmm/
cd python
rm -rf dist
rm -rf fixed_wheels
export OPENMM_LIB_PATH=$PREFIX/lib
export OPENMM_INCLUDE_PATH=$PREFIX/include
$PYTHON -m pip wheel . --wheel-dir=dist

# Fix some overlinking warnings/errors
for lib in ${PREFIX}/lib/plugins/*${SHLIB_EXT}; do
ln -s $lib ${PREFIX}/lib/$(basename $lib) || true
# vendor include directories and libraries
for whl in $PWD/dist/*.whl; do
pushd $PREFIX
plugins=""
for plugin in lib/plugins/*.so; do
if [[ "$plugin" != *CUDA.so ]]; then
plugins="$plugins $plugin"
fi
done
$BUILD_PREFIX/bin/python $RECIPE_DIR/vendor_wheel.py $whl include/openmm include/lepton lib/libOpenMM.so lib/libOpenMM.so.8.1 lib/libOpenMMRPMD.so lib/libOpenMMAmoeba.so lib/libOpenMMDrude.so $plugins
popd
done

if [[ "$with_test_suite" == "true" ]]; then
mkdir -p ${PREFIX}/share/openmm/tests/
# BSD find vs GNU find: -executable is only available in GNU find
# +0111 is somehow equivalent in BSD, but that's not compatible in GNU
# so we use different commands for each...
if [[ "$target_platform" == osx* ]]; then
find . -name "Test*" -perm +0111 -type f \
-exec python $RECIPE_DIR/patch_osx_tests.py "{}" \; \
-exec cp "{}" $PREFIX/share/openmm/tests/ \;
else
find . -name "Test*" -executable -type f -exec cp "{}" $PREFIX/share/openmm/tests/ \;
fi
cp -r python/tests $PREFIX/share/openmm/tests/python
fi
function repair() {
# Repair the wheels in dist
if [[ "$target_platform" == linux-64 ]]; then
rm -rf $PREFIX/lib/libstdc++.*
rm -rf $PREFIX/lib/libgcc*
auditwheel repair dist/*.whl -w $PWD/fixed_wheels --plat manylinux2014_x86_64 --exclude libOpenMM.so.8.1 --exclude libOpenMMOpenCL.so --exclude libOpenMMDrude.so --exclude libOpenMMAmoeba.so --exclude libOpenMMRPMD.so --exclude libOpenCL.so.1 --exclude libcuda.so.1 --exclude libcufft.so.11 --exclude libnvrtc.so.12 --exclude libcufft.so.10 --exclude libnvrtc.so.11.2 --lib-sdir=$LIB_SDIR
elif [[ "$target_platform" == linux-* ]]; then
rm -rf $PREFIX/lib/libstdc++.*
rm -rf $PREFIX/lib/libgcc*
auditwheel repair dist/*.whl -w $PWD/fixed_wheels --plat manylinux2014_$ARCH
else
python -m pip install "https://github.com/isuruf/delocate/archive/sanitize_rpaths2.tar.gz#egg=delocate"
python $(which delocate-wheel) -w fixed_wheels --sanitize-rpaths -v dist/*.whl
fi
}

LIB_SDIR=".libs/lib" repair
rm -rf dist
mkdir dist
for whl in fixed_wheels/*.whl; do
whl_tag="${whl##*-}"
done

pushd openmm-cuda
$PYTHON -m pip wheel .
for whl in $PWD/*.whl; do
whl_name=$(basename $whl)
whl_name="${whl_name::${#whl_name}-7}$whl_tag"
pushd $PREFIX
$BUILD_PREFIX/bin/python $RECIPE_DIR/vendor_wheel.py $whl lib/plugins/libOpenMMCUDA.so
popd
cp $whl ../dist/$whl_name
done
popd
LIB_SDIR=".libs" repair

# Copy the wheel to destination
for whl in fixed_wheels/*.whl; do
if [[ "$build_platform" == "osx-"* ]]; then
WHL_DEST=$RECIPE_DIR/../build_artifacts/pypi_wheels
elif [[ "$build_platform" == "linux-"* ]]; then
WHL_DEST=/home/conda/feedstock_root/build_artifacts/pypi_wheels
fi
mkdir -p $WHL_DEST
cp $whl $WHL_DEST
done

# Install the wheel
for whl in fixed_wheels/*.whl; do
$PYTHON -m pip install $whl
done
1 change: 0 additions & 1 deletion recipe/conda_build_config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
opencl_impl: # [osx]
- apple # [osx]
- khronos # [osx]
channel_targets:
- conda-forge main
MACOSX_SDK_VERSION: # [osx and x86_64]
Expand Down
10 changes: 10 additions & 0 deletions recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package:
source:
git_url: https://github.com/openmm/{{ name }}.git
git_rev: "ec797ac"
patches:
- 0001-wheels.patch

build:
number: {{ build }}
Expand Down Expand Up @@ -58,9 +60,17 @@ requirements:
- m2-findutils # [win]
- m2-coreutils # [win]
{% endif %}
# START WHEEL CHANGES
- auditwheel # [linux]
- setuptools # [linux]
- unzip # [unix]
- patchelf # [linux]
- delocate
# END WHEEL CHANGES

host:
- python
- pip
- swig
- pthread-stubs
- lxml
Expand Down
27 changes: 27 additions & 0 deletions recipe/recipe-scripts-license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
BSD-3-Clause license
Copyright (c) 2015-2022, conda-forge contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
32 changes: 32 additions & 0 deletions recipe/vendor_wheel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import sys
from os.path import join as pjoin
import os
import shutil
from glob import glob
import tempfile
import subprocess

from delocate import wheeltools

cwd = os.getcwd()

def add_library(lib_paths, wheel_name):
print('Processing', wheel_name)
with wheeltools.InWheel(wheel_name, wheel_name):
for lib_path in lib_paths:
d = os.path.dirname(pjoin('OpenMM.libs', lib_path))
os.makedirs(d, exist_ok=True)
f = pjoin(cwd, lib_path)
if os.path.isdir(f):
shutil.copytree(f, pjoin('OpenMM.libs', lib_path), dirs_exist_ok=True)
else:
shutil.copy2(f, pjoin('OpenMM.libs', lib_path))

def main():
args = list(sys.argv)
args.pop(0)
dist_path = args.pop(0)
add_library(args, dist_path)

if __name__ == '__main__':
main()

0 comments on commit 24c9018

Please sign in to comment.