From 4075523da0d5affe641275924a585e22a2768545 Mon Sep 17 00:00:00 2001 From: Sarah Griffiths Date: Thu, 21 May 2026 13:56:33 +0000 Subject: [PATCH] Bambu always 1 thread [CW-7265] --- bin/workflow_glue_r/R/bambu.R | 34 +++---------------- .../tests/testthat/test_bambu.R | 22 +++--------- modules/local/bambu_chunked.nf | 14 ++------ 3 files changed, 10 insertions(+), 60 deletions(-) diff --git a/bin/workflow_glue_r/R/bambu.R b/bin/workflow_glue_r/R/bambu.R index 5af7b5d..86f4788 100644 --- a/bin/workflow_glue_r/R/bambu.R +++ b/bin/workflow_glue_r/R/bambu.R @@ -64,14 +64,6 @@ bambu_arg_spec <- function() { default = "discover", choices = c("discover", "fixed_annotation") ), - list( - name = "threads", - flag = "--threads", - help = "Number of worker threads.", - type = "integer", - default = 1L, - min = 1L - ), list( name = "ndr", flag = "--ndr", @@ -258,11 +250,13 @@ bambu_discovery_enabled <- function(args) { } bambu_build_args <- function(args, reads, annotation_obj, discovery, quant) { + # Pin bambu to ncore=1 in all modes to avoid parallel worker instability. + ncore <- 1L bambu_args <- list( reads = reads, annotations = annotation_obj, genome = args$genome, - ncore = as.integer(args$threads), + ncore = ncore, discovery = discovery, quant = quant, lowMemory = TRUE, @@ -301,25 +295,6 @@ bambu_message_ndr <- function(args) { message(sprintf(" Current NDR = %.3f balances precision and recall", args$ndr)) } } - -bambu_effective_threads <- function(args, bam_count) { - # bambu's low-memory mode can have issues with multiple BAMs and - # parallel threads due to BiocFileCache writes, - # so we enforce single-threading in that case. - threads <- as.integer(args$threads) - if (bam_count > 1 && threads > 1L) { - warning( - paste( - "Low-memory mode with multiple BAMs can fail in bambu due to", - "parallel BiocFileCache writes; forcing threads=1." - ), - call. = FALSE - ) - return(1L) - } - threads -} - bambu_normalise_rc_file_list <- function(rc_files, aliases = NULL) { if (!is.list(rc_files)) { rc_files <- list(rc_files) @@ -409,13 +384,12 @@ bambu_write_discovery_outputs <- function(out_dir, rc_files, discovered_annotati bambu_run_discover_mode <- function(args, analysis_fn, prepare_annotations_fn, bamfile_list_ctor) { inputs <- bambu_resolve_inputs(args, bamfile_list_ctor = bamfile_list_ctor) - args$threads <- bambu_effective_threads(args, length(inputs$bam_paths)) annotation_obj <- prepare_annotations_fn(args$annotation) if (length(inputs$bam_paths) > 1) { message(sprintf("Using BamFileList yieldSize = %d", bambu_default_yield_size)) } - message(sprintf("Running bambu discover setup with threads = %d", args$threads)) + message("Running bambu discover setup with ncore = 1") message("Generating bambu rcFiles...") rc_files <- bambu_call_analysis( analysis_fn, diff --git a/bin/workflow_glue_r/tests/testthat/test_bambu.R b/bin/workflow_glue_r/tests/testthat/test_bambu.R index b86ea21..b765698 100644 --- a/bin/workflow_glue_r/tests/testthat/test_bambu.R +++ b/bin/workflow_glue_r/tests/testthat/test_bambu.R @@ -101,11 +101,6 @@ testthat::test_that("invalid discovery settings rejected", { testthat::expect_silent(workflow_glue_r_normalise_args(args, bambu_arg_spec())) args$ndr <- 1 testthat::expect_silent(workflow_glue_r_normalise_args(args, bambu_arg_spec())) - - args$ndr <- NULL - args$threads <- "2" - normalised <- workflow_glue_r_normalise_args(args, bambu_arg_spec()) - testthat::expect_identical(normalised$threads, 2L) }) # Fail fast if --bams is empty rather than passing empty input to bambu. @@ -259,7 +254,6 @@ testthat::test_that("bambu args include requested discovery and quant flags", { args <- list( genome = "genome.fa", - threads = 3L, transcriptome_mode = "discover", ndr = 0.2 ) @@ -273,7 +267,7 @@ testthat::test_that("bambu args include requested discovery and quant flags", { testthat::expect_true(discover$discovery) testthat::expect_false(discover$quant) testthat::expect_equal(discover$NDR, 0.2) - testthat::expect_equal(discover$ncore, 3L) + testthat::expect_equal(discover$ncore, 1L) testthat::expect_true(discover$lowMemory) testthat::expect_equal(discover$yieldSize, 250000L) @@ -376,8 +370,7 @@ testthat::test_that("discover mode writes chunked rc outputs", { aliases = "sampleA,sampleB", sample_sheet = sample_sheet, transcriptome_mode = "discover", - ndr = 0.25, - threads = 2 + ndr = 0.25 ), bambu_arg_spec() ) @@ -497,8 +490,7 @@ testthat::test_that("quant mode writes chunk quantification outputs", { chunk_rds = chunk_rds, discovered_annotation_rds = discovered_annotation_rds, transcriptome_mode = "discover", - ndr = NULL, - threads = 2 + ndr = NULL ), bambu_arg_spec() ) @@ -562,8 +554,7 @@ testthat::test_that("quant mode skips chunks with no discovered annotations on t chunk_rds = chunk_rds, discovered_annotation_rds = discovered_annotation_rds, transcriptome_mode = "discover", - ndr = NULL, - threads = 2 + ndr = NULL ), bambu_arg_spec() ) @@ -1000,7 +991,6 @@ testthat::test_that("CLI discover writes reusable chunk artifacts", { "--annotation", annotation, "--genome", reference, "--transcriptome_mode", "fixed_annotation", - "--threads", "1", "--out_dir", out_dir ) ) @@ -1064,7 +1054,6 @@ testthat::test_that("CLI quant consumes a discover chunk", { "--annotation", annotation, "--genome", reference, "--transcriptome_mode", "fixed_annotation", - "--threads", "1", "--out_dir", discover_out_dir ) ) @@ -1089,7 +1078,6 @@ testthat::test_that("CLI quant consumes a discover chunk", { "--chunk_rds", manifest$rds_path[[1]], "--discovered_annotation_rds", file.path(discover_out_dir, "bambu_discovered_annotations.rds"), "--genome", reference, - "--threads", "1", "--out_dir", out_dir ) ) @@ -1147,7 +1135,6 @@ testthat::test_that("CLI collate consumes quant chunk directories", { "--annotation", annotation, "--genome", reference, "--transcriptome_mode", "fixed_annotation", - "--threads", "1", "--out_dir", discover_out_dir ) ) @@ -1172,7 +1159,6 @@ testthat::test_that("CLI collate consumes quant chunk directories", { "--chunk_rds", manifest$rds_path[[1]], "--discovered_annotation_rds", file.path(discover_out_dir, "bambu_discovered_annotations.rds"), "--genome", reference, - "--threads", "1", "--out_dir", chunk_out_dir ) ) diff --git a/modules/local/bambu_chunked.nf b/modules/local/bambu_chunked.nf index 7d009db..92bcd1e 100644 --- a/modules/local/bambu_chunked.nf +++ b/modules/local/bambu_chunked.nf @@ -5,11 +5,7 @@ OPTIONAL_FILE = file("$projectDir/data/OPTIONAL_FILE") process bambuDiscover { label "wf_transcriptomes" - cpus { - int requested = (params.threads ?: 4) as int - int sampleCount = aliases instanceof Collection ? aliases.size() : 1 - sampleCount > 1 ? requested : 1 - } + cpus 1 memory "60 GB" input: tuple val(meta), val(aliases), path(bams, stageAs: "bams/??.bam"), path(bais, stageAs: "bams/??.bam.bai"), path(sample_sheet) @@ -32,7 +28,6 @@ process bambuDiscover { --annotation "${annotation}" \ --genome "${reference}" \ --transcriptome_mode "${params.transcriptome_mode}" \ - --threads ${task.cpus} \ ${ndr_arg} \ --out_dir discover """ @@ -41,11 +36,7 @@ process bambuDiscover { process bambuQuant { label "wf_transcriptomes" - cpus { - int requested = (params.threads ?: 4) as int - boolean isJoint = meta instanceof Map && meta.alias == 'cohort' - isJoint ? requested : 1 - } + cpus 1 memory { ["8.GB", "16.GB", "48.GB"][task.attempt - 1] } maxRetries 2 errorStrategy 'retry' @@ -60,7 +51,6 @@ process bambuQuant { --chunk_rds "${chunk_rds}" \ --discovered_annotation_rds "${discovered_annotation}" \ --genome "${reference}" \ - --threads ${task.cpus} \ --out_dir "${chunk_id}" """ }