Skip to content

Commit

Permalink
Merge pull request #23 from A2-ai/cleanup
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
mduncans authored Nov 8, 2024
2 parents c2a121b + 834807d commit 1b11c17
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 61 deletions.
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: slurmtools
Title: slurm tooling
Version: 0.0.0.9003
Version: 0.0.0.9004
Authors@R: c(person("Devin", "Pastoor", , "[email protected]", role = c("aut", "cre")),
person("Jenna", "Elwing", email = "[email protected]", role = "aut"),
person("Matthew", "Smith", email = "[email protected]", role = "aut"))
Expand All @@ -25,7 +25,8 @@ Imports:
here,
cli,
stringi,
hms
hms,
lifecycle
Suggests:
knitr,
rmarkdown,
Expand Down
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export(cancel_slurm_job)
export(generate_nmm_config)
export(get_slurm_jobs)
export(get_slurm_partitions)
export(submit_nonmem_model)
export(submit_slurm_job)
importFrom(brio,read_file)
importFrom(brio,write_file)
importFrom(dplyr,"%>%")
Expand Down
47 changes: 26 additions & 21 deletions R/cancel-job.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#' Cancels a running job
#'
#' @param job_id job id to cancel
#' @param user optional if not the current user.
#' @param confirm requires confirmation to cancel job
#' @importFrom rlang .data
#' @importFrom rlang .env
#'
Expand All @@ -10,38 +10,43 @@
#' @examples \dontrun{
#' cancel_job(243)
#' }
cancel_slurm_job <- function(job_id, user = NULL) {
cancel_slurm_job <- function(job_id, confirm = TRUE) {

current_user = if (is.null(Sys.getenv("USER"))) Sys.info()['user'] else Sys.getenv("USER")

if (!is.null(user) && user != current_user) {
cat("The supplied user does not match the current user.\n")
cat(paste0("\tsupplied user: ", user, "\n\tcurrent_user: ", current_user, "\n"))
cat("You might be cancelling someone elses job.")
continue <- readline("Are you sure you want to cancel this job? (Y/n)\n")
if (continue == "Y") {
current_user <- user
} else if (tolower(continue) == "n") {
stop(paste0("Not cancelling job: ", job_id))
} else {
stop("Please enter Y or n")
}
}

jobs <- get_slurm_jobs(user = current_user)

if (!job_id %in% jobs$job_id) {
stop("Please ensure the job id is correct.")
if (job_id %in% get_slurm_jobs()$job_id) {
message("This job is associated with a different user")
}
message(paste0("Below are the available jobs for you to cancel:"))
print(get_slurm_jobs(user = current_user))
stop(paste0("Please ensure the job id is associated your user_name: ", current_user))
}

job_id_filtered <- jobs %>% dplyr::filter(.data$job_id == .env$job_id)
if (!job_id_filtered$job_state %in% c("RUNNING", "CONFIGURING")) {
stop(paste0("Job: ", job_id, " is not running"))
}

result <- processx::run("scancel", args = c(as.character(job_id)))
if (result$status != 0) {
print(paste0("Stdout: ", result$stdout))
print(paste0("Stderr: ", result$stderr))
if (confirm) {
continue <- readline(
paste0("You are about to cancel job: ", job_id, ". Are you sure you want to cancel? [Y/n]\n")
)
} else {
continue <- "Y"
}

if (continue == "Y") {
result <- processx::run("scancel", args = c(as.character(job_id)))
if (result$status != 0) {
print(paste0("Stdout: ", result$stdout))
print(paste0("Stderr: ", result$stderr))
}
} else if (tolower(continue) == 'n') {
stop("Job NOT cancelled.")
} else {
stop("You must enter Y or n")
}
}
2 changes: 1 addition & 1 deletion R/slurmtools.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#'
#' @section submitting jobs:
#' \itemize{
#' \item \code{\link{submit_nonmem_model}}: Submits a job to slurm
#' \item \code{\link{submit_slurm_job}}: Submits a job to slurm
#' \item \code{\link{generate_nmm_config}}: Generates a NONMEMmonitor config
#' file
#' }
Expand Down
139 changes: 137 additions & 2 deletions R/submit-model.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
#' @param bbi_config_path path to bbi.yaml file for bbi configuration
#' @param slurm_template_opts choose slurm template
#'
#' @export
#' @description
#' `r lifecycle::badge("deprecated")`
#'
#'
#' @keywords internal
submit_nonmem_model <-
function(.mod,
partition = get_slurm_partitions(),
Expand All @@ -23,7 +27,7 @@ submit_nonmem_model <-
submission_root = getOption('slurmtools.submission_root'),
bbi_config_path = getOption('slurmtools.bbi_config_path'),
slurm_template_opts = list()) {

lifecycle::deprecate_soft("0.1.0", "submit_nonmem_model()", "submit_slurm_job()")
if (is.null(partition)) {
rlang::abort("no partition selected")
}
Expand Down Expand Up @@ -127,3 +131,134 @@ submit_nonmem_model <-
processx::run(cmd$cmd, cmd$args, ...)
})
}

#' submit a nonmem model to slurm in parallel
#'
#' @param .mod a path to a model or a bbi nonmem model object
#' @param partition name of the partition to submit the model
#' @param ncpu number of cpus to run the model against
#' @param overwrite whether to overwrite existing model results
#' @param dry_run return the command that would have been invoked, without invoking
#' @param ... arguments to pass to processx::run
#' @param slurm_job_template_path path to slurm job template
#' @param submission_root directory to track job submission scripts and output
#' @param bbi_config_path path to bbi.yaml file for bbi configuration
#' @param slurm_template_opts choose slurm template
#'
#' @export
submit_slurm_job <-
function(.mod,
partition = get_slurm_partitions(),
ncpu = 1,
overwrite = FALSE,
dry_run = FALSE,
...,
slurm_job_template_path = getOption('slurmtools.slurm_job_template_path'),
submission_root = getOption('slurmtools.submission_root'),
bbi_config_path = getOption('slurmtools.bbi_config_path'),
slurm_template_opts = list()) {

if (is.null(partition)) {
rlang::abort("no partition selected")
}
partition <- match.arg(partition)

check_slurm_partitions(ncpu, partition)

if (!inherits(.mod, "bbi_nonmem_model") &&
!fs::file_exists(.mod)) {
stop(
"please provide a bbi_nonmem_model created via read_model/new_model, or a path to the model file"
)
}
if (!inherits(.mod, "bbi_nonmem_model")) {
# its a file path that exists so lets convert that into the structure bbi
# provides for now
.mod <- list(absolute_model_path = fs::path_abs(.mod))
}
parallel <- if (ncpu > 1) {
TRUE
} else {
FALSE
}

if (!fs::file_exists(slurm_job_template_path)) {
rlang::abort(sprintf("slurm job template path not valid: `%s`", slurm_job_template_path))
}
if (overwrite && fs::dir_exists(.mod$absolute_model_path)) {
fs::dir_delete(.mod$absolute_model_path)
}

config_toml_path <- paste0(.mod$absolute_model_path, ".toml")
#if (!fs::file_exists(config_toml_path)) {
# rlang::warn(sprintf("config.toml file not found, if submitting the job with nmm this is required. Please run generate_nmm_config()"))
#}

if (is.null(slurm_template_opts$nmm_exe_path)) {
nmm_exe_path <- Sys.which("nmm")
} else {
nmm_exe_path <- slurm_template_opts$nmm_exe_path
}

if (is.null(slurm_template_opts$bbi_exe_path)) {
bbi_exe_path <- Sys.which("bbi")
} else {
bbi_exe_path <- slurm_template_opts$bbi_exe_path
}

if (is.null(slurm_template_opts$project_path)) {
project_path <- here::here()
} else {
project_path <- slurm_template_opts$project_path
}
if (is.null(slurm_template_opts$project_name)) {
project_name <- here::here() %>% basename()
} else {
project_name <- slurm_template_opts$project_name
}

default_template_list = list(
partition = partition,
parallel = parallel,
ncpu = ncpu,
job_name = sprintf("%s-nonmem-run", basename(.mod$absolute_model_path)),
project_path = project_path,
project_name = project_name,
bbi_exe_path = bbi_exe_path,
bbi_config_path = bbi_config_path,
model_path = .mod$absolute_model_path,
config_toml_path = config_toml_path,
nmm_exe_path = nmm_exe_path
)

template_list = c(
default_template_list,
slurm_template_opts)

template_script <-
withr::with_dir(dirname(.mod$absolute_model_path), {
tmpl <- brio::read_file(slurm_job_template_path)
whisker::whisker.render(
tmpl,
template_list
)
})

script_file_path <-
file.path(submission_root, sprintf("%s.sh", basename(.mod$absolute_model_path)))
if (!dry_run) {
if (!fs::dir_exists(submission_root)) {
fs::dir_create(submission_root)
}
brio::write_file(template_script, script_file_path)
fs::file_chmod(script_file_path, "0755")
}
cmd <- list(cmd = Sys.which("sbatch"), args = script_file_path, template_script = template_script, partition = partition)
if (dry_run) {
return(cmd)
}
withr::with_dir(submission_root, {
processx::run(cmd$cmd, cmd$args, ...)
})
}

2 changes: 1 addition & 1 deletion _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ navbar:
reference:
- title: Data Processing Functions
contents:
- submit_nonmem_model
- submit_slurm_job
- generate_nmm_config
- get_slurm_jobs
- cancel_slurm_job
Expand Down
4 changes: 2 additions & 2 deletions man/cancel_slurm_job.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/slurmtools.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/submit_nonmem_model.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions man/submit_slurm_job.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1b11c17

Please sign in to comment.