n-kall / priorsense

priorsense: an R package for prior diagnostics and sensitivity
https://n-kall.github.io/priorsense/
GNU General Public License v3.0
53 stars 5 forks source link

Zombies #48

Closed avehtari closed 3 months ago

avehtari commented 3 months ago

A minimal example I see zombies left behind when using brms with cmdstanr backend. Eventually the zombies crowd the system which runs out process id's and fails to fork new threads. (Zombies are subprocesses that die, but the parent process doesn't organize funeral for them (with wait() call))

library(brms)
options(brms.backend = "cmdstanr", mc.cores = 4)
library(posterior)
library(priorsense)

SEED <- 48927 # set random seed for reproducibility

data_bern <- data.frame(y = c(1, 1, 1, 0, 1, 1, 1, 0, 1, 0))
fit_bern <- brm(y ~ 1, family = bernoulli(), data = data_bern,
                prior = prior(student_t(7, 0, 1.5), class='Intercept'),
                seed = SEED, refresh = 0)

draws <- as_draws_df(fit_bern)
draws <- draws |>
  mutate_variables(theta=plogis(b_Intercept))

#' no zombies
powerscale_sensitivity(draws, fit=fit_bern, variable="theta")

data_bin2 <- data.frame(N = c(674, 680),
                        y = c(39,22),
                        grp2 = factor(c('control','treatment')))
fit_bin2 <- brm(y | trials(N) ~ 0 + grp2, family = binomial(), data = data_bin2,
                prior = prior(student_t(7, 0,1.5), class='b'),
                seed = SEED, refresh = 0)

#' zombies with every call, the number of zombies is equal to mc.cores
#' NOTE: this is with the first fit object!
powerscale_sensitivity(draws, fit=fit_bern, variable="theta")

EDIT: added comment that number of zombies depends on mc.cores EDIT2: clarified that this happens only with cmdstanr backend EDIT3: only with brms + cmdstanr backend, not with plain cmdstanr

n-kall commented 3 months ago

Looks like the zombies are coming from brms::log_lik(fit_bern)

n-kall commented 3 months ago

It seems this occurs when cmdstanr is loaded, even if the backend used to fit the brmsfit was rstan.

m <- brms::brm(yield ~ 1, npk, backend = "rstan")
brms::log_lik(m) # no zombies

library(cmdstanr)
brms::log_lik(m) # creates zombies
avehtari commented 3 months ago

The zombies are lefty behind by the line https://github.com/paul-buerkner/brms/blob/298b947fa9cfb914aeb7cb3aab7974aa179682b1/R/log_lik.R#L127

  out <- plapply(seq_len(N), log_lik_fun, cores = cores, prep = object)
avehtari commented 3 months ago

I opened an issue https://github.com/paul-buerkner/brms/issues/1658 in brms repo, and closing this