From 1f08a821049f01b14119160eff489a2202c6a07a Mon Sep 17 00:00:00 2001 From: Jeroen Ooms Date: Sat, 30 May 2026 11:18:54 +0200 Subject: [PATCH 1/3] Also test on Linux ARM in R-CMD-check --- .github/workflows/R-CMD-check.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/R-CMD-check.yml b/.github/workflows/R-CMD-check.yml index 0b747214..366408a8 100644 --- a/.github/workflows/R-CMD-check.yml +++ b/.github/workflows/R-CMD-check.yml @@ -34,6 +34,8 @@ jobs: - {os: ubuntu-latest, r: 'oldrel-1'} - {os: ubuntu-latest, r: 'oldrel-2'} - {os: ubuntu-latest, r: 'oldrel-3'} + + - {os: ubuntu-24.04-arm, r: 'release'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} From 2325784a971319b1ef7b25d1343f8b6c22aff58e Mon Sep 17 00:00:00 2001 From: Joseph Wood Date: Sat, 6 Jun 2026 14:22:38 -0400 Subject: [PATCH 2/3] refactor: simplify core detection fallback logic Rely on `parallel::detectCores()` for physical cores, falling back to logical cores and then `1L` when detection fails. Normalize thread limits to a positive integer with a `1L` fallback. --- R/zzz.R | 62 +++++++++++++-------------------------------------------- 1 file changed, 14 insertions(+), 48 deletions(-) diff --git a/R/zzz.R b/R/zzz.R index 74f36239..c39b64c0 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -5,53 +5,19 @@ pkgEnv$nCores <- NULL pkgEnv$maxThreads <- NULL physicalCoreCount <- function() { + ## Use R's default core-detection path only. This is a conservative + ## package fallback, not an attempt to determine exact CPU topology. + n <- parallel::detectCores(logical = FALSE) - if (grepl("darwin|solaris", R.version$os) || .Platform$OS.type == "windows") - return(parallel::detectCores(logical = FALSE)) - - ## According to R News as of # 3.4.4 - ## "parallel::detectCores(logical = FALSE) is ignored on Linux systems, since - ## the information is not available with virtualized OSes." - ## - ## This implementation tries the old command available from version 3.3.0 until - ## 3.4.3 (It was removed in 3.4.4), as I have had success with this command on - ## several Linux flavors. If this fails, we also try the method outlined - ## by user teambob in an answer to: - ## "How to obtain the number of CPUs/cores in Linux from the command line?" - ## https://stackoverflow.com/a/18051445/4408538 - ## - ## Otherwise, the implementation below is nearly identical to parallel::detectCores - ## with the argument logical set to FALSE. You will note that we have excluded - ## freevsd, openbsd, & irix as they do not have this option available. - - systems <- list(linux = c("cat /proc/cpuinfo | grep 'cpu cores'| uniq | cut -f2 -d:", - "grep '^core id' /proc/cpuinfo |sort -u|wc -l"), - darwin = "/usr/sbin/sysctl -n hw.physicalcpu 2>/dev/null", - solaris = "/bin/kstat -p -m cpu_info | grep :core_id | cut -f2 | uniq | wc -l") - - for (i in seq(systems)) if (grepl(paste0("^", names(systems)[i]), R.version$os)) - for (cmd in systems[i]) { - if (is.null(a <- tryCatch(suppressWarnings( - system(cmd, TRUE)), error = function(e) NULL))) {next} - - a <- gsub("^ +", "", a[1]) - if (grepl("^[1-9]", a)) - return(as.integer(a)) - } - - ## if the above fails, we try all of them - for (i in seq(systems)) - for (cmd in systems[i]) { - if (is.null(a <- tryCatch(suppressWarnings( - system(cmd, TRUE)), error = function(e) NULL))) {next} - - a <- gsub("^ +", "", a[1]) - if (grepl("^[1-9]", a)) - return(as.integer(a)) - } + if (is.na(n) || n < 1L) { + n <- parallel::detectCores(logical = TRUE) + } - ## If we get here, we assume 1 core - 1L + if (is.na(n) || n < 1L) { + 1L + } else { + as.integer(n) + } } ## This will set the maximum number of cores @@ -62,10 +28,10 @@ physicalCoreCount <- function() { pkgEnv$nCores <- physicalCoreCount() tempThreads <- stdThreadMax() - if (is.na(tempThreads)) { - pkgEnv$maxThreads <- 1L + pkgEnv$maxThreads <- if (is.na(tempThreads) || tempThreads < 1L) { + 1L } else { - pkgEnv$maxThreads <- tempThreads + as.integer(tempThreads) } invisible() From 5ca1b595bc9af8eb19bc59af36e46713666863f6 Mon Sep 17 00:00:00 2001 From: Joseph Wood Date: Sat, 6 Jun 2026 14:47:55 -0400 Subject: [PATCH 3/3] refactor: simplify thread count fallback and integer coercion Reorder null/NA/invalid checks in `stdThreadMax()` and return an explicit integer. Clarify `physicalCoreCount()` comments around fallback behavior. --- R/Utility.R | 8 ++++++-- R/zzz.R | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/R/Utility.R b/R/Utility.R index 102e7ecd..ec92ce02 100644 --- a/R/Utility.R +++ b/R/Utility.R @@ -1,7 +1,11 @@ stdThreadMax <- function() { nThreads <- .Call(`_RcppAlgos_cpp11GetNumThreads`) - if (nThreads < 1L || is.na(nThreads) || is.null(nThreads)) nThreads = 1L - return(nThreads) + + if (is.null(nThreads) || is.na(nThreads) || nThreads < 1L) { + nThreads <- 1L + } + + as.integer(nThreads) } GetV <- function(v) { diff --git a/R/zzz.R b/R/zzz.R index c39b64c0..1cf1b8af 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -5,8 +5,10 @@ pkgEnv$nCores <- NULL pkgEnv$maxThreads <- NULL physicalCoreCount <- function() { - ## Use R's default core-detection path only. This is a conservative - ## package fallback, not an attempt to determine exact CPU topology. + ## Estimate physical cores using R's default detection path. This value is + ## used for cache-size heuristics, not as the authoritative thread limit. + ## If physical core detection is unavailable, fall back to logical cores + ## and finally to 1. n <- parallel::detectCores(logical = FALSE) if (is.na(n) || n < 1L) {