使用parallel函数时R CRAN检查失败的问题求助
detectCores() The Problem
You're trying to submit an R package to CRAN that uses parallel::makeCluster(parallel::detectCores()) for parallel computation. Local builds work fine, but devtools::check(document = FALSE) throws an error:
Running examples in ‘TESTER-Ex.R’ failed The error most likely occurred in: > base::assign(".ptime", proc.time(), pos = "CheckExEnv") > ### Name: hello_world > ### Title: Prints hello world > ### Aliases: hello_world > > ### ** Examples > > hello_world() Error in .check_ncores(length(names)) : 8 simultaneous processes spawned Calls: hello_world -> <Anonymous> -> makePSOCKcluster -> .check_ncores Execution halted
You reproduced this with a minimal package containing just the hello_world function:
#' Prints hello world #' #' @return nothing #' @export #' #' @examples #' hello_world() hello_world <- function() { # initiate cluster cl <- parallel::makeCluster(parallel::detectCores()) # stop cluster parallel::stopCluster(cl) cat("Hello World\n") return(invisible(NULL)) }
Why This Happens
This is a resource restriction enforced by CRAN's check servers. CRAN sets the environment variable _R_CHECK_LIMIT_CORES_ to limit the number of parallel processes packages can spawn (usually to 2 cores) — this prevents packages from hogging shared server resources.
When you call parallel::detectCores(), it returns the total number of cores available on the machine (in your error case, 8). This exceeds the CRAN-imposed limit, triggering the .check_ncores() validation inside makePSOCKcluster() which throws the error.
Your local environment doesn't have this restriction, which is why everything works fine locally but fails during CRAN checks.
How to Fix It
Adjust your code to respect the CRAN core limit when it's set, and fall back to a reasonable default otherwise. Here's how to modify your hello_world function:
#' Prints hello world #' #' @return nothing #' @export #' #' @examples #' hello_world() hello_world <- function() { # Determine safe number of cores to use n_cores <- if (Sys.getenv("_R_CHECK_LIMIT_CORES_") != "") { # Use CRAN's allowed core count if set as.integer(Sys.getenv("_R_CHECK_LIMIT_CORES_")) } else { # Fall back to physical cores (or 2 if detection fails) nc <- parallel::detectCores(logical = FALSE) if (is.null(nc)) 2 else nc } # Initiate cluster with the safe core count cl <- parallel::makeCluster(n_cores) # Stop cluster parallel::stopCluster(cl) cat("Hello World\n") return(invisible(NULL)) }
Key Notes:
- We check for the
_R_CHECK_LIMIT_CORES_environment variable first — this ensures we comply with CRAN's rules during checks. - Using
detectCores(logical = FALSE)gives us physical cores instead of logical (hyper-threaded) cores, which is often more appropriate for parallel work. - We add a fallback to 2 cores if core detection fails (rare, but handles edge cases).
Alternatively, if your parallel code isn't critical to demonstrate in the example, you could wrap the parallel logic in \dontrun{} or \donttest{} in your roxygen comments. But the core-count adjustment is the better long-term solution, as it keeps your example runnable while respecting CRAN's constraints.
内容的提问来源于stack exchange,提问作者David

