Skip to content

Commit f13cb36

Browse files
committed
allow multiple-rows per array
1 parent 0c3f898 commit f13cb36

File tree

5 files changed

+146
-20
lines changed

5 files changed

+146
-20
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: SimDesign
22
Title: Structure for Organizing Monte Carlo Simulation Designs
3-
Version: 2.16.4
3+
Version: 2.16.5
44
Authors@R: c(person("Phil", "Chalmers", email = "rphilip.chalmers@gmail.com", role = c("aut", "cre"),
55
comment = c(ORCID="0000-0001-5332-2810")),
66
person("Matthew", "Sigal", role = c("ctb")),

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Changes in SimDesign 2.17
44

5+
- `runArraySimulation()` gains a `array2row` function to allow array jobs
6+
to index multiple conditions in the `design` object (default uses one
7+
`arrayID` per row, the original behaviour)
8+
59
- `runArraySimulation()` gains `parallel` flag and friends to use multi-core
610
processing within array distributions. RNG numbers within the L'Ecuyer-CMRG
711
algorithm are incremented using `parallel::nextRNGSubStream()` within each

R/SimCollect.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ SimCollect <- function(files = NULL, filename = NULL,
280280
return(invisible(TRUE))
281281
}
282282
}
283+
if(all(is.na(out$WARNINGS))) out$WARNINGS <- NULL
284+
if(all(is.na(out$ERRORS))) out$ERRORS <- NULL
283285
class(out) <- c('SimDesign', class(out))
284286
if(length(unique(out$REPLICATIONS)) != 1L)
285287
warning("Simulation results do not contain the same number of REPLICATIONS")

R/runArraySimulation.R

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@
7878
#' @param addArrayInfo logical; should the array ID and original design row number
7979
#' be added to the \code{SimExtract(..., what='results')} output?
8080
#'
81+
#' @param array2row user defined function with the single argument \code{arrayID}.
82+
#' Used to convert the detected \code{arrayID}
83+
#' into a suitable row index in the \code{design} object input. By default
84+
#' each \code{arrayID} is associated with its respective row in \code{design}.
85+
#'
86+
#' For example, if each \code{arrayID} should evaluate 10 rows in
87+
#' the \code{design} object then the function
88+
#' \code{function(arrayID){1:10 + 10 * (arrayID-1)}} can be passed to \code{array2row}
89+
#'
8190
#' @param control control list passed to \code{\link{runSimulation}}.
8291
#' In addition to the original \code{control} elements two
8392
#' additional arguments have been added:
@@ -237,12 +246,61 @@
237246
#' setwd('..')
238247
#' SimClean(dirs='sim/')
239248
#'
249+
#'
250+
#' ############
251+
#' # same as above, however passing different amounts of information depending
252+
#' # on the array ID
253+
#' array2row <- function(arrayID){
254+
#' switch(arrayID,
255+
#' "1"=1:8,
256+
#' "2"=9:14,
257+
#' "3"=15)
258+
#' }
259+
#'
260+
#' # arrayID 1 does row 1 though 8, arrayID 2 does 9 to 14
261+
#' array2row(1)
262+
#' array2row(2)
263+
#' array2row(3) # arrayID 3 does 15 only
264+
#'
265+
#' # emulate remote array distribution with only 3 arrays
266+
#' sapply(1:3, \(arrayID)
267+
#' runArraySimulation(design=Design5, replications=10,
268+
#' generate=Generate, analyse=Analyse,
269+
#' summarise=Summarise, iseed=iseed, arrayID=arrayID,
270+
#' filename='condition', dirname='sim', array2row=array2row)) |> invisible()
271+
#'
272+
#' # If necessary, conditions above will manually terminate before
273+
#' # 4 hours and 4GB of RAM are used, returning any
274+
#' # successfully completed results before the HPC session times
275+
#' # out (provided .slurm script specified more than 4 hours)
276+
#'
277+
#' # list saved files
278+
#' dir('sim/')
279+
#'
280+
#' setwd('sim')
281+
#'
282+
#' # note that all row conditions are still stored separately
283+
#' condition14 <- readRDS('condition-14.rds')
284+
#' condition14
285+
#' SimResults(condition14)
286+
#'
287+
#' # aggregate simulation results into single file
288+
#' final <- SimCollect(files=dir())
289+
#' final
290+
#'
291+
#' SimResults(final) |> View()
292+
#'
293+
#' setwd('..')
294+
#' SimClean(dirs='sim/')
295+
#'
296+
#'
240297
#' }
241298
#'
242299
runArraySimulation <- function(design, ..., replications,
243300
iseed, filename, dirname = NULL,
244301
arrayID = getArrayID(),
245-
filename_suffix = paste0("-", arrayID),
302+
array2row = function(arrayID) arrayID,
303+
filename_suffix = paste0("-", array2row(arrayID)),
246304
addArrayInfo = TRUE,
247305
parallel = FALSE, cl = NULL,
248306
ncores = parallel::detectCores() - 1L,
@@ -269,6 +327,7 @@ runArraySimulation <- function(design, ..., replications,
269327
if(length(replications) > 1L)
270328
replications <- replications[arrayID]
271329
stopifnot(arrayID %in% 1L:nrow(design))
330+
rowpick <- array2row(arrayID)
272331
if(!is.null(filename))
273332
filename <- paste0(filename, filename_suffix)
274333
if(!is.null(dirname)){
@@ -284,23 +343,26 @@ runArraySimulation <- function(design, ..., replications,
284343
on.exit(parallel::stopCluster(cl), add=TRUE)
285344
}
286345
}
287-
seed <- genSeeds(design, iseed=iseed, arrayID=arrayID)
288-
dsub <- design[arrayID, , drop=FALSE]
289-
attr(dsub, 'Design.ID') <- attr(design, 'Design.ID')[arrayID]
290-
291-
ret <- runSimulation(design=dsub, replications=replications,
292-
filename=filename, seed=seed,
293-
verbose=FALSE, save_details=save_details,
294-
parallel=parallel, cl=cl,
295-
control=control, save=FALSE, ...)
296-
if(addArrayInfo && (is.null(dots$store_results) ||
297-
(!is.null(dots$store_results) && isTRUE(dots$store_results)))){
298-
results <- SimExtract(ret, 'results')
299-
condition <- attr(design, 'Design.ID')
300-
results <- dplyr::mutate(results, arrayID=arrayID, .before=1L)
301-
results <- dplyr::mutate(results, condition=condition[arrayID], .before=1L)
302-
attr(ret, "extra_info")$stored_results <- results
303-
saveRDS(ret, paste0(filename, '.rds'))
346+
for(i in 1L:length(rowpick)){
347+
row <- rowpick[i]
348+
seed <- genSeeds(design, iseed=iseed, arrayID=row)
349+
dsub <- design[row, , drop=FALSE]
350+
attr(dsub, 'Design.ID') <- attr(design, 'Design.ID')[row]
351+
ret <- runSimulation(design=dsub, replications=replications,
352+
filename=filename[i], seed=seed,
353+
verbose=FALSE, save_details=save_details,
354+
parallel=parallel, cl=cl,
355+
control=control, save=FALSE, ...)
356+
if(addArrayInfo && (is.null(dots$store_results) ||
357+
(!is.null(dots$store_results) && isTRUE(dots$store_results)))){
358+
results <- SimExtract(ret, 'results')
359+
condition <- attr(design, 'Design.ID')
360+
results <- dplyr::mutate(results, arrayID=arrayID, .before=1L)
361+
results <- dplyr::mutate(results, condition=condition[arrayID], .before=1L)
362+
attr(ret, "extra_info")$stored_results <- results
363+
saveRDS(ret, paste0(filename[i], '.rds'))
364+
}
304365
}
366+
if(length(rowpick) > 1L) ret <- NULL
305367
invisible(ret)
306368
}

man/runArraySimulation.Rd

Lines changed: 59 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)