Skip to content

Commit d3fe5e9

Browse files
authored
Thread-safe and more performant parser based on ExprTK (#387)
* Update to install instructions... Point release 3.2.1. The version bump is due to using new manylinux2010 images. * - Added ExprTK based parser and removed muParser. EXPRTK is faster than muParser (see labnotes). - All tests have been passing. - Tweaks are made to exprtk operators/functions to make sure old expressions used scripts remains valid. * Added function ln(double v) to EXPRTK. Compatibility with muParser. All tests are passing. * It is working fine now with Vinu model. Needs to fix the sbmlParserReader which uses numVars_. * Some more cleanup. Testing on travis. Removed moose.Func(); user should use `moose.Function`. moose.Func was disabled long back. * GSolve also honors MOOSE_NUM_THREADS ... * Local tests are passing. Fixed memory leak issue. A little refactoring and memory segv at the end of the test is now clean. Removed unneeded/outdated tests and other scripts. Added new tests based on Vinu model. It is very comprehensive which tests multithreaded Ksolve/Gsolve, SBML, and moose.Function Update to install instructions... (#386) Point release 3.2.1. The version bump is due to using new manylinux2010 images. * Thanks to clang++; caught another memory related bug. If this passes, do a memory profiling. * Minor cleanup. Removed memory allocation and copying at couple of places. Still memory leaks in exprtk. I think I can't get rid of them. Parser is a member object rather than member pointer; still some leak but better version than before. * Renamed test folder for regular tests. Added custom test which uses 4 threads to run Ksolve. Modified atol and rtol in assertion in one of the tests. Using parallel version of Ksolve/Gsolve everywhere by setting MOOSE_NUM_THREADS=$(nproc) Increased `rtol` value to make sure tests passes with BOOST solver as well. When the boost's ode solvers are used, the number generated are slightly different. * - Added a docker file to run travis pipeline locally. - Fixed python2 seg-fault in new tests. The segv was because / means int division in python2. * Converting some rdesigneur scripts to tests; since we need to be able to plot in nonblocking mode, I've added `block` option in `rdes.display` function. Multiple tests using pydoc. They are based on rdesigneur tutorials. install requires matplotlib for rdesigneur. * - The seg-fault in rdesigneur tests are due to #388. * In the ksolve, we partition the interval beforehand now. The single-threaded and multi-threaded numbers are not the same. Fixed tests to accomodate slightly different values resulted n multi-threaded mode. * Categorised tests. Also turned all doctest to normal assertion tests. Moved alpha tests to fixme tests. * All tests passing locally with both GSL and BOOST. * Compilation fixes for the OSX build. One test marked as python3 only. The pyrun expression uses python3 specific division and print function. Causes segfault with python2 (wontfix)
1 parent dd2a902 commit d3fe5e9

File tree

321 files changed

+58584
-36620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

321 files changed

+58584
-36620
lines changed

.ci/travis_build_linux.sh

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ PYTHON2="/usr/bin/python2"
1313
PYTHON3="/usr/bin/python3"
1414

1515
$PYTHON2 -m pip install pip --upgrade --user
16-
$PYTHON2 -m pip install libNeuroML pyNeuroML --upgrade --user
16+
$PYTHON2 -m pip install libNeuroML pyNeuroML python-libsbml --upgrade --user
1717

1818
$PYTHON3 -m pip install pip --upgrade --user
19-
$PYTHON3 -m pip install libNeuroML pyNeuroML --upgrade --user
19+
$PYTHON3 -m pip install libNeuroML pyNeuroML python-libsbml --upgrade --user
2020

2121
NPROC=$(nproc)
2222
MAKE="make -j$NPROC"
@@ -30,15 +30,13 @@ unset PYTHONPATH
3030
$PYTHON2 -m compileall -q .
3131
$PYTHON3 -m compileall -q .
3232

33-
# Python3 with GSL.
34-
echo "Python3: Removed python2-networkx and install python3"
35-
36-
# GSL.
33+
# Python3 with GSL in debug more.
3734
(
3835
mkdir -p _GSL_BUILD_PY3 && cd _GSL_BUILD_PY3 && \
3936
cmake -DPYTHON_EXECUTABLE=$PYTHON3 \
4037
-DCMAKE_INSTALL_PREFIX=/usr -DDEBUG=ON ..
41-
$MAKE && ctest -j$NPROC --output-on-failure -E ".*socket_streamer.*"
38+
# Don't run test_long prefix. They take very long time in DEBUG mode.
39+
$MAKE && MOOSE_NUM_THREADS=$NPROC ctest -j$NPROC --output-on-failure -E ".*test_long*"
4240
make install || sudo make install
4341
cd /tmp
4442
$PYTHON3 -c 'import moose;print(moose.__file__);print(moose.version())'
@@ -49,7 +47,7 @@ echo "Python3: Removed python2-networkx and install python3"
4947
mkdir -p _BOOST_BUILD_PY3 && cd _BOOST_BUILD_PY3 && \
5048
cmake -DWITH_BOOST_ODE=ON -DPYTHON_EXECUTABLE="$PYTHON3" \
5149
-DCMAKE_INSTALL_PREFIX=/usr ..
52-
$MAKE && ctest -j$NPROC --output-on-failure -E ".*socket_streamer.*"
50+
$MAKE && MOOSE_NUM_THREADS=$NPROC ctest -j$NPROC --output-on-failure
5351
)
5452

5553
# GSL and python2, failure is allowed
@@ -58,7 +56,7 @@ set +e
5856
BUILDDIR=_GSL_PY2
5957
mkdir -p $BUILDDIR && cd $BUILDDIR && \
6058
cmake -DPYTHON_EXECUTABLE=$PYTHON2 -DCMAKE_INSTALL_PREFIX=/usr ..
61-
$MAKE && ctest -j$NPROC --output-on-failure -E ".*socket_streamer.*"
59+
$MAKE && MOOSE_NUM_THREADS=$NPROC ctest -j$NPROC --output-on-failure
6260
)
6361
set -e
6462

.ci/travis_build_osx.sh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
set -o nounset # Treat unset variables as an error
2121
set -e
2222

23-
# NOTE: On travis, don't enable -j`nproc` option. It may not compile properly.
2423
NPROC=$(nproc)
2524
(
2625
# Make sure not to pick up python from /opt.
@@ -34,17 +33,16 @@ NPROC=$(nproc)
3433
$PYTHON3 -m pip install pyneuroml --user
3534

3635
mkdir -p _GSL_BUILD && cd _GSL_BUILD \
37-
&& cmake -DDEBUG=ON \
38-
-DPYTHON_EXECUTABLE=$PYTHON3 \
36+
&& cmake -DPYTHON_EXECUTABLE=$PYTHON3 \
3937
..
4038
make pylint -j$NPROC
41-
make -j$NPROC && ctest --output-on-failure -$NPROC
39+
make -j$NPROC && MOOSE_NUM_THREAD=$NPROC ctest --output-on-failure -j$NPROC
4240

4341
cd .. # Now with boost.
4442
mkdir -p _BOOST_BUILD && cd _BOOST_BUILD \
45-
&& cmake -DWITH_BOOST_ODE=ON -DDEBUG=ON \
43+
&& cmake -DWITH_BOOST_ODE=ON \
4644
-DPYTHON_EXECUTABLE=`which python3` ..
4745

48-
make -j$NPROC && ctest -j$NPROC --output-on-failure
46+
make -j$NPROC && MOOSE_NUM_THREAD=$NPROC ctest -j$NPROC --output-on-failure
4947
)
5048
set +e

.docker/travis/Dockerfile

Lines changed: 0 additions & 11 deletions
This file was deleted.

.docker/travis/Makefile

Lines changed: 0 additions & 18 deletions
This file was deleted.

.github/workflows/stale.yml

Lines changed: 0 additions & 19 deletions
This file was deleted.

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ matrix:
55
include:
66
- os: linux
77
dist: bionic
8+
services:
9+
- xvfb
810
- os: osx
911
osx_image: xcode11.3
1012

@@ -21,6 +23,7 @@ addons:
2123
apt:
2224
update: true
2325

26+
2427
before_script:
2528
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then nvm get head || true; fi
2629
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.ci/travis_prepare_osx.sh; fi

CMakeLists.txt

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
44
project(PyMOOSE)
55

66
# cmake related macros.
7-
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
7+
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
88
include(CheckCXXCompiler.cmake)
99
include(CheckIncludeFileCXX)
10-
include(FindPythonModule)
1110

1211
# We find python executable here. Though mainly used inside pymoose.
1312
# FIXME: When cmake 3.12 is widely available use the following:
@@ -19,12 +18,17 @@ if(NOT PYTHONINTERP_FOUND)
1918
find_package(PythonInterp 2.7)
2019
endif()
2120

21+
# Disable rpath on OSX.
22+
if(APPLE)
23+
set(CMAKE_MACOSX_RPATH OFF)
24+
endif()
25+
2226

2327
# NOTE: version should be changed in setup.py file.
2428
# If moose version is not given, use setup.py file to get the default version.
2529
if(NOT VERSION_MOOSE)
2630
execute_process(COMMAND ${PYTHON_EXECUTABLE} setup.py --version
27-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
31+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
2832
OUTPUT_VARIABLE VERSION_MOOSE
2933
OUTPUT_STRIP_TRAILING_WHITESPACE)
3034
endif()
@@ -69,7 +73,6 @@ option(WITH_ASAN "Use AddressSanitizer in DEBUG mode." OFF)
6973

7074
# Default definitions.
7175
add_definitions(-DUSE_GENESIS_PARSER)
72-
7376
if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
7477
message(STATUS "Building for Debug/Unit testing")
7578
add_definitions(-DDO_UNIT_TESTS -O)
@@ -109,6 +112,7 @@ link_directories(${CMAKE_BINARY_DIR})
109112
add_library(libmoose SHARED basecode/main.cpp)
110113
add_executable(moose.bin basecode/main.cpp)
111114

115+
112116
################################### SETUP BUILD ################################
113117

114118
# default include paths.
@@ -225,10 +229,6 @@ if(WITH_MPI)
225229
endif()
226230
endif(WITH_MPI)
227231

228-
# Always use private version of muparser. We have some custom edits.
229-
add_subdirectory(external/muparser)
230-
list(APPEND MOOSE_LIBRARIES muparser)
231-
232232
# Add subdirectroeis
233233
add_subdirectory(basecode)
234234
add_subdirectory(msg)
@@ -368,9 +368,8 @@ endif()
368368

369369
############################ CTEST ######################################
370370
include( CTest )
371-
# If CTEST_OUTPUT_ON_FAILURE environment variable is set, the output is printed
372-
# onto the console if a test fails.
373-
set(ENV{CTEST_OUTPUT_ON_FAILURE} ON)
371+
set(CTEST_NIGHTLY_START_TIME "05:30:00 UTC")
372+
set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=moose")
374373

375374
if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
376375
# Run this test in debug mode. In Release mode, this does not do anything.
@@ -380,33 +379,46 @@ if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
380379
add_test(NAME moose.bin-raw-run COMMAND moose.bin -u -q)
381380
endif()
382381

383-
## PyMOOSE tests.
384-
set(PYMOOSE_TEST_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/python)
385-
386-
# Collect all python script in tests folder and run them.
382+
# PyMOOSE tests. These tests complete in reasonable time and should run by
383+
# default.
384+
set(PYMOOSE_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/py_moose)
387385
file(GLOB PY_TEST_SCRIPTS "${PYMOOSE_TEST_DIRECTORY}/test_*.py" )
388-
389-
390-
# Run python tests.
391-
foreach( _test_script ${PY_TEST_SCRIPTS} )
392-
get_filename_component( _test_name ${_test_script} NAME_WE)
393-
add_test( NAME ${_test_name}
386+
foreach(_test_script ${PY_TEST_SCRIPTS} )
387+
get_filename_component(_name_we ${_test_script} NAME_WE)
388+
set(_test_name "pymoose_${_name_we}")
389+
add_test(NAME ${_test_name}
394390
COMMAND ${PYTHON_EXECUTABLE} ${_test_script}
395391
WORKING_DIRECTORY ${PYMOOSE_TEST_DIRECTORY}
396392
)
397-
set_tests_properties( ${_test_name}
393+
set_tests_properties(${_test_name}
398394
PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python"
399395
)
400396
endforeach( )
401397

402-
# Alpha tests. These should not run by default.
403-
set(MOOSE_ALPHA_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/alpha)
404-
file(GLOB PY_ALPHA_TEST_SCRIPTS "${PYMOOSE_ALPHA_TEST_DIRECTORY}/*.py" )
405-
foreach( _test_script ${PY_ALPHA_TEST_SCRIPTS} )
406-
get_filename_component( _test_name ${_test_script} NAME_WE)
398+
# rdesigneur tests. These tests require matplotlib.
399+
set(RDES_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/py_rdesigneur)
400+
file(GLOB RDES_TEST_SCRIPTS "${RDES_TEST_DIRECTORY}/test_*.py" )
401+
foreach(_test_script ${RDES_TEST_SCRIPTS})
402+
get_filename_component(_name_we ${_test_script} NAME_WE)
403+
set(_test_name "rdes_${_name_we}")
404+
add_test(NAME ${_test_name}
405+
COMMAND ${PYTHON_EXECUTABLE} ${_test_script}
406+
WORKING_DIRECTORY ${RDES_TEST_DIRECTORY}
407+
)
408+
set_tests_properties(${_test_name} PROPERTIES
409+
ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python;MOOSE_NUM_THREADS=4"
410+
)
411+
endforeach()
412+
413+
# FIXME TESTS. These should not run by default. We need to fix them.
414+
set(PYMOOSE_FIXME_TEST_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/fixme)
415+
file(GLOB PY_FIXME_TEST_SCRIPTS "${PYMOOSE_FIXME_TEST_DIRECTORY}/*.py" )
416+
foreach( _test_script ${PY_FIXME_TEST_SCRIPTS} )
417+
get_filename_component( _name_we ${_test_script} NAME_WE)
418+
set(_test_name "alpha_${_name_we}")
407419
add_test( NAME ${_test_name}
408420
COMMAND ${PYTHON_EXECUTABLE} ${_test_script}
409-
CONFIGURATIONS Devel
421+
CONFIGURATIONS alpha
410422
WORKING_DIRECTORY ${PYMOOSE_ALPHA_TEST_DIRECTORY}
411423
)
412424
set_tests_properties( ${_test_name}
@@ -415,41 +427,19 @@ foreach( _test_script ${PY_ALPHA_TEST_SCRIPTS} )
415427
endforeach( )
416428

417429
# Regression and github issues. These should not run by default.
418-
set(PYMOOSE_ISSUES_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/issues)
430+
set(PYMOOSE_ISSUES_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/devel/issues)
419431
file(GLOB PY_ISSUES_SCRIPTS "${PYMOOSE_ISSUES_DIRECTORY}/*.py" )
420-
foreach( _test_script ${PY_ISSUES_SCRIPTS} )
432+
foreach(_test_script ${PY_ISSUES_SCRIPTS})
421433
get_filename_component( _test_name ${_test_script} NAME_WE)
422-
add_test( NAME ${_test_name}
434+
add_test(NAME ${_test_name}
423435
COMMAND ${PYTHON_EXECUTABLE} ${_test_script}
424436
CONFIGURATIONS Devel
425437
WORKING_DIRECTORY ${PYMOOSE_ISSUES_DIRECTORY}
426438
)
427-
set_tests_properties( ${_test_name}
439+
set_tests_properties(${_test_name}
428440
PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/python"
429441
)
430-
endforeach( )
431-
432-
# add pylint target.
433-
set(PYSCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python )
434-
file(GLOB_RECURSE PY_SCRIPTS "python/*.py")
435-
add_custom_target( pylint )
436-
foreach( _py_script ${PY_SCRIPTS} )
437-
get_filename_component( _py_name ${_py_script} NAME_WE)
438-
file( READ ${_py_script} pytext)
439-
string(MD5 _md5 "${pytext}")
440-
set(TGT_NAME "${_py_name}-${_md5}" )
441-
set(PYLINT_OPTIONS --disable=no-member --disable=no-name-in-module
442-
--disable=invalid-unary-operand-type
443-
--disable=import-error
444-
--disable=no-method-argument
445-
)
446-
add_custom_target( ${TGT_NAME}
447-
COMMAND ${PYTHON_EXECUTABLE} -m pylint -E ${PYLINT_OPTIONS} ${_py_script}
448-
COMMENT "Running pylint on ${_py_script}"
449-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
450-
)
451-
add_dependencies(pylint ${TGT_NAME} )
452-
endforeach( )
442+
endforeach()
453443

454444
############################ CPACK ######################################
455445
# This is not maintained anymore since packaging is done using OpenBuildService
@@ -461,9 +451,10 @@ set(PYMOOSE_SDIST_FILE ${CMAKE_BINARY_DIR}/pymoose-${VERSION_MOOSE}.tar.gz)
461451
add_custom_target(sdist
462452
COMMAND ${PYTHON_EXECUTABLE} setup.py sdist --formats=gztar
463453
-d ${CMAKE_BINARY_DIR}
464-
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
454+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
465455
COMMENT "Creating sdist ${PYMOOSE_SDIST_FILE}"
466456
VERBATIM)
457+
467458
add_custom_target(upload_test DEPENDS sdist
468459
COMMAND ${PYTHON_EXECUTABLE} -m twine upload
469460
--user $ENV{PYMOOSE_PYPI_USER} --password $ENV{PYMOOSE_PYPI_PASSWORD}
@@ -478,3 +469,35 @@ add_custom_target(upload DEPENDS sdist
478469
${PYMOOSE_SDIST_FILE}
479470
COMMENT "Uploading source distribution to PyPI"
480471
VERBATIM)
472+
473+
####################### DEVELOPMENT ########################################
474+
475+
# PYLINT target.
476+
set(PYSCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python)
477+
file(GLOB_RECURSE PY_SCRIPTS "python/*.py")
478+
add_custom_target(pylint)
479+
foreach(_py_script ${PY_SCRIPTS})
480+
get_filename_component( _py_name ${_py_script} NAME_WE)
481+
file( READ ${_py_script} pytext)
482+
string(MD5 _md5 "${pytext}")
483+
set(TGT_NAME "${_py_name}-${_md5}" )
484+
set(PYLINT_OPTIONS --disable=no-member --disable=no-name-in-module
485+
--disable=invalid-unary-operand-type
486+
--disable=import-error
487+
--disable=no-method-argument
488+
)
489+
add_custom_target( ${TGT_NAME}
490+
COMMAND ${PYTHON_EXECUTABLE} -m pylint -E ${PYLINT_OPTIONS} ${_py_script}
491+
COMMENT "Running pylint on ${_py_script}"
492+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
493+
)
494+
add_dependencies(pylint ${TGT_NAME} )
495+
endforeach( )
496+
497+
# Replicate Travis-CI building using docker
498+
add_custom_target(docker
499+
COMMAND docker build -t bhallalab/travis:latest
500+
-f ${CMAKE_CURRENT_SOURCE_DIR}/devel/docker/travis/Dockerfile .
501+
COMMENT "Replicating Travis-CI building using Docker."
502+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
503+
VERBATIM)

0 commit comments

Comments
 (0)