{"action":"created","issue":{"url":"https://api.github.com/repos/brian-team/brian2/issues/552","labels_url":"https://api.github.com/repos/brian-team/brian2/issues/552/labels{/name}","comments_url":"https://api.github.com/repos/brian-team/brian2/issues/552/comments","events_url":"https://api.github.com/repos/brian-team/brian2/issues/552/events","html_url":"https://github.com/brian-team/brian2/pull/552","id":103742286,"number":552,"title":"[MRG] Model clocks as `Group`","user":{"login":"mstimberg","id":1381982,"avatar_url":"https://avatars.githubusercontent.com/u/1381982?v=3","gravatar_id":"","url":"https://api.github.com/users/mstimberg","html_url":"https://github.com/mstimberg","followers_url":"https://api.github.com/users/mstimberg/followers","following_url":"https://api.github.com/users/mstimberg/following{/other_user}","gists_url":"https://api.github.com/users/mstimberg/gists{/gist_id}","starred_url":"https://api.github.com/users/mstimberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mstimberg/subscriptions","organizations_url":"https://api.github.com/users/mstimberg/orgs","repos_url":"https://api.github.com/users/mstimberg/repos","events_url":"https://api.github.com/users/mstimberg/events{/privacy}","received_events_url":"https://api.github.com/users/mstimberg/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/brian-team/brian2/labels/in%20progress","name":"in progress","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":25,"created_at":"2015-08-28T15:42:22Z","updated_at":"2015-09-04T17:17:14Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/brian-team/brian2/pulls/552","html_url":"https://github.com/brian-team/brian2/pull/552","diff_url":"https://github.com/brian-team/brian2/pull/552.diff","patch_url":"https://github.com/brian-team/brian2/pull/552.patch"},"body":"This is a proposal for a different approach to the internal implementation of clocks. \r\n\r\nThe basic idea is that `Clock` is a `Group` with the state variables `timestep`, `t` and `dt`, which are all scalar arrays that are set/retrieved as other state variables (and therefore changing them between runs in standalone is not a problem anymore). In addition, it uses `run_regularly` to run abstract code that updates the clock, so this is now part of the generated code. As such, this is quite neat because it makes clocks less special (they are still special because they are used for scheduling, of course) and most importantly it allows us to get completely rid of `AttributeVariable`. Unfortunately, there are a few complications:\r\n* We still want to have `t` and `dt` accessible from pure Python, because even in standalone mode you might want to write `run(defaultclock.dt)`, or use `defaultclock.t` after a run -- also some groups like `PoissonGroup` or `SpikeGeneratorGroup` need to do checks in Python that involve `t` and `dt`. So clocks now store `t` and `dt` twice, once as internal Python attributes, once as standard state variables. This needs some cleaning up and documentation\r\n* To create state variables we need a device, but when the `defaultclock` is created we don't have a device yet... Also, you switch to the standalone device only *after* the `defaultclock` has been created, therefore its state variables are not stored with the device. Fixing this makes things slightly cumbersone, each device now has its own `defaultclock` and the standard `defaultclock` object is a proxy to the respective clock (but `dt` is carried over when you switch a device). Not sure, but this might even be an advantage for brian2genn where it would allow it to define a `GeNNClock` which could then be used for GeNN-specific clock code in the code generation process\r\n* A minor annoyance: templates that directly (i.e. not in user code) refer to `dt` and `t` now have to use `{{dt}}[0]` and `{{t}}[0]` in standalone mode\r\n\r\nSo this all works now, except for standalone mode with OpenMP, because the code that updates the clock writes to shared variables and this does not work correctly (just opened this as #551).\r\n\r\nI am more or less happy with it, because I never liked the whole `AttributeVariable` thing and I have the feeling that having `t` and `dt` stored in a standard way might simplify other things in the future (e.g. storing/restoring the state of a network). However, you (meaning: you as a developer, not as a user) now need to be careful whether you access the \"state variable dt\" or the \"Python dt\" and some other complications which I listed above. An alternative approach to fix #478 that would leave most things as they are would be to simply allow the setting of `AttributeVariable` values and implement this similar to the getting of values (i.e. assume that there's an object and a corresponding setter method in standalone). \r\n\r\nWhat do you think?\r\n\r\nFixes #478, also fixes #389"},"comment":{"url":"https://api.github.com/repos/brian-team/brian2/issues/comments/137796593","html_url":"https://github.com/brian-team/brian2/pull/552#issuecomment-137796593","issue_url":"https://api.github.com/repos/brian-team/brian2/issues/552","id":137796593,"user":{"login":"thesamovar","id":2903870,"avatar_url":"https://avatars.githubusercontent.com/u/2903870?v=3","gravatar_id":"","url":"https://api.github.com/users/thesamovar","html_url":"https://github.com/thesamovar","followers_url":"https://api.github.com/users/thesamovar/followers","following_url":"https://api.github.com/users/thesamovar/following{/other_user}","gists_url":"https://api.github.com/users/thesamovar/gists{/gist_id}","starred_url":"https://api.github.com/users/thesamovar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thesamovar/subscriptions","organizations_url":"https://api.github.com/users/thesamovar/orgs","repos_url":"https://api.github.com/users/thesamovar/repos","events_url":"https://api.github.com/users/thesamovar/events{/privacy}","received_events_url":"https://api.github.com/users/thesamovar/received_events","type":"User","site_admin":false},"created_at":"2015-09-04T17:17:14Z","updated_at":"2015-09-04T17:17:14Z","body":"Looks like there are still a few problems to fix.\r\n\r\nFor the name, I thought about it and didn't come up with anything good. It's not something that any user will ever see I guess, so maybe it's fine? If not, some suggestions (none of which I'm happy with): ``VariableStore``, ``VariableContainer``, ``BrianData``, ``VariableRootObject`` (this is quite technically satisfying in some way), ``VariableRoot``, ..."}}