divergences nimbleHMC

51 views
Skip to first unread message

Eduardo Martins

unread,
Jun 11, 2026, 11:47:02 AM (11 days ago) Jun 11
to nimble-users
Hello,

Is it possible to get the number of divergences reported when using nimbleHMC? Only reference I seem to find about divergences is in the description of deltaMax, but that seems to be just a tuning argument.

Thanks,

Eduardo

Daniel Turek

unread,
Jun 11, 2026, 12:30:56 PM (11 days ago) Jun 11
to Eduardo Martins, nimble-users
Yes, by default (unless you've specified "messages = FALSE" when you assign an HMC sampler, or turned off the nimble-system-level "verbose" option, which has a default value of TRUE) the number of divergent HMC paths encountered will be printed automatically, at the conclusion of each individual MCMC chain.



--
You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nimble-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/nimble-users/acd9aef0-1eca-4958-ab33-a2f598eef965n%40googlegroups.com.

Eduardo Martins

unread,
Jun 11, 2026, 12:44:52 PM (11 days ago) Jun 11
to Daniel Turek, nimble-users
Thanks. Is it stored in an output object? I’m running several models in a HPC and wanted to automate a way of extracting them.

Sent from Outlook for iOS

From: Daniel Turek <danie...@gmail.com>
Sent: Thursday, 11 June 2026 18:30:14
To: Eduardo Martins <egma...@gmail.com>
Cc: nimble-users <nimble...@googlegroups.com>
Subject: Re: divergences nimbleHMC
 

Perry de Valpine

unread,
Jun 11, 2026, 1:21:24 PM (11 days ago) Jun 11
to Eduardo Martins, Daniel Turek, nimble-users
Hi Eduardo,

Good question. Yes, you can access it, but it takes a little explanation.

Compiled nimbleFunction objects automatically provide access from R to member variables and methods in the underlying C++ object. This access is provided in the reference class objects constructed to interface with the corresponding C++ objects. In other words, in R,
compiled_object$x
will access the "x" in the C++ object that compiled_object serves as an interface to. "compiled_object" itself is an R reference class object.

In this case, you will want to access a member variable called "numDivergences" in the NUTS (HMC) sampler.

However, to reduce the building of components that are only rarely used, there is a default setting that this kind of access will not be nested. In other words, compiled_object$my_object$x will not work by default, because my_object is nested within compiled_object. To make this work, you need to set a nimbleOption:

nimbleOptions(buildInterfacesForCompiledNestedNimbleFunctions = TRUE)

Now, where to find the value you want? In the compiled MCMC object, there is an object "samplerFunctions" that is a list of the samplers used. If you are using HMC as the sole sampler, then it is probably the only one on the list. There could be other samplers (possibly if you have posterior predictive nodes, for example). When you configure the samplers, you should see a list confirming that. If you are not sure, you can do MCMCconfig$printSamplers(), or you can look at the uncompiled samplerFunctions. For example, you would be doing:

model <- nimbleModel( < your inputs > )
MCMCconfig <- configureHMC(model)
MCMCconfig$printSamplers() # Look to determine where the NUTS sampler is
MCMC <- buildMCMC(MCMCconfig)
compiled <- compileNimble(model, MCMC)
runMCMC(compiled$MCMC, <your inputs > )

OR
model <- nimbleModel( < your inputs > )
MCMC <- buildHMC(model) # does configureHMC and then buildMCMC
MCMC$samplerFunctions # look at this list
<same as above>

Once you know which sampler in the samplerFunctions is the HMC sampler (say it is the 1st), and if you have set the above nimbleOption, you should be able to do

compiled$MCMC$samplerFunctions[[1]]$numDivergences

You can inspect the source code for nimbleHMC, looking at the sampler_NUTS nimbleFunction, and see in the setup code various other quantities you can access in this way.

An alternative would be to clone the nimbleHMC package and modify it. In the "after_chain" function (called for every sampler after the chain has been run), you could insert a call to a function that you could define with nimbleRcall.  This provides a way to pass any variables you want (e.g., numDivergences) back to R and then manage how to store them in any way you want. For example, you would insert into after_chain:

save_divergences(numDivergences)

where by nimbleRcall you have made "save_divergences" call an R function like "save_divergences_R", which you define normally in R like

save_divergences_R <- function(numDivergences) { < save numDivergences however you want > }

HTH! I did not test the code I gave you above so it is possible I made a mistake.

Perry
 

Eduardo Martins

unread,
Jun 11, 2026, 1:33:36 PM (11 days ago) Jun 11
to Perry de Valpine, Daniel Turek, nimble-users
Thanks so much Perry! I’ll try this out and let you know if I run into any challenges. Appreciate you guys quick response.

Sent from Outlook for iOS

From: Perry de Valpine <pdeva...@berkeley.edu>
Sent: Thursday, 11 June 2026 19:21:09
To: Eduardo Martins <egma...@gmail.com>
Cc: Daniel Turek <danie...@gmail.com>; nimble-users <nimble...@googlegroups.com>
Subject: Re: divergences nimbleHMC
 

Eduardo Martins

unread,
Jun 12, 2026, 12:21:56 AM (11 days ago) Jun 12
to Perry de Valpine, Daniel Turek, nimble-users
Hi Perry and Daniel,

Thanks again for your help. I managed to get the code working, but it looks like there may be a bug with the reporting of divergences using the sampler “NUTS” in nimbleHMC 0.2.4. It seems to always report divergences as 0, whereas the sampler “NUTS_classic” reports divergences > 0 and so does brms for a model fit to the same data set. I’ve attached a reproducible example.

Thanks,

Eduardo
nimbleHMC-divergence.R

Perry de Valpine

unread,
Jun 12, 2026, 12:38:51 PM (10 days ago) Jun 12
to Eduardo Martins, Daniel Turek, nimble-users
Hi Eduardo,

Thanks for the detailed example and report on this. 

I think you're right. I don't see numDivergences actually being incremented when a divergence is detected (setting `divergence <<- TRUE`) in sampler_NUTS.

I've made a new branch with a one-line addition to fix this. Can you please try installing from a branch as follows and then try your code:

remotes::install_github("nimble-dev/nimbleHMC", ref = "fix-numDivergences", subdir = "nimbleHMC")

I think I put the check and increment in the right place, but this algorithm is not simple so it will be worth confirming and hearing if your results now make sense. I got 58 divergences when I ran your code with the new branch.

If you are interested in related samplers, give the Barker sampler of Livingstone and Zanella (2022) and Vogrinc et al. (2023) a try. (See help(samplers) in nimble). They claim good properties relative to NUTS.

(On a more minor topic: I see you noticed that you need to turn `messages=FALSE` to avoid having `numDivergences` reset during `after_chain`, which would then only ever show you a 0 when you probe it after the MCMC run. I believe this was done so that if a user starts the sampler from where they left off, they'll get a fresh report of numDivergences, and that behavior might also be worth re-evaluating or even given a nimbleOption for fine-grained user control in a case like yours where you are investigating performance very closely.)

Perry

Eduardo Martins

unread,
Jun 13, 2026, 1:43:30 AM (10 days ago) Jun 13
to Perry de Valpine, Daniel Turek, nimble-users

Hi Perry,


Thanks so much for turning this around so quickly. I installed the branch and ran my examples. The divergence counts come through now with “NUTS", so the fix looks good on my end! Do you have a rough sense of when it might land in a released version? 


Thanks again,


Eduardo

Chris Paciorek

unread,
Jun 13, 2026, 5:07:01 PM (9 days ago) Jun 13
to Eduardo Martins, nimble-users
hi Eduardo, this is catching us at a time where we don't have any firm timeline for next release and also don't have anything much on the to-do list of thing we want for a next release (instead we are hard at work on extensive reworking of nimble's internals). So it might be a few months until we put out a minor release with this and anything else that has come up, though I suspect it would not be later than October or so.  

-chris

Reply all
Reply to author
Forward
0 new messages