JohannesBuchner / PyMultiNest

Pythonic Bayesian inference and visualization for the MultiNest Nested Sampling Algorithm and PyCuba's cubature algorithms.
http://johannesbuchner.github.io/PyMultiNest/
Other
191 stars 87 forks source link

Screen output during simulation and interrupting a run #247

Closed gabrielastro closed 5 months ago

gabrielastro commented 5 months ago

First of all, thanks for the very useful package! I am using it through species and it works very well. Now a few things:

  1. Would it be possible to have more compact output: a few lines, then an active line getting updated? I am thinking of UltraNest (example from a call from species:

    [ultranest] Sampling 1000 live points from prior ...
    [ultranest] Widening roots to 1196 live points (have 1000 already) ...
    [ultranest] Sampling 196 live points from prior ...
    [ultranest] Widening roots to 1427 live points (have 1196 already) ...
    [ultranest] Sampling 231 live points from prior ...
    3235.3(14.70%) | Like=3253.39..3258.58 [3253.3935..3253.3948]*| it/evals=18315/2127774 eff=0.8413% N=1000

    with the last line getting updated. Currently, the console buffer is filled with blocks:

    Acceptance Rate:                        0.682490
    Replacements:                             246750
    Total Samples:                            361544
    Nested Sampling ln(Z):               1063.517940
    Importance Nested Sampling ln(Z):    3229.804191 +/-  0.311776

    and it is hard to tell where one is, and whatever messages were printed before calling MultiNest are off the buffer.

  2. I do not know the details of MultiNest but would a "percentage complete" be possible/meaningful/not too complicated to implement? It would be helpful for long runs (to estimate when to get results).

  3. More importantly, is it possible to interrupt a run with Ctrl+C, for instance, but touching a "stop" file would be ok too? Currently, if I realise I made some mistake, the only solution seems to be to suspend python with Ctrl+Z and then to kill it with kill %%. My interest is for runs through species and @tomasstolker suggested it should be done from MultiNest. Please see https://github.com/tomasstolker/species/issues/89#issuecomment-1941478083. Uh, I hope you agree with him :ping_pong: :wink:.

  4. Printing a simple one-line "Using N cores in parallel" or so at the beginning of MultiNest would be nice to confirm that one indeed is using 1×N cores and not N×1 core as can happen if MPI is not set up properly. I was not sure at first and used timing tests to figure it out but this feels a bit too complicated. Depending on the problem, timing tests might not reveal that parallelisation is on, as you essentially pointed out :smile:.

JohannesBuchner commented 5 months ago

MultiNest is Fortran code written by Farhan Feroz. PyMultiNest is only the python wrapper. Most of what you ask is MultiNest-related, and nothing that PyMultiNest can control.

1) you can currently only disable the output completely. UltraNest gives fine-grained control. 2) this is not a part of PyMultiNest. UltraNest supports this. 3) this is not a part of PyMultiNest. It is complicated with the MultiNest code. UltraNest, being "pure python", supports this much better. 4) you can query this from mpi4py with from mpi4py import MPI; print(MPI.COMM_WORLD.Get_rank(), MPI.COMM_WORLD.Get_size())

Sorry to not be more useful.

gabrielastro commented 5 months ago

Thanks for your quick answer!

  1. Ok but would it not be relatively easy for PyMultiNest to catch the output of MultiNest and to erase the last line(s) on screen and print again? I do not know how this is done but I would have thought there are good python libraries for handling this.
  2. "Is not a part of" in the sense that it would be too involved or computationally expensive to compute?
  3. Ah! ok.
  4. I meant that it would be good to have the confirmation come from deeper (PyMultiNest or even MultiNest actually, and I forgot that the two are separate), but I guess you are saying that if those lines (… Get_size()) give the expected answer from the top-level, user-written script, it is basically guaranteed to be fine also at the (Py)MultiNest level. Ok, good point!
JohannesBuchner commented 5 months ago

re 1&2:

PyMultiNest just passes things to MultiNest, which calls back a function for evaluation. So PyMultiNest is not in control. For progress viz you would need either a) another thread that monitors sys.stdout/sys.stderr, but catching output doesn't work very reliably, also fortran does some weird caching. b) write a small core program that uses pymultinest, and then call this from another python program with subprocess and parse the stdout/stderr stream as you wish. This would also solve the Ctrl-C issue.

gabrielastro commented 5 months ago

Ok, thanks! Thanks for the sketch—maybe someone will feel inspired to fill it out :).