diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0e86cb1f4..914074f07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -181,6 +181,20 @@ jobs: version: 0.63 container: phhargrove/lfortran:0.63.0-1 + # --- OPT coverage --- + - os: ubuntu-24.04 + compiler: flang + version: 23 + label: OPT + CONFIGURE_ARGS: --disable-debug + container: phhargrove/llvm-flang:23.1.0-latest + - os: ubuntu-22.04 + compiler: lfortran + version: 0.65 + label: OPT + CONFIGURE_ARGS: --disable-debug + container: ghcr.io/lfortran/lfortran:v0.65.0 + # --- PRIF-old coverage --- - os: ubuntu-24.04 compiler: flang @@ -236,6 +250,8 @@ jobs: - os: macos-15 compiler: flang network: udp + label: FPM-0.10 + FPM_VERSION: 0.10.0 - os: macos-26 compiler: flang network: udp @@ -265,6 +281,8 @@ jobs: version: 23 network: udp container: phhargrove/llvm-flang:23.1.0-latest + label: FPM-0.10 + FPM_VERSION: 0.10.0 - os: ubuntu-24.04 compiler: flang version: latest @@ -280,10 +298,10 @@ jobs: COMPILER_VERSION: ${{ matrix.version || needs.setup.outputs.BREW_FLANG_VERSION }} FFLAGS: ${{ matrix.FFLAGS }} ${{ inputs.fflags }} CFLAGS: ${{ matrix.CFLAGS }} ${{ inputs.cflags }} - PREFIX: install + FPM_VERSION: ${{ matrix.FPM_VERSION || '0.13.0' }} NETWORK_ARG: ${{ matrix.network && format('--network={0}',matrix.network) || '' }} CURL_OPTIONS: -L --retry 10 --retry-all-errors --fail - GASNET_CONFIGURE_ARGS: --enable-rpath --enable-debug + CONFIGURE_ARGS: --prefix=install --enable-rpath --enable-debug --verbose ${{ matrix.CONFIGURE_ARGS }} GASNET_SPAWN_VERBOSE: 1 GASNET_SPAWNFN: L GASNET_MASTERIP: 127.0.0.1 @@ -389,17 +407,25 @@ jobs: # Prepend Macports clang to PATH: echo "PATH=/opt/local/bin:${PATH}" >> "$GITHUB_ENV" + - name: Choose FPM + if: ${{ !matrix.brew_via_install }} + run: | + if [[ ${{ runner.arch == 'ARM64' && (runner.os == 'Linux' || env.FPM_VERSION < '0.13.0') }} == true ]] ; then + echo "FPM_BUILD=true" >> "$GITHUB_ENV" + else + echo "FPM_SETUP=true" >> "$GITHUB_ENV" + fi + - name: Setup FPM - if: ${{ !matrix.brew_via_install && !(runner.os == 'Linux' && runner.arch == 'ARM64') }} + if: env.FPM_SETUP uses: fortran-lang/setup-fpm@main with: github-token: ${{ secrets.GITHUB_TOKEN }} - fpm-version: latest + fpm-version: v${{ env.FPM_VERSION }} - name: Build FPM - if: ${{ !matrix.brew_via_install && runner.os == 'Linux' && runner.arch == 'ARM64' }} + if: env.FPM_BUILD run: | - export FPM_VERSION=0.13.0 curl --retry 5 -LOsS https://github.com/fortran-lang/fpm/releases/download/v$FPM_VERSION/fpm-$FPM_VERSION.F90 mkdir fpm-temp gfortran-14 -o fpm-temp/fpm fpm-$FPM_VERSION.F90 @@ -416,14 +442,18 @@ jobs: echo "CXX=g++-${COMPILER_VERSION}" >> "$GITHUB_ENV" # XCode 26 / gfortran bug workaround if [[ ${{ matrix.os }} =~ macos-26 ]] ; then - echo "GASNET_CONFIGURE_ARGS=$GASNET_CONFIGURE_ARGS --enable-force-posix-realtime" >> "$GITHUB_ENV" + echo "CONFIGURE_ARGS=$CONFIGURE_ARGS --enable-force-posix-realtime" >> "$GITHUB_ENV" fi - name: Set flang variables if: ${{ matrix.compiler == 'flang' }} run: | if [ -z "${{ matrix.brew_via_install }}" ] ; then - echo "FC=flang-new" >> "$GITHUB_ENV" + if [[ $COMPILER_VERSION -le 19 ]] ; then + echo "FC=flang-new" >> "$GITHUB_ENV" + else + echo "FC=flang" >> "$GITHUB_ENV" + fi echo "CC=clang" >> "$GITHUB_ENV" echo "CXX=clang++" >> "$GITHUB_ENV" fi @@ -498,11 +528,18 @@ jobs: find $RDIR $BDIR /usr/lib/ -name '*flang_rt*' -exec ls -al {} \; | sort | uniq fi + - name: Test install.sh outputs + run: | + ./install.sh --help 2>&1 | tee output + test ${PIPESTATUS[0]} = 0 && grep -q "fortran@lbl.gov" output + ./install.sh --prereqs 2>&1 | tee output + test ${PIPESTATUS[0]} = 0 && grep -q "GASNet-EX" output + - name: Build Caffeine (install.sh) run: | for var in FC CC CXX FFLAGS CPPFLAGS CFLAGS CXXFLAGS LDFLAGS LIBS GASNET_CONFIGURE_ARGS ; do eval echo "$var=\$$var"; done - ./install.sh --prefix=${PREFIX} ${NETWORK_ARG} --verbose \ + ./install.sh ${CONFIGURE_ARGS} ${NETWORK_ARG} \ ${{ inputs.install_args }} ${{ matrix.install_filter }} if ! grep -q 'NATIVEFLAGS=""' run-fpm.sh ; then echo "NATIVE_MULTI_IMAGE=true" >> "$GITHUB_ENV" @@ -514,6 +551,8 @@ jobs: - name: Version info (run-fpm) run: | ./run-fpm.sh info + ./install/bin/ident ./install/lib/libcaffeine.a | tee output + test ${PIPESTATUS[0]} = 0 && grep -q "CaffeineAssertions" output - name: Run examples run: | @@ -586,7 +625,7 @@ jobs: run: | for var in FC CC CXX FFLAGS CPPFLAGS CFLAGS LDFLAGS LIBS GASNET_CONFIGURE_ARGS ; do eval echo "$var=\$$var"; done - ./install.sh --prefix=${PREFIX} ${NETWORK_ARG} --enable-threads --verbose \ + ./install.sh ${CONFIGURE_ARGS} ${NETWORK_ARG} --enable-threads \ ${{ inputs.install_args }} ${{ matrix.install_filter }} ./run-fpm.sh test --verbose -- ${{ inputs.julienne_args }} diff --git a/README.md b/README.md index 57454e3c4..0ad987d0f 100644 --- a/README.md +++ b/README.md @@ -48,19 +48,24 @@ their solution to support Fortran's multi-image parallel features. Prerequisites & Dependencies ------------- +Caffeine supports recent versions of Linux and macOS, running on x86\_64 (amd64) or ARM64 (aarch64) architectures. +Other architectures and POSIX-like environments may also work, but are not regularly tested. + ### Build prerequisites -The `install.sh` script uses the following packages: -* Fortran and C compilers - * We regularly test with: LLVM Flang versions 19:22 and GNU Fortran versions 13:15 -* [Fortran package manager] `fpm` -* [pkg-config] -* [realpath] -* [make] -* [git] -* [curl] - -The script will invoke these if present in a user's `PATH`. -If not present, the script will ask permission to use [Homebrew] to install the relevant package + +The `install.sh` script uses the following packages to build Caffeine: +* Fortran and C compilers. We [regularly test](https://github.com/BerkeleyLab/caffeine/actions?query=branch%3Amain) with: + - LLVM Flang versions 19:23, + - GNU Fortran versions 13:16, and + - LFortran versions 0.64: +* [`fpm`](https://github.com/fortran-lang/fpm), the Fortran package manager +* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) +* [GNU make](https://www.gnu.org/software/make/) +* [git](https://git-scm.com) +* [curl](https://curl.se) + +The `install.sh` script will invoke these if found in the user's `PATH`. +If not present, the script will ask permission to use [Homebrew](https://brew.sh) to install the relevant package or, in some cases, ask the user to install the package. ### Build dependencies @@ -68,9 +73,9 @@ or, in some cases, ask the user to install the package. Caffeine also depends on the following packages that will be automatically installed as part of the build process. -* [GASNet-EX] exascale networking middleware -* [assert](https://go.lbl.gov/assert) -* [julienne](https://go.lbl.gov/julienne) +* [GASNet-EX] : exascale networking middleware, providing communication services +* [assert](https://go.lbl.gov/assert) : Fortran assertion package, enforces invariants in debug mode +* [julienne](https://go.lbl.gov/julienne) : Fortran test infrastructure (only for unit tests) Caffeine leverages the following non-parallel features of Fortran to simplify the writing of a portable, compact runtime-library that supports Fortran's parallel features: @@ -131,6 +136,16 @@ written in Fortran, simulating the PRIF calls that a theoretical source-to-source Fortran compiler might generate for a simple program written using Fortran's multi-image features to print a message from each image. +Caffeine also includes a broad "smoke test" of multi-image Fortran features. +When Caffeine was installed using a PRIF-compatible Fortran compiler (currently +LLVM Flang 22+ or LFortran 0.64+) the following command will invoke this smoke +test: +```bash +env CAF_IMAGES=8 ./run-fpm.sh run +``` +This will exercise the available PRIF feature set of the compiler version +detected at install time. + Run tests --------- @@ -168,6 +183,21 @@ Here are *a few* of the most useful GASNet knobs: See [GASNet documentation](https://gasnet.lbl.gov/dist-ex/README) for full details on all settings. +Troubleshooting +--------------- + +The Caffeine `./install.sh` script defaults to building the library in an optimized production mode, +which is generally suitable for end users and should be preferred for any performance-oriented runs. + +If you're developing compiler transformations targeting PRIF, or if you encounter a correctness +problem at runtime, then its **highly** recommended to instead build Caffeine in debug mode: +``` +./install.sh --enable-debug +``` +The `--enable-debug` flag disables compiler optimization and enables thousands +of correctness checks system-wide. This includes sanity checking of PRIF subroutine +arguments, and often provides an automated diagnosis that can pinpoint the problem. + PRIF Implementation Status -------------------------- @@ -228,10 +258,3 @@ See [LICENSE.txt](LICENSE.txt) for usage terms and conditions. [CLaSS]: https://go.lbl.gov/class [Berkeley Lab]: https://lbl.gov [MPI]: https://www.mpi-forum.org -[Homebrew]: https://brew.sh -[Fortran package manager]: https://github.com/fortran-lang/fpm -[pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ -[realpath]: https://man7.org/linux/man-pages/man3/realpath.3.html -[make]: https://www.gnu.org/software/make/ -[git]: https://git-scm.com -[curl]: https://curl.se diff --git a/install.sh b/install.sh index 8fb08e6ca..54e78d340 100755 --- a/install.sh +++ b/install.sh @@ -7,11 +7,12 @@ print_usage_info() cat <<'EOF' Caffeine Installation Script -USAGE: -./install.sh [--help | [--prefix=PREFIX] +Usage: ./install.sh [OPTION]... +Options: --help Display this help text - --prefix=PREFIX Install library into 'PREFIX' directory + --prefix= Install libraries into directory + Default prefix='\$HOME/.local/bin' --network= Build Caffeine to target given GASNet network conduit. should be one of: smp: single-node shared-memory conduit (default) @@ -20,9 +21,10 @@ USAGE: ofi: OpenFabrics Interfaces ucx: Unified Communication X --prereqs Display a list of prerequisite software. - Default prefix='\$HOME/.local/bin' --verbose Show verbose build commands - --yes Assume (yes) to all prompts for non-interactive build + --yes Assume (yes) to all prompts for non-interactive install + --enable-debug Build Caffeine and GASNet in LOW-PERFORMANCE debug mode, + disabling optimization and enabling assertions to help find defects. --enable-threads Build a thread-safe Caffeine library and link to thread-safe GASNet, for use in threaded do-concurrent. @@ -33,14 +35,13 @@ Some influential environment variables: FFLAGS Fortran compiler flags CC C compiler command CFLAGS C compiler flags - CPP C preprocessor CPPFLAGS C preprocessor flags, e.g. -I if you have headers in a nonstandard directory LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l Use these variables to override the choices made by the installer or to help -it to find libraries and programs with nonstandard names/locations. +it to find programs with nonstandard names/locations. Report bugs to fortran@lbl.gov or at https://go.lbl.gov/caffeine @@ -48,39 +49,109 @@ EOF } GASNET_VERSION="stable" +GASNET_SOURCE_URL="https://github.com/BerkeleyLab/gasnet/releases/download/gex-$GASNET_VERSION/GASNet-$GASNET_VERSION.tar.gz" +ASSERT_GIT=$(awk -F'"' '/^assert =/ {print $2}' manifest/fpm.toml.template) +ASSERT_VERSION=$(awk -F'"' '/^assert =/ {print $4}' manifest/fpm.toml.template) +JULIENNE_GIT=$(awk -F'"' '/^julienne =/ {print $2}' manifest/fpm.toml.template) +JULIENNE_VERSION=$(awk -F'"' '/^julienne =/ {print $4}' manifest/fpm.toml.template) VERBOSE="" -GASNET_CONDUIT="${GASNET_CONDUIT:-smp}" -GASNET_THREADMODE="${GASNET_THREADMODE:-seq}" YES=false APPEND_CFLAGS="" APPEND_LDFLAGS="" +# these variables deliberately inherited from the caller environment +GASNET_CONDUIT="${GASNET_CONDUIT:-smp}" +GASNET_THREADMODE="${GASNET_THREADMODE:-seq}" +GASNET_CODEMODE="${GASNET_CODEMODE:-opt}" +GASNET_CONFIGURE_ARGS=${GASNET_CONFIGURE_ARGS:-} + list_prerequisites() { cat << EOF -Caffeine and this installer were developed with the following prerequisites. +Caffeine's build system has the following system software prerequisites. If any are missing and if permission is granted, the installer will install the latest versions using Homebrew: - LLVM flang - GASNet-EX $GASNET_VERSION + LLVM flang (or another supported Fortran compiler) fpm - git (used by fpm to clone dependencies) - curl pkg-config - realpath (Homebrew coreutils) - GNU Make (Homebrew coreutils) + GNU Make + git + curl (used to download library dependencies) + +The installer will also download and build the following library dependencies, +which are installed along with the Caffeine library to the install prefix: + + GASNet-EX $GASNET_VERSION + - $GASNET_SOURCE_URL + Assert $ASSERT_VERSION + - $ASSERT_GIT + Julienne $JULIENNE_VERSION (optional, only used for unit tests) + - $JULIENNE_GIT EOF } -# GASNET_CONFIGURE_ARGS is deliberately inherited from the caller environment -GASNET_CONFIGURE_ARGS=${GASNET_CONFIGURE_ARGS:=} + +# expand to an absolute path for $1, possibly including symlinks +abspath() { + if [ -z "$1" ]; then + echo "ERROR: expected a non-empty pathname" >&2 + return 1 + fi + + if [[ "$1" == /* ]] ; then + echo "$1" + else + echo "$PWD/$1" + fi +} + +# like `which` but always returns an absolute path or empty +# If $2 is set then failure is suppressed in the exit code +abswhich() { + local cmd_path + if [ -z "$1" ]; then + echo "ERROR: expected a non-empty pathname" >&2 + return 1 + fi + cmd_path=$(type -P -- "$1") || return $( [[ -n "${2:-}" ]] ) + + echo "$(abspath $cmd_path)" +} + +# expand to the absolute path of $1 with all symlinks and non-canonical elements removed +realpath() { + set +x + if [ -z "$1" ]; then + echo "ERROR: expected a non-empty pathname" >&2 + return 1 + fi + + perl -e ' + use Cwd "abs_path"; + my $abs = abs_path($ARGV[0]); + if (defined $abs) { + print "$abs\n"; + } else { + print "ERROR: $ARGV[0] does not exist"; + exit 1; + } + ' "$1" +} + +append_gasnet_configure_arg() { + if [[ -z "$GASNET_CONFIGURE_ARGS" ]] ; then + GASNET_CONFIGURE_ARGS="\"$1\"" + else + # Quoting is believed sufficient for embedded whitespace but not quotes + GASNET_CONFIGURE_ARGS+=" \"${1//\"/\\\"}\"" + fi +} while [ "$1" != "" ]; do orig_arg="$1" - PARAM=$(echo "$1" | awk -F= '{print $1}') - VALUE=$(echo "$1" | awk -F= '{print $2}') + PARAM=$(awk -F= '{print $1}' <<< $1) + VALUE=$(awk -F= '{print $2}' <<< $1) case $PARAM in -h | --help) print_usage_info @@ -113,19 +184,31 @@ while [ "$1" != "" ]; do --enable-threads) GASNET_THREADMODE=par ;; --disable-threads) GASNET_THREADMODE=seq ;; - *) - # We pass the unmodified argument to GASNet configure - # Quoting is believed sufficient for embedded whitespace but not quotes - GASNET_CONFIGURE_ARGS+="${GASNET_CONFIGURE_ARGS+ }\"${orig_arg//\"/\\\"}\"" + --enable-debug) GASNET_CODEMODE=debug ; append_gasnet_configure_arg "$orig_arg" ;; + --disable-debug) GASNET_CODEMODE=opt ; append_gasnet_configure_arg "$orig_arg" ;; + + *) # Pass unrecognized args unmodified to GASNet configure + append_gasnet_configure_arg "$orig_arg" ;; esac shift done +if [[ -n "$VERBOSE" ]] ; then +( set +x + echo Command-line arguments: + echo PREFIX=$PREFIX + echo GASNET_CONDUIT=$GASNET_CONDUIT + echo GASNET_CONFIGURE_ARGS=$GASNET_CONFIGURE_ARGS + echo GASNET_THREADMODE=$GASNET_THREADMODE + echo GASNET_CODEMODE=$GASNET_CODEMODE +) +fi + # Early check for pre-installed Homebrew BREW="${BREW:-brew}" -if command -v "$BREW" > /dev/null 2>&1; then - BREW_PREFIX=`$BREW --prefix || exit 0` +if type -P "$BREW" > /dev/null 2>&1; then + BREW_PREFIX=$($BREW --prefix || exit 0) if [ -z ${BREW_PREFIX:+x} ] || [ ! -d "$BREW_PREFIX" ] ; then echo Warning: Failed to detect Homebrew prefix BREW_PREFIX= @@ -133,24 +216,24 @@ if command -v "$BREW" > /dev/null 2>&1; then fi if [ -z ${FC:+x} ] || [ -z ${CC:+x} ]; then - if command -v flang > /dev/null 2>&1; then - FC=`which flang` + if type -P flang > /dev/null 2>&1; then + FC=$(abswhich flang) echo "Setting FC=$FC" if [ -n "$BREW_PREFIX" ] && [[ $FC =~ $BREW_PREFIX ]] ; then # We are using Homebrew flang, so prefer Homebrew clang/clang++ export PATH="$BREW_PREFIX/opt/llvm/bin:$PATH" fi fi - if command -v clang > /dev/null 2>&1; then - CC=`which clang` + if type -P clang > /dev/null 2>&1; then + CC=$(abswhich clang) echo "Setting CC=$CC" fi fi -if [ -n "$CC" ] && ! command -v "$CC" > /dev/null 2>&1; then +if [ -n "${CC:+x}" ] && ! type -P "$CC" > /dev/null 2>&1; then echo "CC=$CC not found. If you don't yet have a C compiler, please leave environment variable CC unset." exit 1 fi -if [ -n "$FC" ] && ! command -v "$FC" > /dev/null 2>&1; then +if [ -n "${FC:+x}" ] && ! type -P "$FC" > /dev/null 2>&1; then echo "FC=$FC not found. If you don't yet have a Fortran compiler, please leave environment variable FC unset." exit 1 fi @@ -162,40 +245,38 @@ if [ -z ${CXX:+x} ] && [ -n "$CC" ] ; then else CXX_guess=g++ fi - if [[ $CC =~ (-[0-9]+)$ ]] ; then + if [[ $CC =~ (-[0-9a-z-]+)$ ]] ; then CXX_guess=${CXX_guess}${BASH_REMATCH[0]} fi - if command -v $CXX_guess > /dev/null 2>&1; then - CXX=`which $CXX_guess` + if type -P $CXX_guess > /dev/null 2>&1; then + CXX=$(abswhich $CXX_guess) echo "Setting CXX=$CXX" fi fi set -u # error on use of undefined variable -if command -v pkg-config > /dev/null 2>&1; then - PKG_CONFIG=`which pkg-config` -fi +# find dependencies, which we might need to install +# allow overrides via envvar +PKG_CONFIG=$(abswhich ${PKG_CONFIG:-pkg-config} silent) -if command -v realpath > /dev/null 2>&1; then - REALPATH=`which realpath` -fi - -if command -v make > /dev/null 2>&1; then - MAKE=`which make` -fi +MAKE=$(abswhich ${MAKE:-gmake} silent) # prefer 'gmake' over 'make' +MAKE=$(abswhich ${MAKE:-make} silent) -if command -v fpm > /dev/null 2>&1; then - FPM=`which fpm` -fi +FPM=$(abswhich ${FPM:-fpm} silent) -if ! command -v git > /dev/null 2>&1; then - echo "git not found. Building Caffeine requires fpm, which uses git to download dependencies." +# FPM disallows override of the git command, so don't allow it here either +# Homebrew requires git and curl to operate, so cannot be used to provide them when they are missing +GIT=$(abswhich git silent) +if [[ -z "$GIT" ]] ; then + echo "git not found. Building Caffeine requires git to download dependencies." echo "Please install git, ensure it is in your PATH, and rerun ./install.sh" exit 1 fi -if ! command -v curl > /dev/null 2>&1; then +# FPM disallows override of the curl command, so don't allow it here either +CURL=$(abswhich curl silent) +if [[ -z "$CURL" ]] ; then echo "curl not found. Please install curl, ensure it is in your PATH, and rerun ./install.sh" exit 1 fi @@ -205,7 +286,7 @@ ask_permission_to_use_homebrew() cat << EOF Either one or more of the environment variables FC and CC are unset or -one or more of the following packages are not in the PATH: pkg-config, realpath, make, fpm. +one or more of the following packages are not in the PATH: pkg-config, make, fpm. If you grant permission to install prerequisites, you will be prompted before each installation. Press 'Enter' to choose the square-bracketed default answer: @@ -228,10 +309,6 @@ EOF ask_permission_to_install_homebrew_package() { echo "" - if [ ! -z ${2+x} ]; then - echo "Homebrew installs $1 collectively in one package named '$2'." - echo "" - fi printf "Is it ok to use Homebrew to install $1? [yes] " } @@ -251,8 +328,6 @@ exit_if_user_declines() if [ -n "$answer" -a "$answer" != "y" -a "$answer" != "Y" -a "$answer" != "Yes" -a "$answer" != "YES" -a "$answer" != "yes" ]; then echo "Installation declined." case ${1:-} in - *GASNet*) - echo "Please ensure the $pkg.pc file is in $PKG_CONFIG_PATH and then rerun './install.sh'." ;; *FC*) echo "To use compilers other than Homebrew-installed LLVM flang and clang," echo "please set the FC and CC environment variables and rerun './install.sh'." ;; @@ -265,29 +340,27 @@ exit_if_user_declines() } DEPENDENCIES_DIR="build/dependencies" -if [ ! -d $DEPENDENCIES_DIR ]; then - mkdir -p $DEPENDENCIES_DIR -fi +mkdir -p $DEPENDENCIES_DIR -if [ -z ${FC:+x} ] || [ -z ${CC:+x} ] || [ -z ${PKG_CONFIG:+x} ] || [ -z ${REALPATH:+x} ] || [ -z ${MAKE:+x} ] || [ -z ${FPM:+x} ] ; then +if [ -z ${FC:+x} ] || [ -z ${CC:+x} ] || [ -z ${PKG_CONFIG:+x} ] || [ -z ${MAKE:+x} ] || [ -z ${FPM:+x} ] ; then ask_permission_to_use_homebrew exit_if_user_declines "brew" - if ! command -v $BREW > /dev/null 2>&1; then + if ! type -P $BREW > /dev/null 2>&1; then ask_permission_to_install_homebrew exit_if_user_declines "brew" - curl -L https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh -o $DEPENDENCIES_DIR/install-homebrew.sh --create-dirs + $CURL -L https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh -o $DEPENDENCIES_DIR/install-homebrew.sh --create-dirs chmod u+x $DEPENDENCIES_DIR/install-homebrew.sh if [ -p /dev/stdin ] && [ $CI = false ]; then cat << EOF -Pipe detected. Installing Homebrew requires sudo privileges, which most likely will -not work if you are installing non-interactively, e.g., via 'yes | ./install.sh'. -To install Caffeine non-interactiely, please rerun the Caffeine installer after +ERROR: Pipe detected. Installing Homebrew requires sudo privileges, +which is unlikely to work if you are installing non-interactively. +To install Caffeine non-interactively, please rerun the Caffeine installer after executing the following command to install Homebrew: "./$DEPENDENCIES_DIR/install-homebrew.sh" EOF @@ -303,7 +376,7 @@ EOF fi fi - BREW_PREFIX=`$BREW --prefix || exit 0` + BREW_PREFIX=$($BREW --prefix || exit 0) if [ -z ${BREW_PREFIX:+x} ] || [ ! -d "$BREW_PREFIX" ] ; then echo Failed to detect Homebrew prefix echo 1 @@ -319,62 +392,72 @@ EOF # Homebrew does not inject clang/clang++ into PATH on macOS export PATH="$BREW_PREFIX/opt/llvm/bin:$PATH" - CC=`which clang` - CXX=`which clang++` - FC=`which flang-new` - for tool in $CC $CXX $FC ; do - if ! command -v $tool > /dev/null 2>&1 ; then - echo Failed to detect Homebrew compiler install at $tool + CC="clang" + CXX="clang++" + FC="flang-new" + for tool in CC CXX FC ; do + if ! type -P ${!tool} > /dev/null 2>&1 ; then + eval echo ERROR: Failed to detect Homebrew compiler install at ${!tool} exit 1 + else + eval $tool=$(abswhich ${!tool}) fi done fi - if [ -z ${REALPATH:+x} ] || [ -z ${MAKE:+x} ] ; then - ask_permission_to_install_homebrew_package "'realpath' and 'make'" "coreutils" - exit_if_user_declines "realpath and make" - $BREW install coreutils - REALPATH=`which realpath` - MAKE=`which make` + if [ -z ${MAKE:+x} ] ; then + ask_permission_to_install_homebrew_package "'make'" + exit_if_user_declines "make" + $BREW install make + MAKE=$(abswhich gmake) fi if [ -z ${PKG_CONFIG:+x} ]; then ask_permission_to_install_homebrew_package "'pkg-config'" exit_if_user_declines "pkg-config" $BREW install pkg-config - PKG_CONFIG=`which pkg-config` + PKG_CONFIG=$(abswhich pkg-config) fi if [ -z ${FPM:+x} ] ; then ask_permission_to_install_homebrew_package "'fpm'" exit_if_user_declines "fpm" $BREW install fpm - FPM=`which fpm` + FPM=$(abswhich fpm) fi fi PREFIX=${PREFIX:-"${HOME}/.local"} mkdir -p "$PREFIX" -PREFIX=`$REALPATH "$PREFIX"` +PREFIX=$(abspath "$PREFIX") echo "PREFIX=$PREFIX" +PKG_CONFIG_DIR="$PREFIX/lib/pkgconfig" +mkdir -p "$PKG_CONFIG_DIR" if [ -z ${PKG_CONFIG_PATH:+x} ]; then PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" else PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH" fi echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" +export PKG_CONFIG_PATH -FPM_FC="$($REALPATH $(command -v $FC))" -if [[ $FPM_FC == *flang* ]]; then - # issue #358: pattern must only match the end, to avoid false positives on directory components - FPM_FC=${FPM_FC/%flang-[1-9][0-9]/flang-new} +FC="$(abswhich $FC)" +if [[ $(basename $FC) == *flang* ]]; then + # old versions of fpm rely on basename 'flang-new' to recognize LLVM flang, + # so look for a corresponding symlink to the same compiler + TRY_FC=${FC/%flang-[1-9][0-9]/flang-new} + TRY_FC=${TRY_FC/%flang/flang-new} + if [[ -x $TRY_FC ]] && [[ $(realpath $TRY_FC) == $(realpath $FC) ]] ; then + FC="$(abswhich $TRY_FC)" + fi fi -FPM_CC="$($REALPATH $(command -v $CC))" +CC="$(abswhich $CC)" +CXX="$(abswhich $CXX)" if [ "${BREW_PREFIX:-unset}" != unset ] ; then # fixups necessitated by using Brew flang: - if [[ $FPM_FC =~ flang ]] && [[ $FPM_FC =~ $BREW_PREFIX ]] ; then + if [[ $FC =~ flang ]] && [[ $FC =~ $BREW_PREFIX ]] ; then # workaround issue #228: clang cannot find Homebrew flang's C header APPEND_CFLAGS="-I$(dirname $(find "$BREW_PREFIX/Cellar/flang" -name ISO_Fortran_binding.h | head -1))" @@ -385,36 +468,17 @@ if [ "${BREW_PREFIX:-unset}" != unset ] ; then fi fi -ask_package_permission() -{ - cat << EOF - -$1 not found in $2 - -Press 'Enter' for the square-bracketed default answer: -EOF - printf "Is it ok to download and install $1? [yes] " -} - pkg="gasnet-$GASNET_CONDUIT-$GASNET_THREADMODE" -export PKG_CONFIG_PATH if ! $PKG_CONFIG $pkg ; then - ask_package_permission "GASNet-EX" "PKG_CONFIG_PATH" - exit_if_user_declines "GASNet-EX" - GASNET_TAR_FILE="$DEPENDENCIES_DIR/GASNet-$GASNET_VERSION.tar.gz" - GASNET_SOURCE_URL="https://github.com/BerkeleyLab/gasnet/releases/download/gex-$GASNET_VERSION/GASNet-$GASNET_VERSION.tar.gz" - if [ ! -d $DEPENDENCIES_DIR ]; then - mkdir -pv $DEPENDENCIES_DIR - fi GASNET_DIR=$DEPENDENCIES_DIR/GASNet-$GASNET_VERSION if [ -d $GASNET_DIR ]; then # clean any existing GASNet build dir we are overwriting rm -Rf $GASNET_DIR fi - curl -L $VERBOSE --retry 10 --retry-all-errors --fail $GASNET_SOURCE_URL -o $GASNET_TAR_FILE + $CURL -L $VERBOSE --retry 10 --retry-all-errors --fail $GASNET_SOURCE_URL -o $GASNET_TAR_FILE tar xvzf $GASNET_TAR_FILE -C $DEPENDENCIES_DIR ( @@ -446,45 +510,40 @@ exit_if_pkg_config_pc_file_missing() exit_if_pkg_config_pc_file_missing "$pkg" -GASNET_LDFLAGS="`$PKG_CONFIG $pkg --variable=GASNET_LDFLAGS`" -GASNET_LIBS="`$PKG_CONFIG $pkg --variable=GASNET_LIBS`" -GASNET_CC="`$PKG_CONFIG $pkg --variable=GASNET_CC`" -GASNET_CFLAGS="`$PKG_CONFIG $pkg --variable=GASNET_CFLAGS`" -GASNET_CPPFLAGS="`$PKG_CONFIG $pkg --variable=GASNET_CPPFLAGS`" - -# Check whether GASNet was installed using Spack. If yes, bail out. -# Note: relies on the fact that most Spack installations have "opt/spack" -# in the directory path, and assumes that the first directory returned -# by pkg-config contains the GASNet lib directory -GASNET_LIBDIR="$(echo $GASNET_LIBS | awk '{print $1};')" +GASNET_LDFLAGS=$($PKG_CONFIG $pkg --variable=GASNET_LDFLAGS) +GASNET_LIBS=$($PKG_CONFIG $pkg --variable=GASNET_LIBS) +GASNET_CC=$($PKG_CONFIG $pkg --variable=GASNET_CC) +GASNET_CFLAGS=$($PKG_CONFIG $pkg --variable=GASNET_CFLAGS) +GASNET_CPPFLAGS=$($PKG_CONFIG $pkg --variable=GASNET_CPPFLAGS) + +# Relies on the first directory in GASNET_LIBS is the GASNet lib directory +GASNET_LIBDIR=$(awk '{print $1};' <<< $GASNET_LIBS) GASNET_LIBDIR=${GASNET_LIBDIR#-L} -case "$GASNET_LIBDIR" in - *spack* ) - cat << EOF + +# Check whether GASNet appears to be a Spack install. If yes, bail out. +# Note: most Spack installations have "opt/spack" in the directory path. +if [[ $GASNET_LIBDIR == *spack* ]] && \ + [[ $(realpath $GASNET_LIBDIR) != $(realpath "$PREFIX/lib") ]]; then + cat << EOF ***NOTICE***: The GASNet library built by Spack is ONLY intended for unit-testing purposes, and is generally UNSUITABLE FOR PRODUCTION USE. The RECOMMENDED way to build GASNet is as an embedded library as configured by the higher-level client runtime package (i.e. Caffeine), including system-specific configuration. Exiting install.sh EOF - exit 1 - ;; - * ) - GASNET_PREFIX=$(dirname $GASNET_LIBDIR) - if [ ! -r "$GASNET_PREFIX/include/gasnetex.h" ] ; then - echo "ERROR: Failed to detect GASNet install prefix from $GASNET_LIBS" - exit 1 - fi - ;; -esac + exit 1 +fi +GASNET_PREFIX=$(dirname $GASNET_LIBDIR) +if [ ! -r "$GASNET_PREFIX/include/gasnetex.h" ] ; then + echo "ERROR: Failed to detect GASNet install prefix from $GASNET_LIBS" + exit 1 +fi # Strip compiler flags # Warning: This assumes the full path doesn't contain any spaces! -GASNET_CC_STRIPPED="$(echo $GASNET_CC | awk '{print $1};')" -GASNET_CC_REAL="$($REALPATH $GASNET_CC_STRIPPED)" - -if [ "$GASNET_CC_REAL" != "$FPM_CC" ]; then - echo "GASNET_CC=$GASNET_CC_REAL" and "FPM_CC=$FPM_CC don't match" +GASNET_CC_STRIPPED=$(awk '{print $1};' <<< $GASNET_CC) +if [ "$(realpath $GASNET_CC_STRIPPED)" != "$(realpath $CC)" ]; then + echo "ERROR: C Compiler mismatch: GASNET_CC=$(realpath $GASNET_CC_STRIPPED) and CC=$(realpath $CC) don't match" exit 1; fi @@ -492,60 +551,103 @@ FPM_TOML="fpm.toml" rm -f $FPM_TOML echo "# DO NOT EDIT OR COMMIT -- Created by caffeine/install.sh" > $FPM_TOML cat manifest/fpm.toml.template >> $FPM_TOML -GASNET_LIB_LOCATIONS=`echo $GASNET_LIBS | awk '{locs=""; for(i = 1; i <= NF; i++) if ($i ~ /^-L/) {locs=(locs " " $i);}; print locs; }'` -GASNET_LIB_NAMES=`echo $GASNET_LIBS | awk '{names=""; for(i = 1; i <= NF; i++) if ($i ~ /^-l/) {names=(names " " $i);}; print names; }' | sed 's/-l//g'` +GASNET_LIB_LOCATIONS=$(awk '{locs=""; for(i = 1; i <= NF; i++) if ($i ~ /^-L/) {locs=(locs " " $i);}; print locs; }' <<< $GASNET_LIBS) +GASNET_LIB_NAMES=$(awk '{names=""; for(i=1; i<=NF; i++) if(sub(/^-l/, "", $i)) names=(names ? names " " : "") $i; print names}' <<< $GASNET_LIBS) if [[ $GASNET_CONDUIT == "udp" ]] ; then GASNET_LIB_NAMES+=" stdc++" # udp-conduit requires C++ libraries fi -FPM_TOML_LINK_ENTRY="link = [\"$(echo ${GASNET_LIB_NAMES} | sed 's/ /", "/g')\"]" +FPM_TOML_LINK_ENTRY="link = [\"$(sed 's/ /", "/g' <<< $GASNET_LIB_NAMES)\"]" echo "${FPM_TOML_LINK_ENTRY}" >> $FPM_TOML -CAFFEINE_PC="$PREFIX/lib/pkgconfig/caffeine.pc" -cat << EOF > $CAFFEINE_PC -CAFFEINE_FPM_LDFLAGS=$GASNET_LDFLAGS $GASNET_LIB_LOCATIONS $APPEND_LDFLAGS -CAFFEINE_FPM_FC=$FPM_FC -CAFFEINE_FPM_CC=$GASNET_CC -CAFFEINE_FPM_CFLAGS=$GASNET_CFLAGS $GASNET_CPPFLAGS $APPEND_CFLAGS -Name: caffeine -Description: The CoArray Fortran Framework of Efficient Interfaces to Network Environments (Caffeine) implements the Parallel Runtime Interface for Fortran (PRIF), providing runtime support for multi-image features in modern Fortran compilers. -URL: https://go.lbl.gov/caffeine -Version: 0.8.1 -EOF - -exit_if_pkg_config_pc_file_missing "caffeine" - +# save Fortran flag user inputs user_compiler_flags="${CPPFLAGS:-} ${FFLAGS:-}" -compiler_version=$($FPM_FC --version) +# compiler-specific flag defaults +FFLAGS="-g" +FFLAGS_debug="-O0" +FFLAGS_opt="-O3" +compiler_version=$($FC --version) if [[ $compiler_version =~ 'flang' ]]; then - compiler_flag="-g -O3" + : # use defaults elif [[ $compiler_version =~ 'GNU Fortran' ]]; then - compiler_flag="-g -O3 -ffree-line-length-0 -Wno-unused-dummy-argument" + FFLAGS="-g -ffree-line-length-0 -Wno-unused-dummy-argument" elif [[ $compiler_version =~ 'LFortran' ]]; then - compiler_flag="-O3 --cpp --realloc-lhs-arrays --separate-compilation --no-style-suggestions --implicit-argument-casting" + # LFortran -g deliberately omitted: not always available, and leads to bizarre errors when it's not + FFLAGS="--cpp --realloc-lhs-arrays --separate-compilation --no-style-suggestions --implicit-argument-casting" else # unknown compiler - compiler_flag="-g -O2" + FFLAGS_opt=-O2 echo "WARNING: Failed to detect a recognized Fortran compiler" fi +if [[ "$GASNET_CODEMODE" == "debug" ]] ; then + FFLAGS="$FFLAGS_debug $FFLAGS" +else + FFLAGS="$FFLAGS_opt $FFLAGS" +fi + # enable Assert's multi-image support with PRIF callbacks provided by libcaffeine -compiler_flag+=" -DASSERT_MULTI_IMAGE -DASSERT_PARALLEL_CALLBACKS" +FFLAGS+=" -DASSERT_MULTI_IMAGE -DASSERT_PARALLEL_CALLBACKS" # enable Julienne's multi-image support with PRIF callbacks provided by julienne-driver -compiler_flag+=" -DHAVE_MULTI_IMAGE_SUPPORT -DJULIENNE_PARALLEL_CALLBACKS" - -if ! [[ "$user_compiler_flags " =~ -[DU]ASSERTIONS[=\ ] ]] ; then - # default to enabling assertions, unless the command line sets a relevant flag - compiler_flag+=" -DASSERTIONS" -fi +FFLAGS+=" -DHAVE_MULTI_IMAGE_SUPPORT -DJULIENNE_PARALLEL_CALLBACKS" if [[ $GASNET_THREADMODE == "par" ]] ; then - compiler_flag+=" -DCAF_THREAD_SAFE" + FFLAGS+=" -DCAF_THREAD_SAFE" fi GASNET_CONDUIT_UPPER=$(tr '[:lower:]' '[:upper:]' <<<$GASNET_CONDUIT) -compiler_flag+=" -DCAF_NETWORK_$GASNET_CONDUIT_UPPER" +FFLAGS+=" -DCAF_NETWORK_$GASNET_CONDUIT_UPPER" + +# Append user flags last to allow command-line overrides +FFLAGS+=" $user_compiler_flags" + +if ! [[ "$FFLAGS " =~ -[DU]ASSERTIONS[=\ ] ]] ; then + # assertions not explicitly enabled or disabled on the command-line + # default assertions based on codemode (--enable-debug) + if [[ "$GASNET_CODEMODE" == "debug" ]] ; then + FFLAGS+=" -DASSERTIONS" + fi +fi + +# Ensure that certain preprocessor settings in FFLAGS are always appended to CFLAGS +for opt in $FFLAGS; do + case "$opt" in + -DASSERTIONS* | -UASSERTIONS* | -DFORCE_PRIF_* | -UFORCE_PRIF_*) + APPEND_CFLAGS+=" $opt" + ;; + esac +done + +# flag outputs +CAFFEINE_CFLAGS="$GASNET_CFLAGS $GASNET_CPPFLAGS $APPEND_CFLAGS" +CAFFEINE_LDFLAGS="$GASNET_LDFLAGS $GASNET_LIB_LOCATIONS $APPEND_LDFLAGS" + +CAFFEINE_PC="caffeine-$GASNET_CONDUIT-$GASNET_THREADMODE.pc" +cat << EOF > "$PKG_CONFIG_DIR/$CAFFEINE_PC" +# WARNING: This file is automatically generated - do NOT edit directly +# Copyright 2026, The Regents of the University of California +# Terms of use are as specified in license.txt + +CAFFEINE_FC=$FC +CAFFEINE_CC=$CC +CAFFEINE_FFLAGS=$FFLAGS +CAFFEINE_CFLAGS=$APPEND_CFLAGS +CAFFEINE_LDFLAGS="-L$PREFIX/lib $APPEND_LDFLAGS" +CAFFEINE_NETWORK=$GASNET_CONDUIT +CAFFEINE_THREADMODE=$GASNET_THREADMODE +CAFFEINE_CODEMODE=$GASNET_CODEMODE + +Name: caffeine +Description: The CoArray Fortran Framework of Efficient Interfaces to Network Environments (Caffeine) implements the Parallel Runtime Interface for Fortran (PRIF), providing runtime support for multi-image features in modern Fortran compilers. +URL: https://go.lbl.gov/caffeine +Version: 0.8.1 +Requires: gasnet-$GASNET_CONDUIT-$GASNET_THREADMODE +Cflags: \${CAFFEINE_CFLAGS} +Libs: \${CAFFEINE_LDFLAGS} -lcaffeine-$GASNET_CONDUIT-$GASNET_THREADMODE +EOF +ln -sf "$CAFFEINE_PC" "$PKG_CONFIG_DIR/caffeine-$GASNET_CONDUIT.pc" +ln -sf "$CAFFEINE_PC" "$PKG_CONFIG_DIR/caffeine.pc" + +exit_if_pkg_config_pc_file_missing "caffeine" -# Should come last to allow command-line overrides -compiler_flag+=" $user_compiler_flags" case $GASNET_CONDUIT in ibv|ofi|ucx) @@ -558,7 +660,7 @@ case $GASNET_CONDUIT in GASNET_RUNNER_ARG="${GASNET_RUNNER_ARG:-mpirun -n \${CAF_IMAGES:-2}}" ;; smp) - GASNET_RUNNER_ARG="${GASNET_RUNNER_ARG:-env GASNET_PSHM_NODES=\${CAF_IMAGES:-\${GASNET_PSHM_NODES:-}}}" + GASNET_RUNNER_ARG="${GASNET_RUNNER_ARG:-env GASNET_PSHM_NODES=\${CAF_IMAGES:-\${GASNET_PSHM_NODES:-2}}}" ;; *) GASNET_RUNNER_ARG="${GASNET_RUNNER_ARG:-}" @@ -567,26 +669,32 @@ esac RUN_FPM_SH="run-fpm.sh" cat << EOF > $RUN_FPM_SH -#!/bin/sh +#!/bin/bash #-- DO NOT EDIT -- created by caffeine/install.sh -FPM="${FPM}" -FC="`$PKG_CONFIG caffeine --variable=CAFFEINE_FPM_FC`" -CC="`$PKG_CONFIG caffeine --variable=CAFFEINE_FPM_CC`" +FPM="$FPM" +FC="$FC" +CC="$CC" NATIVEFLAGS="" -RAWFLAGS="$compiler_flag" +RAWFLAGS="$FFLAGS" FFLAGS="\$NATIVEFLAGS \$RAWFLAGS" -CFLAGS="`$PKG_CONFIG caffeine --variable=CAFFEINE_FPM_CFLAGS`" -LDFLAGS="`$PKG_CONFIG caffeine --variable=CAFFEINE_FPM_LDFLAGS`" -FPM_DRIVER=\${FPM_DRIVER:-\`realpath \$0\`} +CFLAGS="$CAFFEINE_CFLAGS" +LDFLAGS="$CAFFEINE_LDFLAGS" +FPM_DRIVER=\${FPM_DRIVER:-\$([[ "\$0" == /* ]] && echo "\$0" || echo "\$PWD/\$0")} export FPM_DRIVER fpm_sub_cmd=\$1; shift -if echo "--help -help --version -version --list -list new update list clean publish" | grep -w -q -e "\$fpm_sub_cmd" ; then +if [[ "\$fpm_sub_cmd" == "install" && "\$1" != "--list" ]] ; then + echo "ERROR: Please use install.sh to install Caffeine." + exit 1 +fi +case "\$fpm_sub_cmd" in +--help|-help|help|--version|-version|--list|-list|new|update|list|clean|publish) set -x exec "\$FPM" "\$fpm_sub_cmd" "\$@" -elif echo "build test run install" | grep -w -q -e "\$fpm_sub_cmd" ; then + ;; +build|test|run|install) sed -i.bak 's/^link = .*\$/$FPM_TOML_LINK_ENTRY/' $FPM_TOML rm -f $FPM_TOML.bak # issue 282: this is the only portable way to use sed -i - if test -n "$GASNET_RUNNER_ARG" && echo "test run" | grep -w -q -e "\$fpm_sub_cmd" ; then + if [[ -n "$GASNET_RUNNER_ARG" && " test run " == *" \$fpm_sub_cmd "* ]]; then set -- "--runner=$GASNET_RUNNER_ARG" "\$@" fi set -x @@ -598,17 +706,19 @@ elif echo "build test run install" | grep -w -q -e "\$fpm_sub_cmd" ; then --c-flag "\$CFLAGS" \\ --link-flag "\$LDFLAGS" \\ "\$@" -elif echo "set-native" | grep -w -q -e "\$fpm_sub_cmd" ; then + ;; +set-native) set -e mkdir -p build cmd="\$FC \$RAWFLAGS app/print-native-flags.F90 -o build/print-native-flags $APPEND_LDFLAGS" eval \$cmd || (set -x ; eval \$cmd) - NATIVEFLAGS="\`build/print-native-flags\`" + NATIVEFLAGS=\$(build/print-native-flags) rm -f build/print-native-flags sed -i.bak 's/^NATIVEFLAGS=.*\$/NATIVEFLAGS="'"\$NATIVEFLAGS"'"/' \$FPM_DRIVER rm -f \$FPM_DRIVER.bak echo NATIVEFLAGS=\"\$NATIVEFLAGS\" -elif echo "info" | grep -w -q -e "\$fpm_sub_cmd" ; then + ;; +info) LINE=-------------------------------------------------- SRCDIR=\$(dirname \$FPM_DRIVER) GASNETDIR="$GASNET_PREFIX" @@ -616,21 +726,19 @@ elif echo "info" | grep -w -q -e "\$fpm_sub_cmd" ; then echo \$LINE echo Version info: echo Caffeine \$(grep version \$SRCDIR/fpm.toml) - if test -d \$SRCDIR/.git ; then + if [[ -d \$SRCDIR/.git ]]; then GITVER=\$( ( cd \$SRCDIR && git describe --long --dirty --always ) 2> /dev/null) - if test -n "\$GITVER"; then - echo " git describe: \$GITVER" - fi + [[ -n "\$GITVER" ]] && echo " git describe: \$GITVER" fi - if test -r "\$GASNETCONFIG"; then + if [[ -r "\$GASNETCONFIG" ]]; then echo GASNet version \$(grep GASNETI_RELEASE_VERSION \$GASNETCONFIG | cut -d' ' -f3-) fi grep -e assert -e julienne \$SRCDIR/fpm.toml echo \$LINE echo Platform info: uname -a - if test -r /etc/os-release ; then grep -e NAME -e VERSION /etc/os-release ; fi - if test -x /usr/bin/sw_vers ; then /usr/bin/sw_vers ; fi + [[ -r /etc/os-release ]] && grep -e NAME -e VERSION /etc/os-release + [[ -x /usr/bin/sw_vers ]] && /usr/bin/sw_vers echo \$LINE echo Install settings: echo ID="\$(date) \$(whoami)" @@ -639,13 +747,14 @@ elif echo "info" | grep -w -q -e "\$fpm_sub_cmd" ; then echo FC=\$FC echo CC=\$CC echo FFLAGS=\$FFLAGS - echo CFLAGS=\$FFLAGS + echo CFLAGS=\$CFLAGS echo LDFLAGS=\$LDFLAGS grep -e link \$SRCDIR/fpm.toml echo GASNET=\$GASNETDIR echo GASNET_CONDUIT=$GASNET_CONDUIT + echo GASNET_CODEMODE=$GASNET_CODEMODE echo GASNET_THREADMODE=$GASNET_THREADMODE - if test -r "\$GASNETCONFIG"; then + if [[ -r "\$GASNETCONFIG" ]]; then grep -e GASNETI_BUILD_ID -e GASNETI_CONFIGURE_ARGS \$GASNETCONFIG | cut -d' ' -f2- fi for tool in FPM FC CC ; do @@ -659,11 +768,12 @@ elif echo "info" | grep -w -q -e "\$fpm_sub_cmd" ; then \$toolval --version done echo \$LINE -else + ;; +*) echo "ERROR: Unrecognized fpm subcommand \$fpm_sub_cmd" \$FPM list exit 1 -fi +esac EOF chmod u+x $RUN_FPM_SH # for backwards-compatibility of instructions/scripting: diff --git a/src/caffeine/caffeine.c b/src/caffeine/caffeine.c index 0b4e23fc3..5af811681 100644 --- a/src/caffeine/caffeine.c +++ b/src/caffeine/caffeine.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -20,6 +19,13 @@ #include "caffeine-internal.h" #include "version.h" +// Ensure assertion enforcement in this file tracks the Caffeine ASSERTIONS setting +#undef NDEBUG +#if !ASSERTIONS +#define NDEBUG 1 +#endif +#include + enum { UNRECOGNIZED_TYPE, ERRMSG_TOO_SHORT @@ -51,18 +57,13 @@ CAF_IDENT(Network, CAF_STRINGIFY(GASNET_CONDUIT_NAME)); CAF_IDENT(LibraryVersion, CAF_STRINGIFY(CAF_RELEASE_VERSION_MAJOR) "." CAF_STRINGIFY(CAF_RELEASE_VERSION_MINOR) "." CAF_STRINGIFY(CAF_RELEASE_VERSION_PATCH)); -#if 0 -// TODO: PRIFVersion does not correctly respect FORCE_PRIF_X flags unless they are also passed in CFLAGS CAF_IDENT(PRIFVersion, CAF_STRINGIFY(CAF_PRIF_VERSION_MAJOR) "." CAF_STRINGIFY(CAF_PRIF_VERSION_MINOR)); -#endif -#if 0 -#if ASSERTIONS // TODO: This doesn't yet work, until we fix issue #241 +#if ASSERTIONS CAF_IDENT(Assertions, "1"); #else CAF_IDENT(Assertions, "0"); #endif -#endif CAF_IDENT(BuildTime, __DATE__ " " __TIME__ ); CAF_IDENT(CompilerID, PLATFORM_COMPILER_IDSTR); CAF_IDENT(GASNetConfig, GASNET_CONFIG_STRING); diff --git a/src/caffeine/co_broadcast_s.F90 b/src/caffeine/co_broadcast_s.F90 index c9838274f..0bd52f9d9 100644 --- a/src/caffeine/co_broadcast_s.F90 +++ b/src/caffeine/co_broadcast_s.F90 @@ -25,8 +25,6 @@ subroutine contiguous_co_broadcast(a, source_image, stat, errmsg, errmsg_alloc) if (present(stat)) stat=0 call caf_co_broadcast(a, source_image, product(shape(a)), current_team%info%gex_team) - ! With a compliant Fortran 2018 compiler, pass in c_sizeof(a) as the `Nelem` argument - ! and eliminate the calculation of num_elements*sizeof(a) in caffeine.c. end subroutine module procedure prif_co_broadcast_cptr