Adding counter to likelihood
This adds a counter for each likelihood evaluation which can then be used for a fairly consistent benchmarking metric
Merge request reports
Activity
- Automatically resolved by Rhys Green
Hi @rhys.green, can you merge master into this branch, we (mostly Greg) fixed a bunch of stuff in the CI today, so it may just work.
added 3 commits
-
beef3589...8c03c68f - 2 commits from branch
lscsoft:master
- c1d4b468 - Merge branch 'master' of https://git.ligo.org/lscsoft/bilby into adding_counter_to_likelihood
-
beef3589...8c03c68f - 2 commits from branch
- Automatically resolved by Rhys Green
- Automatically resolved by Rhys Green
- Automatically resolved by Rhys Green
Hi Rhys, nice idea. I can see the motivation for this, but I just want to check a few things.
-
Is not possible to get this in post processing already? I can't directly see how, but it would be cleaner rather than doing it while sampling.
-
There is a built-in Counter object in python, it would be really good to use this as this is the sort of thing which someone sees and wants to add "prior_evaluation_counter", "other_thing_counter" etc etc. The
Counter
means there is only one object and there are explicit names for what it is counting. -
There are a few things I'm a little concerned about in the implementation (see the review comments) - if we have to hack things into weird places then okay, but it would be best if we don't.
-
There are a few places where you have added an extra line which isn't relevant to this MR. Can you remove these? It is petty I know, but it makes things much simpler if the MR doesn't include various minor additions/deletions.
-
Hi Greg, thanks for looking at this !
-
that was my first thought too but I couldn't see any obvious ways to do it. I tried doing this with something like profiling but that seemed messier than this way ? If you have any suggestions I'd be happy to change the implementation
-
I was not aware of the counter object so yea it makes sense to use that
-
I agree, (see replies in review above)
-
Sure I don't think those were actually supposed to be in this MR
-
to follow up on point 2 I'm not sure if the counter object is the best thing to use, it looks like it's not really designed to count function calls. I think the manual counter is probably cleaner If we want to make it more general, Maybe specify self.likelihood_counts rather than self.count? you could then keep the add_count function but have other self.something_else_counts like you mentioned ?
added 1 commit
- faffbc60 - replacing self.count with result.num counter, this makes the code cleaner as...
added 1 commit
- edec6e8a - adding changes to all samplers, re-adding line after init
added 35 commits
-
edec6e8a...4d2d5d36 - 34 commits from branch
lscsoft:master
- bdb9b9bb - pulling latest and fixing merge conflicts
-
edec6e8a...4d2d5d36 - 34 commits from branch
@john-veitch @colm.talbot @gregory.ashton @christopher-berry this works fine for each of the samplers apart from cpnest. The counter works for cpnest i.e. you can force it to print whilst sampling and the counter goes up but I think potentially at some point after sampling the result object is called again and the num_likelihood_evals is set to None. Anyone have any idea why this is happening/a fix ?
Edited by Rhys GreenHi @rhys.green. What do you mean the result object is "called again"? CPNest can't access anything in its Bilby control class so it can't be over-writing it.
I'm guessing this is because CPNest runs its samplers in separate processes. That means that the wrapper each sampler sees is a copy of the parent process's object as it was before you call cpnest.run(). When the samplers finish their copies of the object are destroyed, and the likelihood counts along with them. I don't see any way of passing this back to Bilby without inter-process communication, so how do the other multi-threaded samplers do it?
Probably the simplest thing to do is to add this functionality to CPNest. I'm already thinking of overhauling the IPC to fix the checkpointing bug, and that'll make it much simpler to track this sort of information.
Edited by John Douglas VeitchAlternatively, and as a quick sanity check, you could declare your counter as a multiprocessing.Value object so that all processes can see it. I wouldn't recommend using that for benchmarking though as it'll slow things down to some extent.
Edited by John Douglas VeitchHi @john-veitch what I meant by that is if I print the self.likelihood_count inside of the cpnest model log_likelihood (line 70 of cpnest.py) the numbers go up, so it must be getting that count information from the base sampler? After it has finished sampling the count goes back to zero, I didn't realise the thread copies of the result object were destroyed so this potentially explains it.
Ideally I'd like to be able to return the likelihood count information to the "parent" result objects in a similar way that the samples are but I'm not sure how to do this through bilby.
I'll try it with multi-processing value object as I suppose using that would still give a fair score in terms of samples per likelihood evaluation.
Ok so I think this now works, it's using the multiprocessing value object. I haven't noticed any significant slowdown from that but I haven't checked quantitatively. I think this implementation is okay and is potentially ready to merge if people want to include this ? @john-veitch @christopher-berry @gregory.ashton @colm.talbot what do you think ? Obviously I'm happy to change things if you guys want
added 1 commit
- 6d5dcb78 - typo - only assigned num_likelihood_evals in test section
if I print the self.likelihood_count inside of the cpnest model log_likelihood (line 70 of cpnest.py) the numbers go up, so it must be getting that count information from the base sampler? After it has finished sampling the count goes back to zero, I didn't realise the thread copies of the result object were destroyed so this potentially explains it.
Just to be clear, you are confusing multiple objects that are held by different processes. When you add a print statement, it is executed in one of the parallel processes, so it is printing the counter that belongs to that process. The version that is held by the main process does not get printed or incremented unless the likelihood is called from that process, which it isn't. So it's not "going back" to zero, it always was.
Using a multiprocessing.Value will allow you to work around this because then all processes see the same counter. It should work for any code that's based on the multiprocessing module, but that is not the only possibility. However since you just want to make progress and it doesn't produce a lot of overhead then it's probably ok.
- Resolved by Moritz Huebner
added 1 commit
- d9d3add0 - adding boolean switch to turn on/off likelihood benchmarking
changed milestone to %0.5.0
@rhys.green The MR looks mostly good to me, you need to resolve the PEP8 issues though
changed milestone to %0.5.1
added 235 commits
-
d9d3add0...a4eef56a - 234 commits from branch
lscsoft:master
- 21d46bd4 - fixing merge conflicts, also set counter to None if not used
-
d9d3add0...a4eef56a - 234 commits from branch
added 1 commit
- 9704e7fb - fixing problem where not counting caused error
@moritz.huebner @colm.talbot @gregory.ashton I think this is probably ready to be merged
- Automatically resolved by Rhys Green
- Automatically resolved by Rhys Green
added 1 commit
- bd367f3b - moving likelihood count function to base sampler to avoid duplication
@colm.talbot cheers for the helpful comments! I think I've managed to address them and this implementation is a bit tidier what do you think ?
changed milestone to %0.5.2
added 35 commits
-
7a0d5e68...d525afba - 34 commits from branch
lscsoft:master
- 39949d13 - updating to master
-
7a0d5e68...d525afba - 34 commits from branch
mentioned in commit 4a340c1e