diff --git a/build-config/hypre/meson.build b/build-config/hypre/meson.build new file mode 100644 index 0000000..72951bf --- /dev/null +++ b/build-config/hypre/meson.build @@ -0,0 +1,2 @@ +hypre_sp = cmake.subproject('hypre') +hypre_dep = hypre_sp.dependency('HYPRE') diff --git a/build-config/meson.build b/build-config/meson.build index f7f6466..18e4720 100644 --- a/build-config/meson.build +++ b/build-config/meson.build @@ -5,3 +5,18 @@ subdir('yaml-cpp') subdir('quill') subdir('boost') subdir('opatIO') +subdir('mpi') +subdir('hypre') + +# Set the config file error handling options +configErr = get_option('config_error_handling') + +# build up any -D flags we need +commonCppArgs = [] +if configErr == 'warn' + commonCppArgs += ['-DCONFIG_WARN'] +elif configErr == 'harsh' + commonCppArgs += ['-DCONFIG_HARSH'] +endif + +add_project_arguments(commonCppArgs, language: 'cpp') \ No newline at end of file diff --git a/build-config/mpi/.mpi_installed b/build-config/mpi/.mpi_installed new file mode 100644 index 0000000..e69de29 diff --git a/build-config/mpi/install.sh b/build-config/mpi/install.sh new file mode 100755 index 0000000..9a02198 --- /dev/null +++ b/build-config/mpi/install.sh @@ -0,0 +1,272 @@ +#!/usr/bin/env bash +# +# install_mpi.sh - Interactive installation script for MPI. +# +# This script checks if MPI is installed (by trying to compile a simple MPI program). +# If not found, it prompts the user to install MPI using the native package manager for: +# - FreeBSD, Ubuntu, Debian, Fedora, Arch, Mint, Manjaro, macOS, OpenSuse, and NixOS. +# +# All output is colorized for clarity and logged to mpi-install-log.txt. + +set -e + +# ANSI color codes. +RED="\033[0;31m" +GREEN="\033[0;32m" +YELLOW="\033[0;33m" +BLUE="\033[0;34m" +NC="\033[0m" # No Color + +# Log file. +LOGFILE="mpi-install-log.txt" +touch "$LOGFILE" # Ensure log file exists + +# Log function: prints to stdout and appends to logfile. +log() { + local message="$1" + # Print the colored message to stdout. + echo -e "$message" + # Strip ANSI escape sequences and append the cleaned message to the log file. + echo -e "$message" | sed -r 's/\x1B\[[0-9;]*[mK]//g' >> "$LOGFILE" +} + +# Function to check if MPI (specifically mpicc and a compilable environment) is installed. +check_mpi_installed() { + log "${BLUE}[Info] Checking for MPI (e.g., Open MPI, MPICH) using mpicc...${NC}" + local tmpDir="mpiTest" # Define tmpDir locally + + # Clean up any previous test directory + if [[ -d "$tmpDir" ]]; then + rm -rf "$tmpDir" + fi + mkdir "$tmpDir" + local sourceFile="$tmpDir/test_mpi.c" + local outputFile="$tmpDir/test_mpi_app" + + # Write a minimal MPI C program + cat > "$sourceFile" < +#include + +int main(int argc, char** argv) { + if (MPI_Init(NULL, NULL) != MPI_SUCCESS) { + // Using fprintf for stderr in case stdout is redirected by build tools + fprintf(stderr, "MPI_Init failed\n"); + return 1; + } + int world_size; + if (MPI_Comm_size(MPI_COMM_WORLD, &world_size) != MPI_SUCCESS) { + fprintf(stderr, "MPI_Comm_size failed\n"); + MPI_Finalize(); // Attempt to finalize even if a step fails + return 1; + } + int world_rank; + if (MPI_Comm_rank(MPI_COMM_WORLD, &world_rank) != MPI_SUCCESS) { + fprintf(stderr, "MPI_Comm_rank failed\n"); + MPI_Finalize(); + return 1; + } + // A simple printf to ensure it links and runs, though not strictly necessary for the check + // printf("MPI Initialized successfully on rank %d of %d\\n", world_rank, world_size); + if (MPI_Finalize() != MPI_SUCCESS) { + fprintf(stderr, "MPI_Finalize failed\n"); + return 1; + } + return 0; +} +EOF + + # Try to find mpicc and compile the test program + if command -v mpicc &> /dev/null; then + # Log the compilation command + log "${BLUE}[Info] Attempting to compile MPI test program with: mpicc \"$sourceFile\" -o \"$outputFile\"${NC}" + # Attempt compilation, redirecting stdout and stderr of mpicc to the log file for details + if mpicc "$sourceFile" -o "$outputFile" >> "$LOGFILE" 2>&1; then + log "${GREEN}[Success] MPI compiler (mpicc) found and test program compiled successfully.${NC}" + # Optional: Could add a mpiexec -n 1 "$outputFile" check here for further validation + rm -rf "$tmpDir" + return 0 # MPI seems to be installed and working + else + log "${RED}[Error] MPI compiler (mpicc) found, but failed to compile the test program. See $LOGFILE for details.${NC}" + fi + else + log "${RED}[Error] MPI compiler (mpicc) not found in PATH.${NC}" + fi + + # Cleanup and return failure + rm -rf "$tmpDir" + return 1 +} + +# Prompt the user for a yes/no answer. +prompt_yes_no() { + local promptMsg="$1" + while true; do + read -r -p "$(echo -e "${YELLOW}$promptMsg${NC} (y/n): ")" answer + case "$answer" in + [Yy]* ) return 0;; + [Nn]* ) return 1;; + * ) echo -e "${RED}Please answer yes (y) or no (n).${NC}";; + esac + done +} + +# Detect OS and Distribution. +OS=$(uname -s) +DISTRO="unknown" +if [ -f /etc/os-release ]; then + # shellcheck disable=SC1091 + . /etc/os-release + DISTRO=$ID +elif [ -f /etc/lsb-release ]; then # Fallback for older systems + # shellcheck disable=SC1091 + . /etc/lsb-release + DISTRO=$DISTRIB_ID +fi +# Normalize some distro names +DISTRO=$(echo "$DISTRO" | tr '[:upper:]' '[:lower:]') + + +if [[ "$OS" == "Darwin" ]]; then + OS="macOS" +fi + +if [[ $OS == "macOS" ]]; then + log "${BLUE}[Info] Detected OS: ${OS}${NC}" +else + log "${BLUE}[Info] Detected OS: ${OS} Distribution: ${DISTRO}${NC}" +fi + +# Main script logic +log "${BLUE}[Info] Starting MPI installation check...${NC}" + +if check_mpi_installed; then + log "${GREEN}[Success] MPI appears to be already installed and configured on your system.${NC}" + log "${GREEN}[Success] Your MPI-dependent application can now proceed.${NC}" + exit 0 +else + log "${YELLOW}[Warning] MPI was not detected or is not properly configured on your system.${NC}" + if prompt_yes_no "[Query] Would you like this script to attempt to install MPI (Open MPI) now?"; then + log "${BLUE}[Info] Attempting to install MPI...${NC}" + case "$OS" in + "macOS") + if ! command -v brew &> /dev/null; then + log "${YELLOW}[Warning] Homebrew is not installed. It is highly recommended for installing MPI on macOS.${NC}" + if prompt_yes_no "[Query] Would you like to install Homebrew now?"; then + log "${BLUE}[Info] Installing Homebrew...${NC}" + # Piping to tee to ensure output is captured in the log file + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2>&1 | tee -a "$LOGFILE" + else + log "${RED}[Error] Homebrew is required for an easy MPI installation on macOS using this script. Aborting.${NC}" + exit 1 + fi + fi + log "${BLUE}[Info] Running: brew install open-mpi${NC}" + brew install open-mpi 2>&1 | tee -a "$LOGFILE" + ;; + "Linux") + case "$DISTRO" in + "ubuntu"|"debian"|"linuxmint"|"pop"|"raspbian") # Added pop and raspbian + log "${BLUE}[Info] Running: sudo apt-get update && sudo apt-get install -y libopenmpi-dev${NC}" + sudo apt-get update 2>&1 | tee -a "$LOGFILE" + sudo apt-get install -y libopenmpi-dev 2>&1 | tee -a "$LOGFILE" + ;; + "fedora"|"centos"|"rhel") # Added centos and rhel (dnf is common now) + if command -v dnf &> /dev/null; then + log "${BLUE}[Info] Running: sudo dnf install -y openmpi-devel${NC}" + sudo dnf install -y openmpi-devel 2>&1 | tee -a "$LOGFILE" + elif command -v yum &> /dev/null; then # Fallback for older CentOS/RHEL + log "${BLUE}[Info] Running: sudo yum install -y openmpi-devel${NC}" + sudo yum install -y openmpi-devel 2>&1 | tee -a "$LOGFILE" + else + log "${RED}[Error] Neither dnf nor yum found. Cannot install MPI on this Fedora/RHEL-like system automatically.${NC}" + exit 1 + fi + ;; + "arch"|"manjaro"|"endeavouros") # Added endeavouros + log "${BLUE}[Info] Running: sudo pacman -S --noconfirm openmpi${NC}" + sudo pacman -S --noconfirm openmpi 2>&1 | tee -a "$LOGFILE" + ;; + "opensuse"|"opensuse-leap"|"opensuse-tumbleweed") # More specific opensuse IDs + log "${BLUE}[Info] Running: sudo zypper install -y openmpi-devel${NC}" # Or openmpi4-devel, openmpi-devel is often a meta package + sudo zypper install -y openmpi-devel 2>&1 | tee -a "$LOGFILE" + ;; + "nixos") + log "${BLUE}[Info] On NixOS, you typically manage packages declaratively or with nix-shell.${NC}" + log "${BLUE}[Info] To install Open MPI imperatively: nix-env -iA nixpkgs.openmpi${NC}" + log "${YELLOW}[Warning] This script will not run nix-env automatically. Please install manually if desired.${NC}" + log "${YELLOW}[Info] For declarative environment, add 'openmpi' to your configuration.nix or shell.nix.${NC}" + # nix-env -iA nixpkgs.openmpi 2>&1 | tee -a "$LOGFILE" # Decided against auto-running this for NixOS + ;; + *) + log "${RED}[Error] Your Linux distribution ($DISTRO) is not recognized or not explicitly supported for automatic MPI installation by this script.${NC}" + log "${RED}[Info] Please try installing Open MPI or another MPI implementation manually.${NC}" + exit 1 + ;; + esac + ;; + "FreeBSD") + log "${BLUE}[Info] Running: sudo pkg install openmpi${NC}" + sudo pkg install -y openmpi 2>&1 | tee -a "$LOGFILE" + ;; + *) + log "${RED}[Error] Automatic MPI installation is not supported on OS: ${OS} by this script.${NC}" + log "${RED}[Info] Please try installing Open MPI or another MPI implementation manually.${NC}" + exit 1 + ;; + esac + + # Verify MPI installation after attempting to install + log "${BLUE}[Info] Verifying MPI installation attempt...${NC}" + if check_mpi_installed; then + log "${GREEN}[Success] MPI installation appears to have succeeded.${NC}" + else + log "${RED}[Error] MPI installation appears to have failed or is still not correctly configured. Please check $LOGFILE and install MPI manually.${NC}" + exit 1 + fi + + else + log "${YELLOW}[Info] User chose not to install MPI automatically.${NC}" + log "${RED}[Error] MPI is required for the application to proceed.${NC}" + log "${YELLOW}Please install an MPI implementation (e.g., Open MPI, MPICH) manually using the appropriate command for your system:${NC}" + case "$OS" in + "macOS") + log "${YELLOW} Example: brew install open-mpi (Install Homebrew from https://brew.sh if not present)${NC}" + ;; + "Linux") + case "$DISTRO" in + "ubuntu"|"debian"|"linuxmint"|"pop"|"raspbian") + log "${YELLOW} Example: sudo apt-get install libopenmpi-dev${NC}" + ;; + "fedora"|"centos"|"rhel") + log "${YELLOW} Example: sudo dnf install openmpi-devel (or sudo yum install openmpi-devel)${NC}" + ;; + "arch"|"manjaro"|"endeavouros") + log "${YELLOW} Example: sudo pacman -S openmpi${NC}" + ;; + "opensuse"|"opensuse-leap"|"opensuse-tumbleweed") + log "${YELLOW} Example: sudo zypper install openmpi-devel${NC}" + ;; + "nixos") + log "${YELLOW} Example: nix-env -iA nixpkgs.openmpi or add to configuration.nix${NC}" + ;; + *) + log "${YELLOW} Please consult your distribution's documentation for installing an MPI development package (e.g., Open MPI, MPICH).${NC}" + ;; + esac + ;; + "FreeBSD") + log "${YELLOW} Example: sudo pkg install openmpi${NC}" + ;; + *) + log "${YELLOW} Please consult your operating system's documentation for installing an MPI development package.${NC}" + ;; + esac + exit 1 + fi +fi + +log "${GREEN}[SUCCESS] MPI is installed and ready for use!${NC}" +log "${GREEN}[SUCCESS] 4DSSE installation can now proceed.${NC}" +exit 0 + diff --git a/build-config/mpi/meson.build b/build-config/mpi/meson.build index e69de29..775a46d 100644 --- a/build-config/mpi/meson.build +++ b/build-config/mpi/meson.build @@ -0,0 +1 @@ +mpi_dep = dependency('mpi', version: '>=5.0.0', language: 'cpp') \ No newline at end of file