Skip to content

[IGNORE] Backport #3093 #9150

[IGNORE] Backport #3093

[IGNORE] Backport #3093 #9150

Workflow file for this run

name: NEURON CI
concurrency:
group: ${{ github.workflow }}#${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- master
- release/**
pull_request:
branches:
- master
- release/**
# TODO : https://github.com/neuronsimulator/nrn/issues/1063
# paths-ignore:
# - '**.md'
# - '**.rst'
# - 'docs/**'
env:
BUILD_TYPE: Release
DESIRED_CMAKE_VERSION: 3.15.0
PY_MIN_VERSION: '3.7'
PY_MAX_VERSION: '3.11'
jobs:
ci:
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} - ${{ matrix.config.build_mode }} (${{ matrix.config.cmake_option }}${{ matrix.config.config_options }}${{ matrix.config.matrix_eval }})
timeout-minutes: 45
env:
INSTALL_DIR: install
SDK_ROOT: $(xcrun --sdk macosx --show-sdk-path)
SKIP_WHEELHOUSE_REPAIR: true
BUILD_TYPE: Release
DESIRED_CMAKE_VERSION: 3.15.0
PY_MIN_VERSION: ${{ matrix.config.python_min_version || '3.8' }}
PY_MAX_VERSION: ${{ matrix.config.python_max_version || '3.11' }}
MUSIC_INSTALL_DIR: /opt/MUSIC
strategy:
matrix:
os: [ macOS-12, ubuntu-20.04]
config:
- { matrix_eval : "CC=gcc-9 CXX=g++-9", build_mode: "setuptools"}
- { matrix_eval : "CC=gcc-8 CXX=g++-8", build_mode: "cmake", music: ON}
- { matrix_eval : "CC=gcc-9 CXX=g++-9", build_mode: "cmake", python_dynamic: ON}
- { matrix_eval : "CC=gcc-7 CXX=g++-7" , build_mode: "cmake", cmake_option: "-DNRN_ENABLE_CORENEURON=ON"}
- { matrix_eval : "CC=gcc-7 CXX=g++-7", build_mode: "cmake", cmake_option: "-DNRN_ENABLE_MPI=OFF -DNRN_ENABLE_INTERVIEWS=OFF -DNRN_ENABLE_CORENEURON=ON"}
- { matrix_eval : "CC=gcc-10 CXX=g++-10", build_mode: "cmake", cmake_option: "-DNRN_ENABLE_PYTHON=OFF -DNRN_ENABLE_RX3D=OFF -DNRN_ENABLE_CORENEURON=ON"}
include:
- os: ubuntu-22.04
config:
build_mode: cmake
# TODO: -DCORENRN_ENABLE_NMODL=ON -DNMODL_SANITIZERS=undefined
cmake_option: -DNRN_ENABLE_CORENEURON=ON
-DNRN_ENABLE_INTERVIEWS=OFF -DCORENRN_SANITIZERS=undefined
flag_warnings: ON
sanitizer: undefined
- os: ubuntu-22.04
config:
build_mode: cmake
# TODO: -DCORENRN_ENABLE_NMODL=ON -DNMODL_SANITIZERS=address,leak
# TODO: CoreNEURON is only LeakSanitizer-clean if we disable MPI
cmake_option: -DNRN_ENABLE_CORENEURON=ON
-DNRN_ENABLE_INTERVIEWS=OFF -DCORENRN_SANITIZERS=address
# TODO: address-leak is the dream, but there are many problems,
# including external ones from the MPI implementations
sanitizer: address
fail-fast: false
steps:
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v2
with:
cmake-version: ${{ env.DESIRED_CMAKE_VERSION }}
- name: Fix kernel mmap rnd bits
if: ${{matrix.os == 'ubuntu-22.04'}}
# Asan in llvm 14 provided in ubuntu 22.04 is incompatible with
# high-entropy ASLR in much newer kernels that GitHub runners are
# using leading to random crashes: https://reviews.llvm.org/D148280
run: sudo sysctl vm.mmap_rnd_bits=28
- name: Install homebrew packages
if: startsWith(matrix.os, 'macOS')
run: |
brew install ccache coreutils doxygen flex mpich ninja xz autoconf autoconf automake libtool
brew unlink mpich
brew install openmpi
brew install --cask xquartz
echo /usr/local/opt/flex/bin >> $GITHUB_PATH
# Core https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
echo CMAKE_BUILD_PARALLEL_LEVEL=3 >> $GITHUB_ENV
echo CTEST_PARALLEL_LEVEL=3 >> $GITHUB_ENV
echo CI_OS_NAME=osx >> $GITHUB_ENV
shell: bash
- name: Install apt packages
if: startsWith(matrix.os, 'ubuntu')
run: |
sudo apt-get install build-essential ccache libopenmpi-dev \
libmpich-dev libx11-dev libxcomposite-dev mpich ninja-build \
openmpi-bin patchelf
# The sanitizer builds use ubuntu 22.04
if [[ "${{matrix.os}}" == "ubuntu-20.04" ]]; then
sudo apt-get install g++-7 g++-8
fi
# Core https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
echo CMAKE_BUILD_PARALLEL_LEVEL=2 >> $GITHUB_ENV
echo CTEST_PARALLEL_LEVEL=2 >> $GITHUB_ENV
echo CI_OS_NAME=linux >> $GITHUB_ENV
shell: bash
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Set up Python@${{ env.PY_MIN_VERSION }}
if: ${{matrix.config.python_dynamic == 'ON'}}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PY_MIN_VERSION }}
- name: Install Python@${{ env.PY_MIN_VERSION }} dependencies
if: ${{ matrix.config.python_dynamic == 'ON' }}
working-directory: ${{runner.workspace}}/nrn
run: |
python -m pip install --upgrade pip -r nrn_requirements.txt
- name: Set up Python@${{ env.PY_MAX_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PY_MAX_VERSION }}
- name: Install Python@${{ env.PY_MAX_VERSION }} dependencies
working-directory: ${{runner.workspace}}/nrn
run: |
python -m pip install --upgrade pip -r nrn_requirements.txt
- name: Setup MUSIC
if: matrix.config.music == 'ON'
run: |
python3 -m venv music-venv
source music-venv/bin/activate
python3 -m pip install mpi4py "cython<3" "numpy<2"
sudo mkdir -p $MUSIC_INSTALL_DIR
sudo chown -R $USER $MUSIC_INSTALL_DIR
# Stable build: https://github.com/INCF/MUSIC/archive/refs/heads/switch-to-MPI-C-interface.zip @ f33b66ea9348888eed1761738ab48c23ffc8a0d0
curl -L -o MUSIC.zip https://codeload.github.com/INCF/MUSIC/zip/f33b66ea9348888eed1761738ab48c23ffc8a0d0
unzip MUSIC.zip && mv MUSIC-* MUSIC && cd MUSIC
./autogen.sh
# workaround for MUSIC on MacOS 12
if [[ "${{matrix.os}}" == "macOS-12" ]]; then
MPI_CXXFLAGS="-g" MPI_CFLAGS="-g" MPI_LDFLAGS="-g" CC=mpicc CXX=mpicxx ./configure --with-python-sys-prefix --prefix=$MUSIC_INSTALL_DIR --disable-anysource
else
./configure --with-python-sys-prefix --prefix=$MUSIC_INSTALL_DIR --disable-anysource
fi
make -j install
deactivate
working-directory: ${{runner.temp}}
- name: Register gcc problem matcher
if: ${{matrix.config.flag_warnings == 'ON'}}
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
- name: Register sanitizer problem matcher
if: ${{matrix.config.sanitizer}}
run: echo "::add-matcher::.github/problem-matchers/${{matrix.config.sanitizer}}.json"
- name: Hash config dictionary
run: |
cat << EOF > matrix.json
${{toJSON(matrix.config)}}
EOF
echo matrix.config JSON:
cat matrix.json
echo -----
- name: Restore compiler cache
uses: actions/cache@v4
with:
path: ${{runner.workspace}}/ccache
save-always: true
key: ${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.ref}}-
${{matrix.os}}-${{hashfiles('matrix.json')}}-
- name: Build and Test
id: build-test
shell: bash
working-directory: ${{runner.workspace}}/nrn
run: |
# OS related
if [ "$RUNNER_OS" == "Linux" ]; then
export ${MATRIX_EVAL};
export SHELL="/bin/bash"
else
export CXX=${CXX:-g++};
export CC=${CC:-gcc};
fi
if [ "$RUNNER_OS" == "macOS" ]; then
# TODO - this is a workaround that was implemented for Azure being reported as getting stuck.
# However it does not get stuck: neuron module not found and script goes to interpreter, seeming stuck.
# This needs to be addressed and SKIP_EMBEDED_PYTHON_TEST logic removed everywhere.
export SKIP_EMBEDED_PYTHON_TEST="true"
fi
# Python setup
export PYTHONPATH=$PYTHONPATH:$INSTALL_DIR/lib/python/
# Python setup
export PYTHON_MIN=$(command -v $PYTHON_MIN_NAME);
export PYTHON_MAX=$(command -v $PYTHON_MAX_NAME);
export PYTHON=$PYTHON_MAX
if [ "$RUNNER_OS" == "macOS" ]; then
# Python is not installed as a framework, so we need to writ 'backend: TkAgg' to `matplotlibrc`.
# Since we are in a virtual environment, we cannot use `$HOME/matplotlibrc`
# The following solution is generic and relies on `matplotlib.__file__` to know where to append backend setup.
$PYTHON -c "import os,matplotlib; f =open(os.path.join(os.path.dirname(matplotlib.__file__), 'mpl-data/matplotlibrc'),'a'); f.write('backend: TkAgg');f.close();"
fi;
# Some logging
echo $LANG
echo $LC_ALL
python3 -c 'import os,sys; os.set_blocking(sys.stdout.fileno(), True)'
cmake --version
# different builds with CMake
if [[ "$BUILD_MODE" == "cmake" ]]; then
cmake_args=(-G Ninja)
# Sanitizer-specific setup
if [[ -n "${{matrix.config.sanitizer}}" ]]; then
CC=$(command -v clang-14)
CXX=$(command -v clang++-14)
symbolizer_path=$(realpath $(command -v llvm-symbolizer-14))
echo symbolizer_path=${symbolizer_path}
cmake_args+=(-DCMAKE_BUILD_TYPE=Custom \
-DCMAKE_C_FLAGS="-O1 -g -Wno-writable-strings" \
-DCMAKE_CXX_FLAGS="-O1 -g -Wno-writable-strings" \
-DLLVM_SYMBOLIZER_PATH="${symbolizer_path}" \
-DNRN_SANITIZERS=$(echo ${{matrix.config.sanitizer}} | sed -e 's/-/,/g'))
fi
cmake_args+=(-DCMAKE_C_COMPILER="${CC}" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER="${CXX}" \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
-DNRN_ENABLE_TESTS=ON \
${{matrix.config.cmake_option}})
if [[ "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then
cmake_args+=(-DNRN_ENABLE_PYTHON=ON \
-DNRN_ENABLE_PYTHON_DYNAMIC=ON \
-DNRN_PYTHON_DYNAMIC="${PYTHON_MIN};${PYTHON_MAX}" \
-DNRN_ENABLE_CORENEURON=ON)
else
cmake_args+=(-DPYTHON_EXECUTABLE="${PYTHON}")
fi
if [[ "$NRN_ENABLE_MUSIC" == "ON" ]]; then
cmake_args+=(-DNRN_ENABLE_MUSIC=ON \
-DCMAKE_PREFIX_PATH=${MUSIC_INSTALL_DIR} \
-DMUSIC_ROOT=${MUSIC_INSTALL_DIR})
fi
# Enable more warnings in the builds whose compiler warnings we
# highlight in the GitHub UI
if [[ "${{matrix.config.flag_warnings}}" == "ON" ]]; then
cmake_args+=(-DNRN_EXTRA_CXX_FLAGS="-Wall \
-Wno-char-subscripts \
-Wno-unknown-pragmas \
-Wno-unused-variable \
-Wno-unused-function \
-Wno-unused-but-set-variable \
-Wno-reorder \
-Wno-sign-compare \
-Wno-strict-aliasing \
-Wno-missing-braces \
-Wno-mismatched-tags" \
-DNRN_EXTRA_MECH_CXX_FLAGS="")
fi
mkdir build && cd build
echo "Building with: ${cmake_args[@]}"
cmake .. "${cmake_args[@]}"
if ccache --version | grep -E '^ccache version 4\.(4|4\.1)$'
then
echo "------- Disable ccache direct mode -------"
# https://github.com/ccache/ccache/issues/935
export CCACHE_NODIRECT=1
fi
ccache -z
# Older versions don't support -v (verbose)
ccache -vs 2>/dev/null || ccache -s
cmake --build . --parallel
ccache -vs 2>/dev/null || ccache -s
if [ "$RUNNER_OS" == "macOS" ]
then
echo $'[install]\nprefix='>src/nrnpython/setup.cfg;
fi
if [[ "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then
echo "--RUNNING BASIC TESTS FROM BUILD DIR--"
for python in "${PYTHON_MIN}" "${PYTHON_MAX}"
do
echo "Using ${python}"
NEURONHOME="${PWD}/share/nrn" \
PYTHONPATH="${PWD}/lib/python" \
PATH="${PWD}/bin" \
LD_LIBRARY_PATH="${PWD}/lib:${LD_LIBRARY_PATH}" \
DYLD_LIBRARY_PATH="${PWD}/lib:${DYLD_LIBRARY_PATH}" \
"${python}" -c "from neuron import h; import neuron; neuron.test()"
done
fi
ctest --output-on-failure
cmake --build . --target install
export PATH="${INSTALL_DIR}/bin:${PATH}"
if [[ -f "${INSTALL_DIR}/bin/nrn-enable-sanitizer" ]]; then
echo --- bin/nrn-enable-sanitizer ---
cat bin/nrn-enable-sanitizer
echo ---
nrn_enable_sanitizer=${INSTALL_DIR}/bin/nrn-enable-sanitizer
nrn_enable_sanitizer_preload="${nrn_enable_sanitizer} --preload"
else
echo nrn-enable-sanitizer not found, not using it
fi
elif [[ "$BUILD_MODE" == "setuptools" ]]; then
./packaging/python/build_wheels.bash CI;
fi;
# basic test for cmake when python is not disabled
if [[ "$BUILD_MODE" == "cmake" && ! "${cmake_args[*]}" =~ "NRN_ENABLE_PYTHON=OFF" ]]; then
$PYTHON --version && ${nrn_enable_sanitizer_preload} $PYTHON -c 'import neuron; neuron.test()'
fi;
# test neurondemo with cmake
if [[ "$BUILD_MODE" != "setuptools" ]]; then
${nrn_enable_sanitizer} neurondemo -nogui -c 'demo(4)' -c 'run()' -c 'quit()'
fi;
# with cmake dynamic check python_min and python_max together
if [[ "$BUILD_MODE" == "cmake" && "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then
${nrn_enable_sanitizer_preload} $PYTHON_MAX -c 'import neuron; neuron.test()'
${nrn_enable_sanitizer_preload} $PYTHON_MIN -c 'import neuron; neuron.test()'
fi;
# run rxd tests manually if rxd is enabled *and CoreNEURON is
# disabled -- otherwise hh-related tests fail
if [[ "$BUILD_MODE" == "cmake" \
&& ! "${cmake_args[*]}" =~ "NRN_ENABLE_RX3D=OFF" \
&& ! "${cmake_args[*]}" =~ "NRN_ENABLE_CORENEURON=ON" ]]; then
${nrn_enable_sanitizer_preload} $PYTHON ../share/lib/python/neuron/rxdtests/run_all.py
fi;
if [ "$BUILD_MODE" == "setuptools" ]; then
neuron_wheel=wheelhouse/NEURON*.whl;
# test with virtual environment
${nrn_enable_sanitizer_preload} ./packaging/python/test_wheels.sh $PYTHON $neuron_wheel
# test with global installation
${nrn_enable_sanitizer_preload} ./packaging/python/test_wheels.sh $PYTHON $neuron_wheel false
fi;
env:
BUILD_MODE: ${{ matrix.config.build_mode }}
CCACHE_BASEDIR: ${{runner.workspace}}/nrn
CCACHE_DIR: ${{runner.workspace}}/ccache
NRN_ENABLE_PYTHON_DYNAMIC : ${{ matrix.config.python_dynamic }}
NRN_ENABLE_MUSIC: ${{ matrix.config.music }}
PYTHON_MIN_NAME: "python${{ env.PY_MIN_VERSION }}"
PYTHON_MAX_NAME: "python${{ env.PY_MAX_VERSION }}"
INSTALL_DIR : ${{ runner.workspace }}/install
MATRIX_EVAL: ${{ matrix.config.matrix_eval }}
# This step will set up an SSH connection on tmate.io for live debugging.
# To enable it, you have to:
# * add 'live-debug-ci' to your PR title
# * push something to your PR branch (note that just re-running the pipeline disregards the title update)
- name: live debug session on failure (manual steps required, check `.github/neuron-ci.yml`)
if: failure() && contains(github.event.pull_request.title, 'live-debug-ci')
uses: mxschmitt/action-tmate@v3
# see https://github.com/orgs/community/discussions/26822
final:
name: Final CI
needs: [ci]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Check ci matrix all done
if: >-
${{
contains(needs.*.result, 'failure')
|| contains(needs.*.result, 'cancelled')
|| contains(needs.*.result, 'skipped')
}}
run: exit 1