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

Prepare for Alfalfa 0.8.0 #4

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
context: .
push: true
target: alfalfa-dependencies
platforms: linux/amd64,linux/arm64
platforms: linux/amd64, linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.output.labels }}
cache-from: type=gha
Expand Down
191 changes: 27 additions & 164 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG PYTHON_VERSION=3.10.14
ARG PYTHON_VERSION=3.12.2
ARG DEBIAN_VERSION=bookworm

# Build modelica-dependencies on bullseye (this uses an older version of GLibc which allows for making manylinux wheels)
Expand All @@ -8,9 +8,6 @@ ARG ASSIMULO_VERSION=3.5.2
RUN apt-get update \
&& apt-get install -y \
cmake \
liblapack-dev \
libsuitesparse-dev \
libhypre-dev \
curl \
git \
build-essential \
Expand All @@ -26,41 +23,12 @@ RUN python3 -m pip install \
auditwheel \
patchelf

RUN gnuArch="$(dpkg-architecture --query DEB_HOST_MULTIARCH)"; \
ln -s /usr/lib/$gnuArch/libblas.so /usr/lib/$gnuArch/libblas_OPENMP.so

WORKDIR /build

RUN curl -fSsL https://portal.nersc.gov/project/sparse/superlu/superlu_mt_3.1.tar.gz | tar xz \
&& cd SuperLU_MT_3.1 \
&& make CFLAGS="-O2 -fPIC -fopenmp" BLASLIB="-lblas" PLAT="_OPENMP" MPLIB="-fopenmp" lib -j1 \
&& cp -v ./lib/libsuperlu_mt_OPENMP.a /usr/lib \
&& cp -v ./SRC/*.h /usr/include

RUN git clone --depth 1 -b ${SUNDIALS_VERSION} https://github.com/LLNL/sundials.git \
&& cd sundials \
&& mkdir build && cd build \
&& cmake \
-LAH \
-DSUPERLUMT_BLAS_LIBRARIES=blas \
-DSUPERLUMT_LIBRARIES=blas \
-DSUPERLUMT_INCLUDE_DIR=/usr/include \
-DSUPERLUMT_LIBRARY=/usr/lib/libsuperlu_mt_OPENMP.a \
-DSUPERLUMT_THREAD_TYPE=OpenMP \
-DCMAKE_INSTALL_PREFIX=/usr \
-DSUPERLUMT_ENABLE=ON \
-DSUNDIALS_INDEX_SIZE=32 \
-DLAPACK_ENABLE=ON \
-DEXAMPLES_ENABLE=OFF \
-DEXAMPLES_ENABLE_C=OFF \
.. \
&& make -j4 \
&& make install

RUN gnuArch="$(dpkg-architecture --query DEB_HOST_MULTIARCH)" \
&& git clone --depth 1 -b Assimulo-3.5.2 https://github.com/modelon-community/Assimulo.git \
&& cd Assimulo \
&& python3 setup.py bdist_wheel --sundials-home=/usr --blas-home=/usr/lib/${gnuArch} --lapack-home=/usr/lib/${gnuArch} --superlu-home=/usr \
&& python3 setup.py bdist_wheel \
&& auditwheel repair --plat manylinux_2_31_$(uname -m) build/dist/*.whl \
&& pip3 install wheelhouse/*.whl

Expand All @@ -70,12 +38,13 @@ RUN git clone --depth 1 -b 2.4.1 https://github.com/modelon-community/fmi-librar
&& mkdir fmi_build && cd fmi_build \
&& mkdir fmi_library \
&& cmake -DCMAKE_INSTALL_PREFIX=/build/fmi-libary/fmi_library .. \
&& make -j4 \
&& make -j$(nproc) \
&& make install

RUN git clone --depth 1 -b PyFMI-2.13.1 https://github.com/modelon-community/PyFMI.git \
RUN git clone --depth 1 -b PyFMI-2.14.0 https://github.com/modelon-community/PyFMI.git \
&& cd PyFMI \
&& python3 setup.py bdist_wheel --fmil-home=/build/fmi-libary/fmi_library --with-openmp\
&& python3 setup.py build --fmil-home=/build/fmi-libary/fmi_library -j $(nproc)\
&& python3 setup.py bdist_wheel --fmil-home=/build/fmi-libary/fmi_library\
&& auditwheel repair --plat manylinux_2_31_$(uname -m) dist/*.whl

WORKDIR /artifacts
Expand All @@ -90,131 +59,25 @@ RUN gnuArch="$(dpkg-architecture --query DEB_HOST_ARCH_CPU)"\
&& curl -SfL https://archive.debian.org/debian/pool/main/g/gcc-6/libgfortran3_6.3.0-18+deb9u1_${gnuArch}.deb -o libgfortran3.deb

FROM python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS energyplus-dependencies
ARG OPENSTUDIO_VERSION=3.8.0
ARG OPENSTUDIO_VERSION_SHA=f953b6fcaf
ARG ENERGYPLUS_VERSION=24.1.0
ARG ENERGYPLUS_VERSION_SHA=9d7789a3ac
ARG OPENSTUDIO_VERSION=3.9.0
ARG OPENSTUDIO_VERSION_SHA=c77fbb9569
ARG ENERGYPLUS_VERSION=24.2.0
ARG ENERGYPLUS_VERSION_SHA=94a887817b

RUN apt-get update \
&& apt-get install -y \
curl \
binutils \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /artifacts

RUN export gnuArch=x86_64; if [ "$(uname -m)" = "aarch64" ]; then gnuArch=arm64; fi; export gnuArch \
&& echo https://github.com/NREL/EnergyPlus/releases/download/v${ENERGYPLUS_VERSION}/EnergyPlus-${ENERGYPLUS_VERSION}-${ENERGYPLUS_VERSION_SHA}-Linux-Ubuntu22.04-${gnuArch}.tar.gz \
&& curl -SfL https://github.com/NREL/EnergyPlus/releases/download/v${ENERGYPLUS_VERSION}/EnergyPlus-${ENERGYPLUS_VERSION}-${ENERGYPLUS_VERSION_SHA}-Linux-Ubuntu22.04-${gnuArch}.tar.gz -o energyplus.tar.gz \
&& curl -SfL https://github.com/NREL/OpenStudio/releases/download/v${OPENSTUDIO_VERSION}/OpenStudio-${OPENSTUDIO_VERSION}+${OPENSTUDIO_VERSION_SHA}-Ubuntu-22.04-${gnuArch}.deb -o openstudio.deb \
&& curl -SfL https://openstudio-resources.s3.amazonaws.com/bcvtb-linux.tar.gz -o bcvtb.tar.gz

FROM python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS dual-python
RUN set -eux; \
export gnuArch=x86_64; if [ "$(uname -m)" = "aarch64" ]; then gnuArch=arm64; fi; export gnuArch; \
curl -SfL https://github.com/NREL/EnergyPlus/releases/download/v${ENERGYPLUS_VERSION}a/EnergyPlus-${ENERGYPLUS_VERSION}-${ENERGYPLUS_VERSION_SHA}-Linux-Ubuntu22.04-${gnuArch}.tar.gz -o energyplus.tar.gz; \
curl -SfL https://github.com/NREL/OpenStudio/releases/download/v${OPENSTUDIO_VERSION}/OpenStudio-${OPENSTUDIO_VERSION}+${OPENSTUDIO_VERSION_SHA}-Ubuntu-22.04-${gnuArch}.deb -o openstudio.deb

ENV PYTHON_VERSION=3.8.19
ENV GPG_KEY=E3FF2839C048B25C084DEBE9B26995E310250568

RUN set -eux; \
\
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends \
dpkg-dev \
gcc \
gnupg \
libbluetooth-dev \
libbz2-dev \
libc6-dev \
libdb-dev \
libexpat1-dev \
libffi-dev \
libgdbm-dev \
liblzma-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
make \
tk-dev \
uuid-dev \
wget \
xz-utils \
zlib1g-dev \
; \
\
wget -O python.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz"; \
wget -O python.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc"; \
GNUPGHOME="$(mktemp -d)"; export GNUPGHOME; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$GPG_KEY"; \
gpg --batch --verify python.tar.xz.asc python.tar.xz; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME" python.tar.xz.asc; \
mkdir -p /usr/src/python; \
tar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \
rm python.tar.xz; \
\
cd /usr/src/python; \
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
./configure \
--build="$gnuArch" \
--enable-loadable-sqlite-extensions \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
--with-system-expat \
--without-ensurepip \
; \
nproc="$(nproc)"; \
EXTRA_CFLAGS="$(dpkg-buildflags --get CFLAGS)"; \
LDFLAGS="$(dpkg-buildflags --get LDFLAGS)"; \
LDFLAGS="${LDFLAGS:--Wl},--strip-all"; \
make -j "$nproc" \
"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \
"LDFLAGS=${LDFLAGS:-}" \
"PROFILE_TASK=${PROFILE_TASK:-}" \
; \
# https://github.com/docker-library/python/issues/784
# prevent accidental usage of a system installed libpython of the same version
rm python; \
make -j "$nproc" \
"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}" \
"LDFLAGS=${LDFLAGS:--Wl},-rpath='\$\$ORIGIN/../lib'" \
"PROFILE_TASK=${PROFILE_TASK:-}" \
python \
; \
make altinstall; \
\
cd /; \
rm -rf /usr/src/python; \
\
find /usr/local -depth \
\( \
\( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \
-o \( -type f -a \( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \) \) \
-o \( -type f -a -name 'wininst-*.exe' \) \
\) -exec rm -rf '{}' + \
; \
\
ldconfig; \
\
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \
| awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -r apt-mark manual \
; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \
\
python3.8 --version

RUN python3.8 -m ensurepip --altinstall


FROM dual-python AS alfalfa-dependencies
FROM python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION} AS alfalfa-dependencies

ENV ENERGYPLUS_DIR=/usr/local/EnergyPlus
ENV HOME=/alfalfa
Expand All @@ -223,30 +86,31 @@ WORKDIR /artifacts

# Install EnergyPlus
RUN --mount=type=bind,from=energyplus-dependencies,source=/artifacts,target=/artifacts set -eux; \
mkdir ${ENERGYPLUS_DIR}; \
mkdir -p ${ENERGYPLUS_DIR}; \
tar -C $ENERGYPLUS_DIR/ --strip-components=1 -xzf energyplus.tar.gz; \
cd ${ENERGYPLUS_DIR}; \
cp -n -r ${ENERGYPLUS_DIR}/python_lib/* /usr/local/lib/python3.12; \
rm -rf \
ExampleFiles \
DataSets \
Documentation \
MacroDataSets \
python_standard_lib \
python_lib \
WeatherData \
libpython3.8.so.1.0 \
libpython3.12.so.1.0 \
; \
ln -s $ENERGYPLUS_DIR/energyplus /usr/local/bin/; \
ln -s $ENERGYPLUS_DIR/ExpandObjects /usr/local/bin/; \
ln -s $ENERGYPLUS_DIR/runenergyplus /usr/local/bin/; \
ln -s /usr/local/lib/python3.8 ${ENERGYPLUS_DIR}/python_standard_lib; \
ln -s /usr/local/lib/libpython3.8.so.1.0 ${ENERGYPLUS_DIR}/libpython3.8.so.1.0
ln -s /usr/local/lib/python3.12 ${ENERGYPLUS_DIR}/python_lib; \
ln -s /usr/local/lib/libpython3.12.so.1.0 ${ENERGYPLUS_DIR}/libpython3.12.so.1.0

# Install OpenStudio
RUN --mount=type=bind,from=energyplus-dependencies,source=/artifacts,target=/artifacts set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
gdebi-core \
openjdk-17-jre-headless \
binutils \
; \
gdebi -o "APT::Install-Recommends=0" -n openstudio.deb; \
cd /usr/local/openstudio*; \
Expand All @@ -258,15 +122,16 @@ RUN --mount=type=bind,from=energyplus-dependencies,source=/artifacts,target=/art
ln -s ${ENERGYPLUS_DIR} EnergyPlus; \
apt-get purge -y \
gdebi-core \
binutils \
; \
apt-get autoremove -y; \
rm -rf /var/lib/apt/lists/*


# Install Assimulo, PyFMI and Old Fortran Libraries
RUN --mount=type=bind,from=modelica-dependencies,source=/artifacts,target=/artifacts set -eux; \
python3.10 -m pip install 'numpy>=1.19.5' 'scipy>=1.10.1' 'matplotlib>3'; \
python3.10 -m pip install --no-deps Assimulo*.whl PyFMI*.whl; \
python3.12 -m pip install 'numpy>=1.19.5' 'scipy>=1.10.1' 'matplotlib>3'; \
python3.12 -m pip install --no-deps Assimulo*.whl PyFMI*.whl; \
pip3 cache purge; \
apt-get update; \
apt-get install -y --no-install-recommends \
Expand All @@ -283,7 +148,5 @@ RUN --mount=type=bind,from=modelica-dependencies,source=/artifacts,target=/artif
apt-get autoremove -y; \
rm -rf /var/lib/apt/lists/*

ENV PYTHONPATH="${ENERGYPLUS_DIR}:/usr/local/openstudio-3.9.0/Python"
WORKDIR $HOME

# Only the xml lib component of bcvtb is actaully required for communication, so we just extract that to save space
RUN --mount=type=bind,from=energyplus-dependencies,source=/artifacts,target=/artifacts tar -xzf /artifacts/bcvtb.tar.gz bcvtb/lib/xml
Loading