{"action":"created","issue":{"url":"https://api.github.com/repos/brian-team/brian2/issues/551","labels_url":"https://api.github.com/repos/brian-team/brian2/issues/551/labels{/name}","comments_url":"https://api.github.com/repos/brian-team/brian2/issues/551/comments","events_url":"https://api.github.com/repos/brian-team/brian2/issues/551/events","html_url":"https://github.com/brian-team/brian2/issues/551","id":103734476,"number":551,"title":"Writes to shared variables not correctly handled with OpenMP","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/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/brian-team/brian2/labels/device:%20C++%20standalone","name":"device: C++ standalone","color":"ff00ff"},{"url":"https://api.github.com/repos/brian-team/brian2/labels/high%20priority","name":"high priority","color":"eb6420"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/brian-team/brian2/milestones/5","html_url":"https://github.com/brian-team/brian2/milestones/2.0","labels_url":"https://api.github.com/repos/brian-team/brian2/milestones/5/labels","id":380500,"number":5,"title":"2.0","description":"First widely announced full release version of Brian 2.","creator":{"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},"open_issues":21,"closed_issues":27,"state":"open","created_at":"2013-07-17T13:52:20Z","updated_at":"2015-08-28T15:43:14Z","due_on":null,"closed_at":null},"comments":7,"created_at":"2015-08-28T15:00:48Z","updated_at":"2015-08-31T13:27:27Z","closed_at":null,"body":"Writes to shared variables will be executed by each thread, therefore things like `s += 1` will not give the expected result. Example:\r\n```Python\r\nfrom brian2 import *\r\nset_device('cpp_standalone')\r\nprefs.devices.cpp_standalone.openmp_threads = 4\r\nG = NeuronGroup(10, 's : 1 (shared)')\r\nG.run_regularly('s += 1')\r\nrun(defaultclock.dt)\r\ndevice.build(run=True, compile=True)\r\nprint G.s\r\n```\r\nThis should print 1.0, but it prints 4.0 (or sometimes 3.0 if two threads update `s` at the same time).\r\n\r\nThis is not trivial to fix, and I'm wondering whether we don't have to introduce a massive change to the templates to correct this. The problem is that we can't simply wrap the scalar code in the template with a `simple` or `master` pragma, because then all variable definitions within this block are not accessible outside, which would prevent vector code from accessing any of the scalar variables (e.g. the `lio` constants). So we'd have to split the `scalar_code` block into a part that declares the variables and one that contains the statements. I'd prefer to avoid this, since it entails low-level changes to the code generation pipeline and will also break the GPU devices that are currently worked on. I think a better option would be to not have the OpenMP `parallel` block in the network run, but in each code object individually. This way, we could have the scalar code executed serially before going into the parallel part. Another advantage would be that there would be no longer a need for the `IS_OPENMP_COMPATIBLE` annotation -- if a template does not know about OpenMP it does not open a parallel block and everything runs serially. It would be a change to all templates, but one that would not affect the GPU devices.\r\nHowever, I think @yger did something like this when he started working on the OpenMP support and IIRC, this was too slow because of OpenMP overhead? Maybe I should just manually try this out with an example..\r\n"},"comment":{"url":"https://api.github.com/repos/brian-team/brian2/issues/comments/136370633","html_url":"https://github.com/brian-team/brian2/issues/551#issuecomment-136370633","issue_url":"https://api.github.com/repos/brian-team/brian2/issues/551","id":136370633,"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-08-31T13:27:27Z","updated_at":"2015-08-31T13:27:27Z","body":"If that doesn't work I can't think of anything else apart from splitting up the declarations and evaluations."}}