hensing / PyDDE

PyDDE: Python/C DDE solver
http://users.ox.ac.uk/~clme1073/python/PyDDE/
Other
17 stars 44 forks source link

Segmentation fault #1

Open jsv13 opened 9 years ago

jsv13 commented 9 years ago

Hi Henning,

when using PyDDE with more than 10 state variables I get a segmentation fault possibly due to memory problems. Before digging into the problem myself, I was wondering if you are aware of this issue and can offer some quick help.

Best, Jannis

hensing commented 9 years ago

Hi Jannis!

I'm not aware of this problem - can you post a minimal example? Best regards

Henning

jsv13 commented 9 years ago
import numpy as np
import PyDDE.pydde as dde

d = 5e-3
nn = 20
tmin = 0.
tmax = 1e-2

def ddegrad(s, c, t):
    lags = np.zeros(nn)

    if (t>c[0]):
        for ii in range(nn):
            lags[ii] = dde.pastvalue(ii,t-c[0],ii)

    res = np.zeros((nn,))

    for ii in range(nn):
        res[ii] = -s[ii]

    return res

tds = dde.dde()
ddecons = np.array([d])
ddeist = np.random.rand(nn)
ddestsc = np.zeros((nn,))

tds.dde(y=ddeist, times=np.arange(tmin, tmax, 1e-5),
           func=ddegrad, parms=ddecons,
           tol=0.0005, dt=1e-4, hbsize=1e4, nlag=1, ssc=ddestsc)

t = tds.data[:,0]
data = tds.data[:,1:]

print data
jsv13 commented 9 years ago

I just figured out that using zero in the last argument of dd.pastvalue, that is

dde.pastvalue(ii,t-c[0],0)

does not cause any error.Is it ok to use it that way or will it give wrong results?

hensing commented 9 years ago

I'm not aware of this problem, sorry. But did you try to pass an hist_function instead of pastvalues? -> dde.hist_from_funcs(my_history_dict)

Besides: don't you have to run the solver via dde.run()?

bjcairns commented 9 years ago

Jannis,

The third argument to dde.pastvalue() is the "mark" number, indexed from 0. If I remember correctly -- and I admit there's a good chance I don't -- the number of marks is the number of lags you want to keep up with.

You state that there is one lag in the tds.dde() call in your code, but then call for the ii-th mark in ddegrad(). So, I suspect you are asking for more lags than have been allocated for, hence the segfault.

The manual, though out of date, states that using multiple lags is more efficient, but that pastvalue() will work, if more slowly, if you track only a single lag and refer to it by mark 0. The fix you found should work, and possibly is just what you want, but if you want to track multiple lags, you'd be better off changing the nlag argument in tds.dde().

Ben.

P.S. In neither use nor help maintain PyDDE any more, though I'm grateful to Henning for putting it up on GitHub. I probably won't be any more use :)

hensing commented 9 years ago

@jannis31 did it work or do you still get segfaults?

jsv13 commented 9 years ago

I will be back in office next week and only then I can test the proposed solutions. I'll report the outcome here.

jsv13 commented 8 years ago

What Ben explained is correct. The 3rd argument indexes the different lags, so setting it to zero (I use only one lag) does normally not cause any segfaults. However, if there is a runtime error, instead of raising an exception python exits abruptly with segfault. Thus, there must still be something wrong with pydde, perhaps with the memory management. This makes debugging extremely difficult, since you have to catch possible errors manually before they occur to avoid the segfault.