From 49f81d3a80f3134250944ee594343fc5012ee039 Mon Sep 17 00:00:00 2001 From: MintoDA1 <51412913+MintoDA1@users.noreply.github.com> Date: Tue, 15 Aug 2023 07:28:39 -0400 Subject: [PATCH] More fixes to build scripts. Pushing for testing --- Dockerfile.Intel | 108 ++++++++++++----- buildscripts/build_all.sh | 48 +++----- buildscripts/build_dependencies.sh | 182 +++++++++++++++-------------- buildscripts/build_swiftest.sh | 82 ++++++------- buildscripts/set_compilers.sh | 125 ++++++++++++++++++++ environment.yml | 3 +- swiftest/simulation_class.py | 98 ++++++++-------- 7 files changed, 409 insertions(+), 237 deletions(-) create mode 100755 buildscripts/set_compilers.sh diff --git a/Dockerfile.Intel b/Dockerfile.Intel index 223cc33d5..653620858 100644 --- a/Dockerfile.Intel +++ b/Dockerfile.Intel @@ -14,51 +14,107 @@ # This build target compiles all dependencies and the swiftest driver itself FROM intel/oneapi-hpckit:2023.1.0-devel-ubuntu20.04 as build-deps -ENV SCRIPT_DIR="buildscripts" SHELL ["/bin/bash", "--login", "-c"] -ENV SHELL="/bin/bash" +ENV INSTALL_DIR=/usr/local WORKDIR /swiftest -# Compile the dependencies -COPY ./${SCRIPT_DIR}/get_platform.sh ./${SCRIPT_DIR}/ -COPY ./${SCRIPT_DIR}/make_build_environment.sh ./${SCRIPT_DIR} -COPY ./${SCRIPT_DIR}/build_dependencies.sh ./${SCRIPT_DIR}/ -COPY ./${SCRIPT_DIR}/swiftest-build-env.yml ./${SCRIPT_DIR}/ -COPY ./${SCRIPT_DIR}/fetch_dependencies.sh ./${SCRIPT_DIR}/ -RUN ${SCRIPT_DIR}/fetch_dependencies.sh -RUN apt-get update && \ - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends m4 && \ - rm -rf /var/lib/apt/lists/* && \ - ${SCRIPT_DIR}/build_dependencies.sh Intel +ENV CC="${ONEAPI_ROOT}/compiler/latest/linux/bin/icx" +ENV FC="${ONEAPI_ROOT}/compiler/latest/linux/bin/ifx" +ENV CXX="${ONEAPI_ROOT}/compiler/latest/linux/bin/icpx" +ENV F77="${FC}" + +ENV INSTALL_DIR=/usr/local +ENV NCDIR="${INSTALL_DIR}" +ENV NFDIR="${INSTALL_DIR}" +ENV HDF5_ROOT="${INSTALL_DIR}" +ENV HDF5_LIBDIR="${HDF5_ROOT}/lib" +ENV HDF5_INCLUDE_DIR="${HDF5_ROOT}/include" +ENV HDF5_PLUGIN_PATH="${HDF5_LIBDIR}/plugin" +ENV LD_LIBRARY_PATH="${INSTALL_DIR}/lib" +ENV LDFLAGS="-L${INSTALL_DIR}/lib" +ENV CPPFLAGS="-I${INSTALL_DIR}/include" + +COPY ./buildscripts/fetch_dependencies.sh ./ +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + m4 && \ + rm -rf /var/lib/apt/lists/* && \ + ./fetch_dependencies.sh -d ./ + +# Get the HDF5, NetCDF-C, and NetCDF-Fortran libraries +RUN cd zlib-* && \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --static && \ + make && make install && \ + cd ../hdf5-* && \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --disable-shared \ + --enable-build-mode=production \ + --disable-fortran \ + --disable-java \ + --disable-cxx \ + --with-zlib=${INSTALL_DIR} && \ + make && make install && \ + cd ../netcdf-c-* && \ + ./configure \ + --prefix=${INSTALL_DIR} \ + --disable-shared \ + --disable-dap \ + --disable-libxml2 \ + --disable-byterange && \ + make && make install +RUN cd netcdf-fortran-* && \ + export CFLAGS="-fPIC" && \ + export FCFLAGS="${CFLAGS} -standard-semantics" && \ + export FFLAGS=${CFLAGS} && \ + export LIBS=$(${INSTALL_DIR}/bin/nc-config --libs --static) && \ + ./configure --disable-shared --prefix=${NFDIR} && \ + make && make install FROM intel/oneapi-hpckit:2023.1.0-devel-ubuntu20.04 as build-swiftest ENV SCRIPT_DIR="buildscripts" SHELL ["/bin/bash", "--login", "-c"] ENV SHELL="/bin/bash" WORKDIR /swiftest -ENV BUILD_DIR=/swiftest/build + +ENV FC="${ONEAPI_ROOT}/compiler/latest/linux/bin/mpiifort" +ENV CC="${ONEAPI_ROOT}/compiler/latest/linux/bin/icx" +ENV CXX="${ONEAPI_ROOT}/compiler/latest/linux/bin/icpx" +ENV F77="${FC}" + +ENV CPATH=${INSTALL_DIR}/include +ENV NETCDF_FORTRAN_HOME=${INSTALL_DIR} +ENV LD_LIBRARY_PATH="${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" # Copy build artifacts over to the swiftest package builder stage -COPY --from=build-deps ${BUILD_DIR}/lib/ /usr/local/lib/ -COPY --from=build-deps ${BUILD_DIR}/include/ /usr/local/include/ -COPY --from=build-deps ${BUILD_DIR}/bin/ /usr/local/bin/ -COPY --from=build-deps ${BUILD_DIR}/share/ /usr/local/share/ +ENV INSTALL_DIR=/usr/local +COPY --from=build-deps ${INSTALL_DIR}/ ${INSTALL_DIR}/ # Compile the Swiftest project -COPY ./buildscripts/build_swiftest.sh ./buildscripts/ +COPY ./requirements.txt ./ +COPY ./environment.yml ./ COPY ./cmake/ ./cmake/ +COPY ./pyproject.toml ./ +COPY ./setup.py ./ COPY ./src/ ./src/ COPY ./swiftest/ ./swiftest/ COPY ./CMakeLists.txt ./ -COPY ./setup.py ./ -COPY ./environment.yml ./ -COPY ./pyproject.toml ./ -COPY ./requirements.txt ./ COPY ./version.txt ./ +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install python3-pip python3.8-venv -y + +# Generate the build environment in conda ENV PIP_ROOT_USER_ACTION=ignore -RUN /bin/bash -lic && "${SCRIPT_DIR}/make_build_environment" && \ - /bin/bash -lic "${SCRIPT_DIR}/build_swiftest.sh Intel" +ENV LDFLAGS="-L${INSTALL_DIR}/lib" +ENV CFLAGS="-fPIC -standard-semantics" +ENV FFLAGS=${CFLAGS} +ENV SKBUILD_CONFIGURE_OPTIONS="-DBUILD_SHARED_LIBS=OFF -DMACHINE_CODE_VALUE=\"SSE2\"" +RUN export NFCFG="${INSTALL_DIR}/bin/nf-config" && \ + export LIBS=$($NFCFG --flibs) && \ + python3 -m pip install build pip && \ + python3 -m build --wheel #Export the generated wheel file to the host machine FROM scratch as export-wheel -COPY --from=build-swiftest /swiftest/dist/ /dist/ \ No newline at end of file +COPY --from=build-swiftest /swiftest/dist/ ./ \ No newline at end of file diff --git a/buildscripts/build_all.sh b/buildscripts/build_all.sh index 597aa1b35..e91d5cc0f 100755 --- a/buildscripts/build_all.sh +++ b/buildscripts/build_all.sh @@ -1,16 +1,6 @@ #!/bin/bash -# This script will determine the steps necessary to set up an appropriate build environment necessary to build Swiftest and all its -# dependencies. The steps that are executed depend on the combination of platform and architecture, as follows: -# -# Linux amd64/x86_64: -# Docker present: The build scripts will run inside a Docker container with Intel compilers (preferred). -# Docker not present: The build scripts will run inside a custom conda environment and build with Intel compilers if available, -# or GNU compiler compilers otherwise. -# Linux aarch64/arm64: -# Docker present: The build scripts will run inside a Docker container with GNU compilers -# Docker not present: The build scripts will run inside a custom conda environment with GNU compilers -# Mac OS (Darwin): -# The build scripts will run inside a custom conda environment with GNU compilers +# This script will generate cross-platform wheels for the Swiftest Python package using Docker. If it is called from MacOS it will +# also generate a Mac build. # # Copyright 2023 - David Minton # This file is part of Swiftest. @@ -26,6 +16,8 @@ SCRIPT_DIR=$(realpath $(dirname $0)) ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) BUILD_DIR="${ROOT_DIR}/build" +PREFIX=${BUILD_DIR}/usr/local + mkdir -p ${BUILD_DIR} read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) @@ -39,24 +31,20 @@ cd ${ROOT_DIR} VERSION=$( cat version.txt ) echo "Building Swiftest version ${VERSION} for ${OS}-${ARCH}" +if command -v docker &> /dev/null; then + echo "Docker detected" + + cmd="docker build --tag swiftest:latest --tag swiftest:${VERSION} --file=dockerfile.${COMPILER} --output=${ROOT_DIR}/dist/ ." + echo "Executing Docker build:\n${cmd}" + eval "$cmd" + exit 0 +else + echo "Docker not detected" +fi + case $OS in - Linux) - if [ "$ARCH" = "x86_64" ]; then - COMPILER="Intel" - else - COMPILER="GNU-Linux" - fi # Determine if Docker is available - if command -v docker &> /dev/null; then - echo "Docker detected" - cmd="docker build --tag swiftest:latest --tag swiftest:${VERSION} --file=dockerfile.${COMPILER} ." - echo "Executing Docker build:\n${cmd}" - eval "$cmd" - exit 0 - else - echo "Docker not detected" - fi ;; MacOSX) COMPILER="GNU-Mac" @@ -70,8 +58,8 @@ case $OS in ;; esac -${SCRIPT_DIR}/fetch_dependencies.sh && \ -${SCRIPT_DIR}/build_dependencies.sh $COMPILER && \ -${SCRIPT_DIR}/build_swiftest.sh $COMPILER +${SCRIPT_DIR}/fetch_dependencies.sh -d ${BUILD_DIR} && \ +${SCRIPT_DIR}/build_dependencies.sh -c $COMPILER -p ${PREFIX} && \ +${SCRIPT_DIR}/build_swiftest.sh -c $COMPILER -p ${PREFIX} diff --git a/buildscripts/build_dependencies.sh b/buildscripts/build_dependencies.sh index f3f9f5a6c..58fe6c8f8 100755 --- a/buildscripts/build_dependencies.sh +++ b/buildscripts/build_dependencies.sh @@ -12,127 +12,139 @@ # If not, see: https://www.gnu.org/licenses. SCRIPT_DIR=$(realpath $(dirname $0)) BUILD_DIR=$(realpath ${SCRIPT_DIR}/../build) + mkdir -p ${BUILD_DIR} cd $BUILD_DIR -USTMT="Usage: $0 <{Intel}|GNU>" -if [[ ( $@ == "--help") || $@ == "-h" ]]; then - echo $USTMT - exit 0 -fi -COMPILER=${1:-Intel} - -case $COMPILER in - Intel) - if command -v ifx &> /dev/null; then - export FC=$(command -v ifx) - export CC=$(command -v icx) - export CXX=$(command -v icpx) - elif command -v ifort &> /dev/null; then - export FC=$(command -v ifort) - export CC=$(command -v icc) - export CXX=$(command -v icpc) - else - echo "Error. Cannot find valid Intel fortran compiler." - exit 1 - fi - export F77="${FC}" +# Parse arguments +USTMT="Usage: ${0} <-c Intel|GNU-Linux|GNU-Mac> [-p {/usr/local}|/prefix/path]" +IFORT=false +PREFIX=/usr/local +COMPILER="" +CARG="" +while getopts ":c:p:" ARG; do + case "${ARG}" in + c) + COMPILER="${OPTARG}" ;; - GNU-Linux) - export FC=$(command -v gfortran) - export CC=$(command -v gcc) - export CXX=$(command -v g++) + p) + PREFIX="${OPTARG}" ;; - GNU-Mac) - export FC=$HOMEBREW_PREFIX/bin/gfortran-13 - export CC=$HOMEBREW_PREFIX/bin/gcc-13 - export CXX=$HOMEBREW_PREFIX/bin/g++-13 - ;; - *) - echo "Unknown compiler type: ${COMPILER}" + :) + echo "Error: -${OPTARG} requires an argument." echo $USTMT exit 1 ;; -esac -export F77=${FC} -echo "Using $COMPILER compilers:\nFC: $FC\nCC: $CC\nCXX: $CXX\n" + *) + ;; + esac +done +CMD="${SCRIPT_DIR}/set_compilers.sh -c $COMPILER" +read -r CC CXX FC F77 CPP < <($CMD) +export CC=${CC} +export CXX=${CXX} +export FC=${FC} +export F77=${F77} +export CPP=${CPP} -export INSTALL_DIR=${BUILD_DIR} -mkdir -p ${INSTALL_DIR} -export NCDIR="${INSTALL_DIR}" -export NFDIR="${INSTALL_DIR}" -export HDF5_ROOT="${INSTALL_DIR}" +printf "*********************************************************\n" +printf "* STARTING DEPENDENCY BUILD *\n" +printf "*********************************************************\n" +printf "Using ${COMPILER} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n" +printf "Installing to ${PREFIX}\n" +printf "\n" +export CPPFLAGS="-I{PREFIX}/include" +export LDFLAGS="${LDFLAGS} -L${PREFIX}/lib" +export HDF5_ROOT="${PREFIX}" export HDF5_LIBDIR="${HDF5_ROOT}/lib" export HDF5_INCLUDE_DIR="${HDF5_ROOT}/include" export HDF5_PLUGIN_PATH="${HDF5_LIBDIR}/plugin" +export NCDIR="${PREFIX}" +export NFDIR="${PREFIX}" +export LD_LIBRARY_PATH="${PREFIX}/lib" +export LDFLAGS="-L${PREFIX}/lib" +export CPPFLAGS="-I${PREFIX}/include" -export LDFLAGS="${LDFLAGS} -L${INSTALL_DIR}/lib" -export CPATH="${INSTALL_DIR}/include" -export CFLAGS="-fPIC" - +printf "*********************************************************\n" +printf "* BUILDING ZLIB STATIC LIBRARY *\n" +printf "*********************************************************\n" cd zlib-1.2.13 -make distclean -./configure --prefix=${INSTALL_DIR} --static +./configure --prefix=${PREFIX} --static make make install -if [ $? -ne 0]; then - echo "zlib could not be compiled." +if [ $? -ne 0 ]; then + printf "zlib could not be compiled.\n" exit 1 fi +printf "\n" +printf "*********************************************************\n" +printf "* BUILDING HDF5 STATIC LIBRARY *\n" +printf "*********************************************************\n" cd ../hdf5-1.14.1-2 -if [ "$COMPILER" = "GNU-Mac" ]; then +if [ "$COMPILER"="GNU-Mac" ]; then read -r OS ARCH < <($SCRIPT_DIR/get_platform.sh) - if [ "ARCH" = "arm64" ]; then - echo "echo arm-apple-darwin" > bin/config.sub + if [ $OS="MacOS" ] && [ "$ARCH"="arm64" ]; then + printf "Manually setting bin/config.sub to arm-apple-darwin\n" + printf "echo arm-apple-darwin" > bin/config.sub fi fi -make distclean -./configure --disable-shared \ - --enable-build-mode=production \ - --disable-fortran \ - --disable-java \ - --disable-cxx \ - --prefix=${INSTALL_DIR} \ - --with-zlib=${INSTALL_DIR} -make -make install -if [ $? -ne 0]; then - echo "hdf5 could not be compiled." +COPTS="--disable-shared --enable-build-mode=production --disable-fortran --disable-java --disable-cxx --prefix=${PREFIX} --with-zlib=${PREFIX}" +./configure ${COPTS} +make && make install +if [ $? -ne 0 ]; then + printf "hdf5 could not be compiled.\n" exit 1 fi + +printf "\n" +printf "*********************************************************\n" +printf "* BUILDING NETCDF-C STATIC LIBRARY *\n" +printf "*********************************************************\n" cd ../netcdf-c-4.9.2 -make distclean -./configure --disable-shared \ - --disable-dap \ - --disable-libxml2 \ - --disable-byterange \ - --prefix=${INSTALL_DIR} -make -make check -make install -if [ $? -ne 0]; then - echo "netcdf-c could not be compiled." +COPTS="--disable-shared --disable-dap --disable-byterange --prefix=${PREFIX}" +if [ ! $COMPILER="GNU-Mac" ]; then + COPTS="${COPTS} --disable-libxml2" +fi +printf "COPTS: ${COPTS}\n" +printf "LIBS: ${LIBS}\n" +printf "CFLAGS: ${CFLAGS}\n" +printf "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}\n" +printf "LDFLAGS: ${LDFLAGS}\n" + +./configure $COPTS +make && make check && make install +if [ $? -ne 0 ]; then + printf "netcdf-c could not be compiled."\n exit 1 fi -if [ $COMPILER = "Intel" ]; then + +export CFLAGS="-fPIC" +if [ $COMPILER="Intel" ]; then export FCFLAGS="${CFLAGS} -standard-semantics" - export FFLAGS=${CFLAGS} else export FCFLAGS="${CFLAGS}" - export FFLAGS="${CFLAGS}" fi +export FFLAGS=${CFLAGS} + +export LIBS="$(${PREFIX}/bin/nc-config --libs --static)" -make distclean -export LIBS="$(${INSTALL_DIR}/bin/nc-config --libs)" +printf "\n" +printf "*********************************************************\n" +printf "* BUILDING NETCDF-FORTRAN STATIC LIBRARY *\n" +printf "*********************************************************\n" cd ../netcdf-fortran-4.6.1 -./configure --disable-shared --with-pic --prefix=${NFDIR} -make -make check -make install +./configure --disable-shared --with-pic --prefix=${PREFIX} +make && make check && make install if [ $? -ne 0 ]; then - echo "netcdf-fortran could not be compiled." + printf "netcdf-fortran could not be compiled.\n" exit 1 fi + +printf "\n" +printf "*********************************************************\n" +printf "* DEPENDENCIES ARE BUILT *\n" +printf "*********************************************************\n" +printf "Dependencys are installed to: ${PREFIX}\n\n" diff --git a/buildscripts/build_swiftest.sh b/buildscripts/build_swiftest.sh index 8a817bdea..362acae09 100755 --- a/buildscripts/build_swiftest.sh +++ b/buildscripts/build_swiftest.sh @@ -11,58 +11,48 @@ # If not, see: https://www.gnu.org/licenses. SCRIPT_DIR=$(realpath $(dirname $0)) ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) -USTMT="Usage: $0 <{Intel}|GNU> [/path/to/nf-nc-hdf5]" -if [[ ( $@ == "--help") || $@ == "-h" ]]; then - echo $USTMT - exit 0 -fi -COMPILER=${1:-Intel} -DEPDIR_DEFAULT=$(realpath ${ROOT_DIR}/build) -DEPDIR=${2:-$DEPDIR_DEFAULT} -echo "NetCDF & HDF library directory: ${DEPDIR}" -case $COMPILER in - Intel) - if command -v ifx &> /dev/null; then - export FC=$(command -v ifx) - export CC=$(command -v icx) - export CXX=$(command -v icpx) - elif command -v ifort &> /dev/null; then - export FC=$(command -v ifort) - export CC=$(command -v icc) - export CXX=$(command -v icpc) - else - echo "Error. Cannot find valid Intel fortran compiler." - exit 1 - fi - export F77="${FC}" - ;; - GNU-Linux) - export FC=$(command -v gfortran) - export CC=$(command -v gcc) - export CXX=$(command -v g++) +# Parse arguments +USTMT="Usage: ${0} <-c Intel|GNU-Linux|GNU-Mac> [-p {/usr/local}|/prefix/path]" +IFORT=false +PREFIX=/usr/local +COMPILER="" +CARG="" +while getopts ":c:p:" ARG; do + case "${ARG}" in + c) + COMPILER="${OPTARG}" ;; - GNU-Mac) - export FC=$HOMEBREW_PREFIX/bin/gfortran-13 - #export CC=$HOMEBREW_PREFIX/bin/gcc-13 - #xport CXX=$HOMEBREW_PREFIX/bin/g++-13 - export CC=/usr/bin/clang - export CXX=/usr/bin/clang++ + p) + PREFIX="${OPTARG}" ;; - *) - echo "Unknown compiler type: ${COMPILER}" + :) + echo "Error: -${OPTARG} requires an argument." echo $USTMT exit 1 ;; -esac -export F77=${FC} -NL=$'\n' -echo "Using ${COMPILER} compilers:${NL}FC: ${FC}${NL}CC: ${CC}${NL}CXX: ${CXX}${NL}" - + *) + ;; + esac +done +CMD="${SCRIPT_DIR}/set_compilers.sh -c $COMPILER -f" +read -r CC CXX FC F77 < <($CMD) +printf "Using ${COMPILER} compilers:\nFC: ${FC}\nCC: ${CC}\nCXX: ${CXX}\n\n" +printf "Installing to ${PREFIX}\n" +printf "Dependency libraries in ${PREFIX}\n" +export DEPDIR=$PREFIX export CPATH=$DEPDIR/include export NETCDF_FORTRAN_HOME=$DEPDIR + export LD_LIBRARY_PATH="${DEPDIR}/lib:${LD_LIBRARY_PATH}" -export LIBS=$(${DEPDIR}/bin/nf-config --flibs) +NFCFG="${DEPDIR}/bin/nf-config" +if command -v $NFCFG &> /dev/null; then + export LIBS=$($NFCFG --flibs) +else + printf "Error: Cannot find ${NFCFG}.\n" + printf "Is NetCDF-Fortran installed?\n" + exit 1 +fi export LDFLAGS="${LDFLAGS} -L${DEPDIR}/lib" export CFLAGS="-fPIC" export CMAKE_ARGS="-DBUILD_SHARED_LIBS=OFF" @@ -70,11 +60,13 @@ export CMAKE_ARGS="-DBUILD_SHARED_LIBS=OFF" if [ $COMPILER = "Intel" ]; then export FCFLAGS="${CFLAGS} -standard-semantics" export FFLAGS=${CFLAGS} + export CMAKE_ARGS="${CMAKE_ARGS} -DMACHINE_CODE_VALUE=\"SSE2\"" else export FCFLAGS="${CFLAGS}" export FFLAGS="${CFLAGS}" + export CMAKE_ARGS="${CMAKE_ARGS} -DMACHINE_CODE_VALUE=\"generic\"" fi cd $ROOT_DIR -python -m pip install build -python -m build --wheel +python3 -m pip install build pip +python3 -m build --wheel diff --git a/buildscripts/set_compilers.sh b/buildscripts/set_compilers.sh new file mode 100755 index 000000000..8711589c4 --- /dev/null +++ b/buildscripts/set_compilers.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# This script will determine the paths to the suite of compilers and return values for CC, CXX, FC, and F77 based on the compiler +# vender options +# On x86_64 Linux machines, Intel compilers are preferred. +# On aarch64 Linux machines, default GNU compilers are preferred. +# On MacOS machines, GNU compilers from Homebrew are preferred. +# +# Copyright 2023 - David Minton +# This file is part of Swiftest. +# Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with Swiftest. +# If not, see: https://www.gnu.org/licenses. +# Parse arguments +USTMT="Usage: ${0} <-c Intel|GNU-Linux|GNU-Mac> [-f|--force-ifort]" +IFORT=false +COMPILER="" +while getopts ":c:f" ARG; do + case "${ARG}" in + f) + ;; + c) + COMPILER="${OPTARG}" + ;; + :) + echo "Error: -${OPTARG} requires an argument." + echo $USTMT + exit 1 + ;; + *) + ;; + esac +done + +case "$COMPILER" in + Intel|GNU-Linux|GNU-Mac) + ;; + *) + echo "Unknown compiler type: $COMPILER" + echo "Valid options are Intel, GNU-Linux, or GNU-Mac" + echo $USTMT + exit 1 + ;; +esac + +# Only replace compiler definitions if they are not already set +case $COMPILER in + Intel) + if [ ! -v FC ]; then + if command -v ifx &> /dev/null; then + export FC=$(command -v ifx) + elif command -v ifort &> /dev/null; then + export FC=$(command -v mpiifort) + else + printf "Error. Cannot find valid Intel Fortran compiler.\n" + exit 1 + fi + fi + if [ ! -v F77 ]; then + export F77="${FC}" + fi + + if [ ! -v CC ]; then + if command -v icx &> /dev/null; then + export CC=$(command -v icx) + elif command -v icc &> /dev/null; then + export CC=$(command -v icc) + else + printf "Error. Cannot find valid Intel C compiler.\n" + exit 1 + fi + fi + + if [ ! -v CXX ]; then + if command -v icpx &> /dev/null; then + export CXX=$(command -v icpx) + elif command -v icpc &> /dev/null; then + export CXX=$(command -v icpc) + else + printf "Error. Cannot find valid Intel C++ compiler.\n" + exit 1 + fi + fi + + if command -v mpiifort &> /dev/null; then + export I_MPI_F90=${FC} + export FC=$(command -v mpiifort) + fi + + if command -v mpiicc &> /dev/null; then + export I_MPI_CC =${CC} + export CC=$(command -v mpiicc) + fi + + if command -v mpiicpc &> /dev/null; then + export I_MPI_CXX =${CXX} + export CXX=$(command -v mpiicpc) + fi + + export CPP=${CPP:-$HOMEBRE_PREFIX/bin/cpp-13} + ;; + GNU-Linux) + export FC=${FC:-$(command -v gfortran)} + export CC=${CC:-$(command -v gcc)} + export CXX=${CXX:-$(command -v g++)} + export CXX=${CPP:-$(command -v cpp)} + ;; + GNU-Mac) + export FC=${FC:-$HOMEBREW_PREFIX/bin/gfortran-13} + export CC=${CC:-$HOMEBREW_PREFIX/bin/gcc-13} + export CXX=${CXX:-$HOMEBREW_PREFIX/bin/g++-13} + export CPP=${CPP:-$HOMEBRE_PREFIX/bin/cpp-13} + ;; + *) + printf "Unknown compiler type: ${COMPILER}\n" + echo "Valid options are Intel, GNU-Linux, or GNU-Mac" + printf $USTMT + exit 1 + ;; +esac +export F77=${FC} + +printf "${CC} ${CXX} ${FC} ${F77} ${CPP}" \ No newline at end of file diff --git a/environment.yml b/environment.yml index cb49c2304..015c642f1 100644 --- a/environment.yml +++ b/environment.yml @@ -19,4 +19,5 @@ dependencies: - astroquery>=0.4.6 - tqdm>=4.65.0 - x264>=1!157.20191217 - - ffmpeg>=4.3.2 \ No newline at end of file + - ffmpeg>=4.3.2 + - py>=1.11 \ No newline at end of file diff --git a/swiftest/simulation_class.py b/swiftest/simulation_class.py index c9f125173..678231115 100644 --- a/swiftest/simulation_class.py +++ b/swiftest/simulation_class.py @@ -14,6 +14,7 @@ from swiftest import init_cond from swiftest import tool from swiftest import constants +from swiftest import driver from swiftest import __file__ as _pyfile import json import os @@ -25,10 +26,10 @@ from functools import partial import numpy.typing as npt import shutil -import subprocess import shlex import warnings import sys +from py.io import StdCaptureFD from tqdm.auto import tqdm from typing import ( Literal, @@ -403,11 +404,6 @@ def _run_swiftest_driver(self): Internal callable function that executes the swiftest_driver run """ - # Get current environment variables - env = os.environ.copy() - cmd = f"{env['SHELL']} {self.driver_script}" - - def _type_scrub(output_data): int_vars = ["ILOOP","NPL","NTP","NPLM"] for k,v in output_data.items(): @@ -430,44 +426,46 @@ def _type_scrub(output_data): post_message += f" Wall time / step: {0.0:.5e} s" pbar = tqdm(total=noutput, desc=pre_message, postfix=post_message, bar_format='{l_bar}{bar}{postfix}') try: - with subprocess.Popen(shlex.split(cmd), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=env, - universal_newlines=True) as p: - - for line in p.stdout: - if "SWIFTEST STOP" in line: - process_output = False - - if process_output: - kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, - output_data = _type_scrub({kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]}) - pre_message = f"Time: {output_data['T']:.{twidth}e} / {self.param['TSTOP']:.{twidth}e} {self.TU_name}" - post_message = f" npl: {output_data['NPL']} ntp: {output_data['NTP']}" - if "NPLM" in output_data: - post_message += f" nplm: {output_data['NPLM']}" - if "LTOTERR" in output_data: - post_message += f" dL/L0: {output_data['LTOTERR']:.5e}" - if "ETOTERR" in output_data: - post_message += f" dE/|E0|: {output_data['ETOTERR']:+.5e}" - post_message += f" Wall time / step: {output_data['WTPS']:.5e} s" - interval = output_data['ILOOP'] - iloop - if interval > 0: - pbar.update(interval) - pbar.set_description_str(pre_message) - pbar.set_postfix_str(post_message) - iloop = output_data['ILOOP'] - - if "SWIFTEST START" in line: - process_output = True - - res = p.communicate() - if p.returncode != 0: - for line in res[1]: - print(line, end='') - warnings.warn("Failure in swiftest_driver", stacklevel=2) - sys.exit() + capture = StdCaptureFD(out=False, in_=False) + out,err = capture.reset() + # with subprocess.Popen(shlex.split(cmd), + # stdout=subprocess.PIPE, + # stderr=subprocess.PIPE, + # env=env, + # universal_newlines=True) as p: + driver(self.integrator,str(self.param_file), "compact") + for line in out: + if "SWIFTEST STOP" in line: + process_output = False + + if process_output: + kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, + output_data = _type_scrub({kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]}) + pre_message = f"Time: {output_data['T']:.{twidth}e} / {self.param['TSTOP']:.{twidth}e} {self.TU_name}" + post_message = f" npl: {output_data['NPL']} ntp: {output_data['NTP']}" + if "NPLM" in output_data: + post_message += f" nplm: {output_data['NPLM']}" + if "LTOTERR" in output_data: + post_message += f" dL/L0: {output_data['LTOTERR']:.5e}" + if "ETOTERR" in output_data: + post_message += f" dE/|E0|: {output_data['ETOTERR']:+.5e}" + post_message += f" Wall time / step: {output_data['WTPS']:.5e} s" + interval = output_data['ILOOP'] - iloop + if interval > 0: + pbar.update(interval) + pbar.set_description_str(pre_message) + pbar.set_postfix_str(post_message) + iloop = output_data['ILOOP'] + + if "SWIFTEST START" in line: + process_output = True + + res = p.communicate() + if p.returncode != 0: + for line in res[1]: + print(line, end='') + warnings.warn("Failure in swiftest_driver", stacklevel=2) + sys.exit() except: warnings.warn(f"Error executing main swiftest_driver program", stacklevel=2) res = p.communicate() @@ -2773,12 +2771,12 @@ def write_param(self, else: warnings.warn('Cannot process unknown code type. Call the read_param method with a valid code name. Valid options are "Swiftest", "Swifter", or "Swift".',stacklevel=2) - # Generate executable script - self.driver_script = os.path.join(self.simdir, "swiftest_driver.sh") - with open(self.driver_script, 'w') as f: - f.write(f"#{self._shell_full}\n") - f.write(f"cd {self.simdir}\n") - f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} compact\n") + # # Generate executable script + # self.driver_script = os.path.join(self.simdir, "swiftest_driver.sh") + # with open(self.driver_script, 'w') as f: + # f.write(f"#{self._shell_full}\n") + # f.write(f"cd {self.simdir}\n") + # f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} compact\n") return