-
Notifications
You must be signed in to change notification settings - Fork 128
Description
Overview of the issue
Not a bug per se, but warrants a discussion. For this particular mod file https://github.com/ModelDBRepository/138382/blob/3548e4565608f7f61ea51ead2432e3f40bdf279e/cdp3.mod, NMODL takes over 7 minutes to just generate the code:
$ time nmodl --neuron cdp3.mod
real 7m11.235s
user 7m9.113s
sys 0m0.507s
My guess is that this is due to the KINETIC block being rather complex, and the resulting C++ file has almost 40000 lines.
On the other hand, nocmodl translates the file much faster:
$ time nocmodl cdp3.mod
real 0m0.089s
user 0m0.071s
sys 0m0.018s
Note that, for this particular model, compilation actually fails when using the NMODL translator, with the error (this is technically unrelated to the slowness, but it happens to the same model so I'm mentioning it for completeness):
/include/Eigen/src/Core/DenseStorage.h: In instantiation of ‘void Eigen::internal::check_static_allocation_size() [with T = double; int Size = 35721]’:
/include/Eigen/src/Core/DenseStorage.h:51:41: required from ‘Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, Alignment>::plain_array() [with T = double; int Size = 35721; int MatrixOrArrayOptions = 0; int Alignment = 0]
’
/include/Eigen/src/Core/DenseStorage.h:211:38: required from ‘Eigen::DenseStorage<T, Size, _Rows, _Cols, _Options>::DenseStorage() [with T = double; int Size = 35721; int _Rows = 189; int _Cols = 189; int _Options = 0]’
/include/Eigen/src/Core/PlainObjectBase.h:476:45: required from ‘Eigen::PlainObjectBase<Derived>::PlainObjectBase() [with Derived = Eigen::Matrix<double, 189, 189>]’
/include/Eigen/src/Core/Matrix.h:259:21: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix() [with _Scalar = double; int _Rows = 189; int _Cols = 189; int _Options = 0; int _MaxRows = 189; int _MaxCols = 189]’
138382/AnwarEtAl2010/x86_64/cdp3.cpp:303:33: required from ‘int nmodl::newton::newton_solver(Eigen::Matrix<double, N, 1>&, FUNC, double, int) [with int N = 189; FUNC = neuron::functor_cdp3_0]’
138382/AnwarEtAl2010/x86_64/cdp3.cpp:39091:65: required from here
/include/Eigen/src/Core/DenseStorage.h:33:40: error: static assertion failed: OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
33 | EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
/include/Eigen/src/Core/DenseStorage.h:33:3: note: in expansion of macro ‘EIGEN_STATIC_ASSERT’
33 | EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
| ^~~~~~~~~~~~~~~~~~~
/include/Eigen/src/Core/DenseStorage.h:33:40: note: the comparison reduces to ‘(285768 <= 131072)’
33 | EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
/include/Eigen/src/Core/DenseStorage.h:33:3: note: in expansion of macro ‘EIGEN_STATIC_ASSERT’
The key line being:
note: the comparison reduces to ‘(285768 <= 131072)’
Since sizeof(T) is 8 on my machine, it seems the default limit for the an N x N matrix is N = 128. We can get around this issue by adding:
#define EIGEN_STACK_ALLOCATION_LIMIT 0somewhere (I added it by hand to the file, but I'm sure we can add it as a flag to the nrnivmodl makefile).
Expected result/behavior
NMODL should not take so long to just translate the whole file. My suspicion is that the sympy solver, being written in pure Python, is rather slow for large systems.