Thanks! Now it's working. Well, almost...
I think there are scoping issues that are causing me problems. I have two examples.
For the first, the code is below: when I try to parallelise it, I get the following error:
Error in checkForRemoteErrors(val) :
2 nodes produced errors; first error: R function 'calc_dmnormAltParams' in the code 'calc_dmnormAltParams(lifted_chol_oPomega_oB1to11_comma_1to11_cB_cP[1:11, 1:11], 1, 0)' does not exist.
I can use clusterExport() to export functions I know, but nimble is evidently creating new functions that I would need to track down, so I'm hoping there's a better approach.
At least I'm making progress.
Bob
library(disdat)
library(nimble)
dbern_vec <- nimbleFunction( ## Define the distribution
run = function(x = double(1), p = double(1), wt = double(1),
log = integer(0, default = 0)) {
returnType(double(0))
logProb <- sum(wt*dbinom(x=x, size=1, prob=p, log = TRUE))
if(log) return(logProb)
else return(exp(logProb))
})
rbern_vec <- nimbleFunction( ## Define a simulation function, optionally.
run = function(n = integer(0), p = double(1), wt = double(1)) {
returnType(double(1))
if(n != 1) print("rbern_vec only allows n = 1; using n = 1.")
smp <- rbinom(n, p, size=1)
return(smp)
})
MaxNetcode <- nimbleCode({
for(j in 1:k) {
ratetau[j] <- MeanLambda*reg[j]
sigma2[j] ~ dexp(rate=ratetau[j])
}
omega[1:k, 1:k] <- diag(1/sigma2[1:k]) # precision
alpha ~ dnorm(0, sd = 1)
beta[1:k] ~ dmnorm(zeros[1:k], omega[1:k, 1:k])
linpred[1:n] <- alpha + X[1:n, 1:k] %*% beta[1:k]
logit(Prob[1:n]) <- linpred[1:n]
y[1:n] ~ dbern_vec(p=Prob[1:n], wt=W[1:n])
})
DoAll <- function(X=1, cod, dat, cons, init) {
Model <- nimbleModel(code = cod, data = dat,
constants = cons, inits = init)
CmyModel <- compileNimble(Model, showCompilerOutput = FALSE)
ConfModel <- configureMCMC(CmyModel)
Targets <- c("alpha", paste0("beta[", 1:Const$k, "]"))
ConfModel$addMonitors(Targets)
ConfModel$addSampler(target = c("alpha", "beta"), type = "RW_block",
control = list(adaptInterval = 5))
myMCMC <- buildMCMC(ConfModel, monitors = Targets)
CmyMCMC <- compileNimble(myMCMC)
mcmc <- runMCMC(CmyMCMC, samplesAsCodaMCMC=TRUE, inits=init,
nchains=1, nburnin = 5, niter=10, thin=1)
mcmc
}
CAN <- disData("CAN")
EnvPO <- c("alt", "asp2", "ontprec", "ontprec4", "ontprecsd", "ontslp",
"onttemp", "onttempsd", "onttmin4", "ontveg", "watdist")
Species <- "can02"
SpData <- rbind(CAN$po[CAN$po$spid==Species,c("occ", EnvPO)], CAN$bg[,c("occ", EnvPO)])
SpData[,EnvPO] <- apply(SpData[,EnvPO], 2, scale) # scale covariates
mm <- as.matrix(SpData[,EnvPO])
weights <- SpData$occ + (1 - SpData$occ) * 100
Const <- list(n = nrow(mm), k = ncol(mm), MeanLambda = 1,
zeros=rep(0,ncol(mm)))
Data = list(y = SpData$occ, X = mm, W=rep(1,nrow(mm)), reg=rep(1, ncol(mm)))
Inits = list(alpha = rnorm(1, log(1/(1+1/mean(SpData$occ))), 1),
beta = rnorm(Const$k, 0, sd=0.1), sigma2=rep(1, ncol(mm)))
this_works <- lapply(1:2, DoAll,cod=MaxNetcode, dat=Data, cons=Const, init=Inits)
library(parallel)
a_cluster <- makeCluster(2)
clusterExport(cl = a_cluster, varlist = c("nimbleModel", "dbern_vec"))
this_doesnt_work <- parLapply(cl=a_cluster, 1:2, DoAll, cod=MaxNetcode, dat=Data, cons=Const, init=Inits)
stopCluster(a_cluster)