From a3c3b0dad210d3b6602a59f72731de59a9c6a9f1 Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Fri, 31 Jul 2026 13:43:46 +0200 Subject: [PATCH 1/5] solve all of lm's mod2 columns at once Every column of mod2 is regressed on the same design matrix, but the script called `fastLm()` once per column inside a serial `pblapply()`, redoing an n x 51 decomposition for each of the ~229k ATAC peaks. Solving the normal equations once gives the identical fit -- on synthetic data of that shape the predictions agree to 2e-15, also when the design matrix is badly conditioned. In run 1gVHaBsNbAHcfT lm was the only method near its walltime, at 7.6h of 8h. * Replace the per-column loop with a single `solve()` * Drop the now unused RcppArmadillo and pbapply dependencies --- src/methods/lm/config.vsh.yaml | 2 +- src/methods/lm/script.R | 21 +++++---------------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/methods/lm/config.vsh.yaml b/src/methods/lm/config.vsh.yaml index 2287e8bf..c452ed1e 100644 --- a/src/methods/lm/config.vsh.yaml +++ b/src/methods/lm/config.vsh.yaml @@ -27,7 +27,7 @@ engines: image: openproblems/base_r:1 setup: - type: r - cran: [ lmds, RcppArmadillo, pbapply] + cran: [ lmds ] runners: - type: executable - type: nextflow diff --git a/src/methods/lm/script.R b/src/methods/lm/script.R index 9ced5385..e46efc91 100644 --- a/src/methods/lm/script.R +++ b/src/methods/lm/script.R @@ -1,6 +1,5 @@ cat("Loading dependencies\n") requireNamespace("anndata", quietly = TRUE) -requireNamespace("pbapply", quietly = TRUE) library(Matrix, warn.conflicts = FALSE, quietly = TRUE) ## VIASH START @@ -42,24 +41,14 @@ gc() cat("Reading mod2 files\n") X_mod2 <- anndata::read_h5ad(par$input_train_mod2)$layers[["normalized"]] -cat("Predicting for each column in modality 2\n") -preds <- pbapply::pblapply( - seq_len(ncol(X_mod2)), - function(i) { - y <- X_mod2[, i] - uy <- unique(y) - if (length(uy) > 1) { - fit <- RcppArmadillo::fastLm(dr_train, y) - # fit <- lm(y ~ ., dr_train) - stats::predict(fit, dr_test) - } else { - rep(uy, nrow(dr_test)) - } - } +cat("Predicting every column in modality 2 at once\n") +coefficients <- solve( + crossprod(dr_train), + as.matrix(crossprod(dr_train, X_mod2)) ) cat("Creating outputs object\n") -prediction <- Matrix::Matrix(do.call(cbind, preds), sparse = TRUE) +prediction <- Matrix::Matrix(dr_test %*% coefficients, sparse = TRUE) rownames(prediction) <- rownames(dr_test) colnames(prediction) <- colnames(X_mod2) From cd415ed627b55cb3db65d84e9739aff410232d5d Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Fri, 31 Jul 2026 13:44:11 +0200 Subject: [PATCH 2/5] route the predict steps to midgpu de.NBI Berlin has two GPU flavours, both a single T4: `de.NBI GPU T4 medium` (16 vCPU / 64 GB) and `de.NBI GPU T4 large` (32 vCPU / 128 GB). In run 1gVHaBsNbAHcfT these four steps peaked at 1.4-3.5 GB while each occupying a whole large node, and they were 20 of the ~35 jobs queued behind the two T4s. * novel_predict, simple_mlp_predict, ss_opm_predict, babel_predict: gpu -> midgpu The train steps stay on `gpu`: ss_opm_train really does peak at 96 GB. --- src/methods/babel/babel_predict/config.vsh.yaml | 2 +- src/methods/novel/novel_predict/config.vsh.yaml | 2 +- src/methods/simple_mlp/simple_mlp_predict/config.vsh.yaml | 2 +- src/methods/ss_opm/ss_opm_predict/config.vsh.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/methods/babel/babel_predict/config.vsh.yaml b/src/methods/babel/babel_predict/config.vsh.yaml index d989db25..6624f0c8 100644 --- a/src/methods/babel/babel_predict/config.vsh.yaml +++ b/src/methods/babel/babel_predict/config.vsh.yaml @@ -25,4 +25,4 @@ runners: - type: executable - type: nextflow directives: - label: [highmem, hightime, midcpu, gpu] + label: [highmem, hightime, midcpu, midgpu] diff --git a/src/methods/novel/novel_predict/config.vsh.yaml b/src/methods/novel/novel_predict/config.vsh.yaml index e6e80cba..2c79390e 100644 --- a/src/methods/novel/novel_predict/config.vsh.yaml +++ b/src/methods/novel/novel_predict/config.vsh.yaml @@ -22,5 +22,5 @@ runners: - type: executable - type: nextflow directives: - label: [highmem, hightime, midcpu, highsharedmem, gpu] + label: [highmem, hightime, midcpu, highsharedmem, midgpu] diff --git a/src/methods/simple_mlp/simple_mlp_predict/config.vsh.yaml b/src/methods/simple_mlp/simple_mlp_predict/config.vsh.yaml index 4c3dd79d..44e6cb86 100644 --- a/src/methods/simple_mlp/simple_mlp_predict/config.vsh.yaml +++ b/src/methods/simple_mlp/simple_mlp_predict/config.vsh.yaml @@ -25,4 +25,4 @@ runners: - type: executable - type: nextflow directives: - label: [highmem, hightime, midcpu, gpu, highsharedmem] + label: [highmem, hightime, midcpu, midgpu, highsharedmem] diff --git a/src/methods/ss_opm/ss_opm_predict/config.vsh.yaml b/src/methods/ss_opm/ss_opm_predict/config.vsh.yaml index fc07657b..e9224c77 100644 --- a/src/methods/ss_opm/ss_opm_predict/config.vsh.yaml +++ b/src/methods/ss_opm/ss_opm_predict/config.vsh.yaml @@ -39,4 +39,4 @@ runners: - type: executable - type: nextflow directives: - label: [highmem, hightime, midcpu, highsharedmem, gpu] + label: [highmem, hightime, midcpu, highsharedmem, midgpu] From 13fbd88e467a4b5619e62feb834d559e5d6dda4c Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Fri, 31 Jul 2026 13:44:11 +0200 Subject: [PATCH 3/5] correct the memory and cpu labels from the run trace * knnr_py, cellmapper_linear, knnr_r: midmem -> highmem * cellmapper_linear, knnr_r: midcpu -> lowcpu * solution, zeros: midmem -> lowmem knnr_py peaked at 82 GB and cellmapper_linear at 68 GB against their 50 GB request, and both were OOM-killed once in run 1gVHaBsNbAHcfT; knnr_r sits at 45 GB of 50. The other way round, solution uses 0.5 GB and zeros 11 GB of their 50 GB, and knnr_r and cellmapper_linear use 1.4 and 3.8 of 15 cores. --- src/control_methods/solution/config.vsh.yaml | 2 +- src/control_methods/zeros/config.vsh.yaml | 2 +- src/methods/cellmapper_linear/config.vsh.yaml | 2 +- src/methods/knnr_py/config.vsh.yaml | 2 +- src/methods/knnr_r/config.vsh.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/control_methods/solution/config.vsh.yaml b/src/control_methods/solution/config.vsh.yaml index f107ae9d..117b1c02 100644 --- a/src/control_methods/solution/config.vsh.yaml +++ b/src/control_methods/solution/config.vsh.yaml @@ -13,4 +13,4 @@ runners: - type: executable - type: nextflow directives: - label: [midtime, midmem, lowcpu] + label: [midtime, lowmem, lowcpu] diff --git a/src/control_methods/zeros/config.vsh.yaml b/src/control_methods/zeros/config.vsh.yaml index e774b70a..9c82e488 100644 --- a/src/control_methods/zeros/config.vsh.yaml +++ b/src/control_methods/zeros/config.vsh.yaml @@ -13,4 +13,4 @@ runners: - type: executable - type: nextflow directives: - label: [midtime, midmem, lowcpu] + label: [midtime, lowmem, lowcpu] diff --git a/src/methods/cellmapper_linear/config.vsh.yaml b/src/methods/cellmapper_linear/config.vsh.yaml index e824cd85..b6def679 100644 --- a/src/methods/cellmapper_linear/config.vsh.yaml +++ b/src/methods/cellmapper_linear/config.vsh.yaml @@ -71,4 +71,4 @@ runners: - type: executable - type: nextflow directives: - label: [midtime,midmem,midcpu] + label: [midtime, highmem, lowcpu] diff --git a/src/methods/knnr_py/config.vsh.yaml b/src/methods/knnr_py/config.vsh.yaml index 2c87c75f..db59bc7c 100644 --- a/src/methods/knnr_py/config.vsh.yaml +++ b/src/methods/knnr_py/config.vsh.yaml @@ -33,4 +33,4 @@ runners: - type: executable - type: nextflow directives: - label: [hightime, midmem, midcpu] + label: [hightime, highmem, midcpu] diff --git a/src/methods/knnr_r/config.vsh.yaml b/src/methods/knnr_r/config.vsh.yaml index 8a163d93..d8d3d22e 100644 --- a/src/methods/knnr_r/config.vsh.yaml +++ b/src/methods/knnr_r/config.vsh.yaml @@ -36,4 +36,4 @@ runners: - type: executable - type: nextflow directives: - label: [hightime, midmem, midcpu] + label: [hightime, highmem, lowcpu] From 8905457f12cc22ae9ffb012fdf4483a177ad290d Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Fri, 31 Jul 2026 13:44:27 +0200 Subject: [PATCH 4/5] update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9885e92e..0751137d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,14 @@ * `novel_train`: Store only the metadata `novel_predict` needs in the model artifact, instead of a full copy of `train_mod2` (PR #47). +* `lm`: Fit every column of mod2 in one `solve()` of the normal equations instead of calling `RcppArmadillo::fastLm()` once per column. Every column shares the same design matrix, so the old loop redid an `n x n_pcs` decomposition for each of the ~229k ATAC peaks. Predictions are unchanged; `RcppArmadillo` and `pbapply` are no longer needed (PR #58). + +* `novel_predict`, `simple_mlp_predict`, `ss_opm_predict`, `babel_predict`: Ask for `midgpu` rather than `gpu`. All four peak below 4 GB, so they fit the `de.NBI GPU T4 medium` flavour and no longer occupy a whole large node. The train steps stay on `gpu` (PR #58). + +* `knnr_py`, `knnr_r`, `cellmapper_linear`: Ask for `highmem` rather than `midmem`, and `lowcpu` rather than `midcpu` for the latter two. `knnr_py` peaks at 82 GB and `cellmapper_linear` at 68 GB against a 50 GB request, and both were OOM-killed on the larger datasets (PR #58). + +* `solution`, `zeros`: Ask for `lowmem` rather than `midmem` -- they use 0.5 GB and 11 GB of the 50 GB they asked for (PR #58). + ## BUG FIXES * `guanlab_dengkw_pm`: Restore the consensus scheme of the original submission -- five reshuffles of the batches into two halves, ten kernel ridge models averaged. The port had replaced it with a single fixed two-way split for ADT pairs and leave-one-batch-out otherwise, so the result depended on the order the batches happened to come in. `--n_repeats` and `--seed` are now arguments; the unused `--distance_method` and `--n_pcs` are gone (PR #32). From cc75ab6af3c20d79a7b943ce671014c022548de4 Mon Sep 17 00:00:00 2001 From: Robrecht Cannoodt Date: Fri, 31 Jul 2026 13:49:21 +0200 Subject: [PATCH 5/5] update submodule --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index d961b8b1..6eda5dd0 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit d961b8b13a14b5f6b9c75bdc4bde1c5c5faf657f +Subproject commit 6eda5dd0b9c46b43ee36fc379152e079c26f25d3