diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index fe1a68ea3a..0466b290a1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -1,5 +1,9 @@ name: NEURON Code Coverage +concurrency: + group: ${{ github.workflow }}#${{ github.ref }} + cancel-in-progress: true + on: push: branches: @@ -9,14 +13,15 @@ on: branches: - master - release/** - paths-ignore: - - '**.md' - - '**.rst' - - 'docs/**' +# TODO : https://github.com/neuronsimulator/nrn/issues/1063 +# paths-ignore: +# - '**.md' +# - '**.rst' +# - 'docs/**' env: - PY_MIN_VERSION: 2.7 - PY_MAX_VERSION: 3.8 + PY_MIN_VERSION: '3.6' + PY_MAX_VERSION: '3.10' jobs: coverage: @@ -30,9 +35,17 @@ jobs: - name: Install apt packages run: | - sudo apt-get install build-essential doxygen autoconf automake libtool lcov autotools-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin patchelf python-pip python-tk python-numpy python3-numpy python3-pip g++-5 g++-6 g++-8 g++-9 + sudo apt-get install build-essential doxygen lcov libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin patchelf gpg shell: bash + - name: Setup Caliper profiler + run: | + git clone https://github.com/LLNL/Caliper.git + cd Caliper + mkdir build && cd build + cmake .. + make && sudo make install + - name: Set up Python@${{ env.PY_MIN_VERSION }} uses: actions/setup-python@v2 with: @@ -71,7 +84,7 @@ jobs: # CMake options & flags export COVERAGE_FLAGS="--coverage -O0 -fno-inline -g"; - export CMAKE_OPTION="-DNRN_ENABLE_BINARY_SPECIAL=ON -DNRN_ENABLE_MPI=ON -DNRN_ENABLE_INTERVIEWS=ON -DNRN_ENABLE_PYTHON=ON -DNRN_ENABLE_PYTHON_DYNAMIC=ON -DNRN_PYTHON_DYNAMIC=${PYTHON_MIN};${PYTHON_MAX} -DNRN_ENABLE_CORENEURON=ON"; + export CMAKE_OPTION="-DNRN_ENABLE_MPI=ON -DNRN_ENABLE_INTERVIEWS=ON -DNRN_ENABLE_PYTHON=ON -DNRN_ENABLE_PYTHON_DYNAMIC=ON -DNRN_PYTHON_DYNAMIC=${PYTHON_MIN};${PYTHON_MAX} -DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_PROFILING=ON"; cmake $CMAKE_OPTION -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX -DNRN_ENABLE_TESTS=ON -DCMAKE_C_FLAGS="${COVERAGE_FLAGS}" -DCMAKE_CXX_FLAGS="${COVERAGE_FLAGS}" ..; # Coverage @@ -84,15 +97,27 @@ jobs: ctest -VV; (cd ..; lcov --capture --directory . --no-external --output-file build/coverage-run.info) lcov --add-tracefile coverage-base.info --add-tracefile coverage-run.info --output-file coverage-combined.info + + # Download codecov script and perform integrity checks + curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --import # One-time step + curl -Os https://uploader.codecov.io/latest/linux/codecov + curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM + curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM.sig + gpg --verify codecov.SHA256SUM.sig codecov.SHA256SUM + shasum -a 256 -c codecov.SHA256SUM + chmod +x codecov + # Prefer auto-discovery for now. Specify reports once all python testing is unified under single report (-f option). - bash <(curl -s https://codecov.io/bash) + ./codecov env: MATRIX_EVAL: "CC=gcc CXX=g++" PYTHON_MIN_NAME: "python${{ env.PY_MIN_VERSION }}" PYTHON_MAX_NAME: "python${{ env.PY_MAX_VERSION }}" # This step will set up an SSH connection on tmate.io for live debugging. - # To trigger it, simply add 'live-debug-coverage' to your last pushed commit message. - - name: live debug session on failure - if: failure() && contains(github.event.head_commit.message, 'live-debug-coverage') + # To enable it, you have to: + # * add 'live-debug-coverage' 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/coverage.yml`) + if: failure() && contains(github.event.pull_request.title, 'live-debug-coverage') uses: mxschmitt/action-tmate@v3 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 46ef3955ce..31e2736d12 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,7 +11,9 @@ on: - release/** env: - DEFAULT_PY_VERSION: 3.8 + # Python 3.10 fails executing jupyter notebooks. Don't need 3.10 for building docs anyway. + # see https://github.com/neuronsimulator/nrn/issues/1612 + DEFAULT_PY_VERSION: '3.8' jobs: documentation: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 7de88f2a4e..7fe9c6e455 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,5 +1,9 @@ name: Windows Installer +concurrency: + group: ${{ github.workflow }}#${{ github.ref }} + cancel-in-progress: true + on: push: branches: @@ -26,7 +30,12 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - + + - name: Set up Python3 + uses: actions/setup-python@v2 + with: + python-version: '3.10' + - name: Download Dependencies run: | .\nrn\ci\win_download_deps.cmd @@ -48,9 +57,11 @@ jobs: BUILD_SOURCESDIRECTORY: ${{runner.workspace}}\nrn # This step will set up an SSH connection on tmate.io for live debugging. - # To trigger it, simply add 'live-debug-win' to your last pushed commit message. - - name: live debug session on failure - if: failure() && contains(github.event.head_commit.message, 'live-debug-win') + # To enable it, you have to: + # * add 'live-debug-win' 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/windows.yml`) + if: failure() && contains(github.event.pull_request.title, 'live-debug-win') uses: mxschmitt/action-tmate@v3 - name: Upload build artifact diff --git a/src/nrniv/nrnpy.cpp b/src/nrniv/nrnpy.cpp index 2551676607..de0f6cefa4 100644 --- a/src/nrniv/nrnpy.cpp +++ b/src/nrniv/nrnpy.cpp @@ -12,6 +12,9 @@ #include "classreg.h" #include "nonvintblock.h" #include "nrnmpi.h" +#include +#include + extern "C" { extern int nrn_nopython; @@ -371,41 +374,24 @@ static void* load_nrnpython_helper(const char* npylib) { return handle; } -int digit_to_int(char ch) { - int d = ch - '0'; - if ((unsigned) d < 10) { - return d; - } - d = ch - 'a'; - if ((unsigned) d < 6) { - return d + 10; - } - d = ch - 'A'; - if ((unsigned) d < 6) { - return d + 10; - } - return -1; -} - -static int pylib2pyver10(const char* pylib) { - // check backwards for N.N or NN // obvious limitations - int n1 = -1; int n2 = -1; - for (const char* cp = pylib + strlen(pylib) -1 ; cp > pylib; --cp) { - if (isdigit(*cp)) { - if (n2 < 0) { - n2 = digit_to_int(*cp); - } else { - n1 = digit_to_int(*cp); - return n1*10 + n2; - } - }else if (*cp == '.') { - // skip - }else{ // - // start over - n2 = -1; - } - } - return 0; +// Get python version as integer from pythonlib path +static int pylib2pyver10(std::string pylib) { + //skip past last \ or / + const auto pos = pylib.find_last_of("/\\"); + if (pos != std::string::npos) { + pylib = pylib.substr(pos + 1); + } + + // erase nondigits + pylib.erase( + std::remove_if(pylib.begin(), + pylib.end(), + [](char c) { + return !std::isdigit(c); + }), pylib.end()); + + // parse number. 0 is fine to return as error (no need for stoi) + return std::atoi(pylib.c_str()); } static void load_nrnpython(int pyver10, const char* pylib) {