sampler doesn't sample in parallel

47 views
Skip to first unread message

David Christianson

unread,
Apr 30, 2025, 11:21:12 AM4/30/25
to nimble-users
Hello All, Has anyone else encountered an issue where a node is sampled well on a single chain but the sampler sticks when running the model in parallel on multiple chains?  In my case, I started with a model that wasn't sampling a node on a single chain until I forced a slice sampler on that node.  However, when I switched to running in parallel, by wrapping my nimbleModel, compile, config, remove/add sampler, build, compile, run lines inside a function as recommended, the same nodes do not move beyond passed their initial values. Adjusting the sliceWidth control to start with a large initial width didn't help.  The parallelization is not effecting the other nodes in the model. I can also see from the trace plots that stuck nodes are accepting their random initial values.  Here is a snippet of the parallelization code where I think the problem must lie:
run_MCMC_allcode <- function(X, data, constants, code, monitors, niter, nburnin, thin){
  library(nimble)
  dmy_function<-nimbleFunction(...#custom function)
  assign(' dmy_function  ',  dmy_function  , envir = .GlobalEnv)
  inits <- X$inits
  # Build model
  model <- nimbleModel(code = code,
                       data = data,
                       constants = constants,
                       inits = inits)
  assign('rmy_function',  rmy_function  , envir = .GlobalEnv) # dummy random
  cmodel <- compileNimble(model)
  conf <- configureMCMC(cmodel, monitors = monitors)
  conf$removeSamplers(paste0("K[", 1:constants$S, "]")) # this is stuck node K: discrete scalars
  for(i in seq_len(constants$S)) {
    conf$addSampler(target = paste0("K[", i, "]"),
                    type   = "slice")
  }
  modbuild<- buildMCMC(conf)
  modc <- compileNimble(modbuild, project = model)
  seed <- X$seed
  results <- runMCMC(modc, niter = niter, nburnin = nburnin, thin = thin, setSeed = seed)
  return(list(results = results, seed = seed))
}

output <- parLapply(cl = cl, X = inputsList,
                      fun = run_MCMC_allcode,
                      data = data,
                      constants = constants,
                      code = code,
                      monitors = c("lambdaM","alpha","sigma","pbar",
                                    "M","K"),
                      niter = 1000,
                      nburnin = 100,
                      thin = 1)

Chris Paciorek

unread,
May 2, 2025, 8:07:41 PM5/2/25
to David Christianson, nimble-users
hi David,

This does sound odd. Parallelization shouldn't affect the sampling. In fact if you run a single chain with a particular random number seed on its own, and then run multiple chains in parallel with one of them having the same seed as the single chain, the two chains should give identical results. Could you try that?

Perhaps a side note, but I think you're saying the K[1], ..., K[S] are S different discrete random variables and that things get unstuck when you assign slice samplers to them. This is strange because the default sampler for a categorical random variable (if that's what each `K[i]` - perhaps I'm misunderstanding) should be a conjugate sampler in the sense that the sampler will determine the log-probability of the model under each possible value for K[i] and then draw from a categorical distribution. So it's almost guaranteed to move around unless somehow the log-probability values for all but the current value are -Inf. 

So it may be worth investigating why the K[i] nodes are stuck with the default sampler. One way to do that is to set up an uncompiled MCMC. Suppose "MCMC" is the object returned from "buildMCMC()". You should be able to access samplers via  `MCMC$samplerFunctions[[i]]` where `i` is a choice of which sampler you want to look at. E.g. you can set the state of the model, then the seed, and then manually call one iteration of sampler i:
```
MCMC$samplerFunctions[[i]]$run()
```
You can also invoke the R debugger (`debug(MCMC$samplerFunctions[[i]]$run)`) and then invoke the code above to be able to step through the steps of the sampler and hopefully identify why it doesn't like any of the possible values other than the current one.

You could also run the MCMC for a few iterations and then try the above, though it will run very slowly in uncompiled mode.

I'm happy to iterate here with you. In addition to trying the first thing I suggested, it would help if you could provide the model code and let me know what default sampler is assigned to the problematic K nodes.

-chris



--
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/7c0bdaa1-02a0-4957-b82c-cdd9a7040527n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages