Skip to content

Commit

Permalink
Added support for running many models
Browse files Browse the repository at this point in the history
As of now, this is an internal function only and require the models to be the same, just different parameters. Or, other cases are not yet tested...
  • Loading branch information
hrue committed Nov 26, 2024
1 parent 66c0a15 commit f9ddd54
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 12 deletions.
55 changes: 43 additions & 12 deletions inlaprog/src/inla.c
Original file line number Diff line number Diff line change
Expand Up @@ -7109,14 +7109,14 @@ int main(int argc, char **argv)
_USAGE;
exit(EXIT_FAILURE);
}
if (optind < argc - 1) {
fprintf(stderr, "\n");
for (i = 0; i < argc; i++) {
fprintf(stderr, "\targv[%1d] = [%s]\n", i, argv[i]);
if (verbose) {
if (optind < argc - 1) {
printf("\n");
for (i = 0; i < argc; i++) {
printf("\targv[%1d] = [%s]\n", i, argv[i]);
}
printf("\targc=[%1d] optind=[%1d]\n\n", argc, optind);
}
fprintf(stderr, "\targc=[%1d] optind=[%1d]\n\n", argc, optind);
fprintf(stderr, "\n*** Error: Can only process one .INI-file at the time.\n");
exit(EXIT_SUCCESS);
}
if (verbose) {
if (G.mode == INLA_MODE_HYPER) {
Expand Down Expand Up @@ -7150,24 +7150,52 @@ int main(int argc, char **argv)
}

if (G.mode == INLA_MODE_DEFAULT || G.mode == INLA_MODE_HYPER) {
char cwd_buff[1024+1], *cwd = NULL;
cwd = getcwd(cwd_buff, (size_t) 1024);

for (arg = optind; arg < argc; arg++) {
if (verbose) {
printf("Process file[%s] threads[%1d] max.threads[%1d] blas_threads_force[%1d]",
printf("\ncwd[%s]\n", cwd);
printf("Process file/directory[%s] threads[%1d] max.threads[%1d] blas_threads_force[%1d]",
argv[arg], GMRFLib_MAX_THREADS(), host_max_threads, GMRFLib_openmp->blas_num_threads_force);
if (GMRFLib_openmp->max_threads_nested) {
printf(" nested[%1d:%1d]\n", GMRFLib_openmp->max_threads_nested[0], GMRFLib_openmp->max_threads_nested[1]);
} else {
printf("\n");
}
}

if (cwd) chdir(cwd);
assert(my_dir_exists(argv[arg]) == INLA_OK || my_file_exists(argv[arg]) == INLA_OK);
char *model_ini = NULL;
if (my_file_exists(argv[arg]) == INLA_OK && my_dir_exists(argv[arg]) != INLA_OK) {
model_ini = argv[arg];
} else {
if (my_dir_exists(argv[arg]) == INLA_OK) {
char *new = strdup("Model.ini");
model_ini = new;
if (verbose) {
printf("Change directory to [%s]\n", argv[arg]);
}
chdir(argv[arg]);
} else {
fprintf(stderr, "\n\n *** ERROR *** This is neither a file or directory[%s]\n\n\n",
argv[arg]);
continue;
}
}

if (verbose) {
printf("Run with model[%s]\n", model_ini);
}
if (!silent) {
printf("\nWall-clock time used on [%s] max_threads=[%1d]\n", argv[arg], GMRFLib_MAX_THREADS());
printf("\nWall-clock time used on [%s] max_threads=[%1d]\n", model_ini, GMRFLib_MAX_THREADS());
}
time_used[0] = GMRFLib_timer();
atime_used[0] = clock();

GMRFLib_openmp_implement_strategy(GMRFLib_OPENMP_PLACES_PARSE_MODEL, NULL, NULL);
mb = inla_build(argv[arg], verbose, 1);
mb = inla_build(model_ini, verbose, 1);
GMRFLib_openmp_implement_strategy(GMRFLib_OPENMP_PLACES_BUILD_MODEL, NULL, NULL);
time_used[0] = GMRFLib_timer() - time_used[0];
atime_used[0] = clock() - atime_used[0];
Expand Down Expand Up @@ -7273,7 +7301,7 @@ int main(int argc, char **argv)
fflush(stdout);
}
if (verbose) {
printf("\nWall-clock time used on [%s]\n", argv[arg]);
printf("\nWall-clock time used on [%s]\n", model_ini);
printf("\tPreparations : %7.3f seconds\n", time_used[0]);
if (GMRFLib_inla_mode == GMRFLib_MODE_CLASSIC) {
printf("\tApprox inference : %7.3f seconds\n", time_used[1]);
Expand Down Expand Up @@ -7331,7 +7359,7 @@ int main(int argc, char **argv)
GMRFLib_sprintf(&nfile, "%s/cpu-intern", mb->dir);
FILE *fp = fopen(nfile, "w");
if (fp) {
fprintf(fp, "Wall-clock time used on [%s]\n", argv[arg]);
fprintf(fp, "Wall-clock time used on [%s]\n", model_ini);
fprintf(fp, "Preparations : %7.3f seconds\n", time_used[0]);
if (GMRFLib_inla_mode == GMRFLib_MODE_CLASSIC) {
fprintf(fp, "Approx inference : %7.3f seconds\n", time_used[1]);
Expand Down Expand Up @@ -7380,6 +7408,9 @@ int main(int argc, char **argv)
fclose(fp);
Free(nfile);
}
if (mb) {
inla_output_ok(mb->dir);
}
}
}

Expand Down
97 changes: 97 additions & 0 deletions rinla/R/inla.R
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,15 @@
}
if (keep) {
## create the directory locally or whereever specified by the user
if (!is.null(working.directory)) {
dir.create(working.directory, showWarnings = FALSE, recursive = TRUE)
}

if (is.null(working.directory)) {
working.directory <- "inla.model"
working.directory.start <- "inla.model"
} else {
working.directory <- paste0(working.directory, "/inla.model")
working.directory.start <- working.directory
}

Expand Down Expand Up @@ -2709,3 +2714,95 @@ formals(inla.core) <- formals(inla.core.safe) <- formals(inla)
do.call("Sys.setenv", vars)
return (invisible())
}

`inla.run.many` <- function(working.directory = NULL,
verbose = inla.getOption("verbose"),
num.threads = inla.getOption("num.threads"),
cleanup = FALSE)
{
stopifnot(!is.null(working.directory))
inla.call <- inla.getOption('inla.call')
silent <- inla.getOption('silent')
timeout <- inla.getOption('inla.timeout')
file.log <- inla.tempfile()
file.log2 <- inla.tempfile()
verbose.arg <- if (verbose) "-v" else ""
all.args <- paste0(verbose.arg, " -Pcompact -t", inla.getOption('num.threads'))
models <- dir(working.directory, full.names = TRUE)
mfiles <- paste(shQuote(models), collapse = " ")
timeout.used <- Sys.time()

try_catch_result <- tryCatch({
if (inla.os("linux") || inla.os("mac") || inla.os("mac.arm64")) {
if (verbose) {
echoc <- system(paste(shQuote(inla.call), all.args, mfiles), timeout = timeout)
} else {
echoc <- system(paste(
shQuote(inla.call), all.args, mfiles, " > ", shQuote(file.log),
inla.ifelse(silent == 2L, " 2>/dev/null", "")
), timeout = timeout)
}
timeout.used <- Sys.time() - timeout.used
inla.inlaprogram.timeout(timeout.used, timeout)
} else if (inla.os("windows")) {
## need to set these variables here
Sys.setenv(
MIMALLOC_ARENA_EAGER_COMMIT = 1,
MIMALLOC_PURGE_DELAY = -1,
MIMALLOC_PURGE_DECOMMITS = 0
)
if (verbose) {
echoc <- try(system2(inla.call,
args = paste(all.args, mfiles),
stdout = "", stderr = "", wait = TRUE, timeout = timeout))
} else {
echoc <- try(system2(inla.call,
args = paste(all.args, mfiles),
stdout = file.log, stderr = file.log2,
wait = TRUE, timeout = timeout))
}
## and unset them here
Sys.unsetenv(
c(
"MIMALLOC_ARENA_EAGER_COMMIT",
"MIMALLOC_PURGE_DELAY",
"MIMALLOC_PURGE_DECOMMITS"
)
)
timeout.used <- Sys.time() - timeout.used
inla.inlaprogram.timeout(timeout.used, timeout)
if (echoc != 0L) {
if (!verbose && (silent != 2L)) {
inla.inlaprogram.has.crashed()
}
}
} else {
stop("\n\tNot supported architecture.")
}
TRUE
},
error = function(e) {
errorCondition("The inla program call crashed.",
class = "inlaCrashError")
})

if (inherits(try_catch_result, "error")) {
stop(try_catch_result)
}

res <- rep(list(list()), length(models))
for(i in seq_along(models)) {
res[[i]] <- inla.collect.results(models[i])
if (!verbose && (i == 1)) {
if (file.exists(file.log)) res[[i]]$logfile <- readLines(file.log)
if (file.exists(file.log2)) res[[i]]$logfile2 <- readLines(file.log2)
}
}
unlink(file.log)
unlink(file.log2)
if (cleanup) {
unlink(working.directory, recursive = TRUE)
}

return (res)
}

0 comments on commit f9ddd54

Please sign in to comment.