leiden icon indicating copy to clipboard operation
leiden copied to clipboard

Package installation segfault error on CentOS

Open ayushnoori opened this issue 1 year ago • 6 comments

Hi there, I'm attempting to install leiden on CentOS 7.9.2009 and have encountered the following installation error. Would appreciate any assistance. Thanks!

> install.packages("leiden")
Installing package into ‘/home/an252/R-4.2.1/library’
(as ‘lib’ is unspecified)
trying URL 'https://mirrors.nics.utk.edu/cran/src/contrib/leiden_0.4.3.tar.gz'
Content type 'application/x-gzip' length 3246718 bytes (3.1 MB)
==================================================
downloaded 3.1 MB

* installing *source* package ‘leiden’ ...
** package ‘leiden’ successfully unpacked and MD5 sums checked
** using staged installation
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
sh: line 1: 15516 Segmentation fault      R_TESTS= '/n/app/R/4.2.1-gcc-9.2.0/lib64/R/bin/R' --no-save --no-restore --no-echo 2>&1 < '/tmp/Rtmpz2zILL/file3c7f4ff851a1'

 *** caught segfault ***
address 0x90, cause 'memory not mapped'

Traceback:
 1: py_initialize(config$python, config$libpython, config$pythonhome,     config$virtualenv_activate, config$version >= "3.0", interactive(),     numpy_load_error)
 2: (function() {    Sys.setenv(PYTHONPATH = newpythonpath)    on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)    py_initialize(config$python, config$libpython, config$pythonhome,         config$virtualenv_activate, config$version >= "3.0",         interactive(), numpy_load_error)})()
 3: doTryCatch(return(expr), name, parentenv, handler)
 4: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 5: tryCatchList(expr, classes, parentenv, handlers)
 6: tryCatch({    oldpythonpath <- Sys.getenv("PYTHONPATH")    newpythonpath <- Sys.getenv("RETICULATE_PYTHONPATH", unset = paste(config$pythonpath,         system.file("python", package = "reticulate"), sep = .Platform$path.sep))    local({        Sys.setenv(PYTHONPATH = newpythonpath)        on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)        py_initialize(config$python, config$libpython, config$pythonhome,             config$virtualenv_activate, config$version >= "3.0",             interactive(), numpy_load_error)    })}, error = function(e) {    Sys.setenv(PATH = oldpath)    if (is.na(curr_session_env)) {        Sys.unsetenv("R_SESSION_INITIALIZED")    }    else {        Sys.setenv(R_SESSION_INITIALIZED = curr_session_env)    }    stop(e)})
 7: initialize_python(required_module, use_environment)
 8: ensure_python_initialized(required_module = module)
 9: import(module)
10: doTryCatch(return(expr), name, parentenv, handler)
11: tryCatchOne(expr, names, parentenv, handlers[[1L]])
12: tryCatchList(expr, classes, parentenv, handlers)
13: tryCatch({    import(module)    TRUE}, error = clear_error_handler(FALSE))
14: reticulate::py_module_available("pandas")
15: fun(libname, pkgname)
16: doTryCatch(return(expr), name, parentenv, handler)
17: tryCatchOne(expr, names, parentenv, handlers[[1L]])
18: tryCatchList(expr, classes, parentenv, handlers)
19: tryCatch(fun(libname, pkgname), error = identity)
20: runHook(".onAttach", ns, dirname(nspath), nsname)
21: attachNamespace(ns, pos = pos, deps, exclude, include.only)
22: doTryCatch(return(expr), name, parentenv, handler)
23: tryCatchOne(expr, names, parentenv, handlers[[1L]])
24: tryCatchList(expr, classes, parentenv, handlers)
25: tryCatch({    attr(package, "LibPath") <- which.lib.loc    ns <- loadNamespace(package, lib.loc)    env <- attachNamespace(ns, pos = pos, deps, exclude, include.only)}, error = function(e) {    P <- if (!is.null(cc <- conditionCall(e)))         paste(" in", deparse(cc)[1L])    else ""    msg <- gettextf("package or namespace load failed for %s%s:\n %s",         sQuote(package), P, conditionMessage(e))    if (logical.return && !quietly)         message(paste("Error:", msg), domain = NA)    else stop(msg, call. = FALSE, domain = NA)})
26: library(pkg_name, lib.loc = lib, character.only = TRUE, logical.return = TRUE)
27: withCallingHandlers(expr, packageStartupMessage = function(c) tryInvokeRestart("muffleMessage"))
28: suppressPackageStartupMessages(library(pkg_name, lib.loc = lib,     character.only = TRUE, logical.return = TRUE))
29: doTryCatch(return(expr), name, parentenv, handler)
30: tryCatchOne(expr, names, parentenv, handlers[[1L]])
31: tryCatchList(expr, classes, parentenv, handlers)
32: tryCatch(expr, error = function(e) {    call <- conditionCall(e)    if (!is.null(call)) {        if (identical(call[[1L]], quote(doTryCatch)))             call <- sys.call(-4L)        dcall <- deparse(call, nlines = 1L)        prefix <- paste("Error in", dcall, ": ")        LONG <- 75L        sm <- strsplit(conditionMessage(e), "\n")[[1L]]        w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],                 type = "b")        if (w > LONG)             prefix <- paste0(prefix, "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix, conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if (!silent && isTRUE(getOption("show.error.messages"))) {        cat(msg, file = outFile)        .Internal(printDeferredWarnings())    }    invisible(structure(msg, class = "try-error", condition = e))})
33: try(suppressPackageStartupMessages(library(pkg_name, lib.loc = lib,     character.only = TRUE, logical.return = TRUE)))
34: tools:::.test_load_package("leiden", "/home/an252/R-4.2.1/library/00LOCK-leiden/00new")
An irrecoverable exception occurred. R is aborting now ...
ERROR: loading failed
* removing ‘/home/an252/R-4.2.1/library/leiden’

The downloaded source packages are in
	‘/tmp/Rtmp6ZFOiM/downloaded_packages’
Warning message:
In install.packages("leiden") :
  installation of package ‘leiden’ had non-zero exit status
> 

ayushnoori avatar Jun 20 '23 03:06 ayushnoori

We are observing this same error on the R 4.3 migration over on Conda Forge. For us, R 4.2.3 works just fine. This issue only arises with R 4.3.0 build during the test phase.

R version 4.3.0 (2023-04-21) -- "Already Tomorrow"
Copyright (C) 2023 The R Foundation for Statistical Computing
Platform: x86_64-conda-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library('leiden')
create conda environment (yes/no)?
no (use interactive mode)
using environment: NA
Unable to set up conda environment r-reticulate
run in terminal:
conda init
conda create -n r-reticulate
conda environment r-reticulate installed
python modules igraph and leidenalg installed

 *** caught segfault ***
address 0xfffffffffffff020, cause 'memory not mapped'

Traceback:
 1: py_initialize(config$python, config$libpython, config$pythonhome,     config$virtualenv_activate, config$version >= "3.0", interactive(),     numpy_load_error)
 2: (function() {    Sys.setenv(PYTHONPATH = newpythonpath)    on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)    py_initialize(config$python, config$libpython, config$pythonhome,         config$virtualenv_activate, config$version >= "3.0",         interactive(), numpy_load_error)})()
 3: doTryCatch(return(expr), name, parentenv, handler)
 4: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 5: tryCatchList(expr, classes, parentenv, handlers)
 6: tryCatch({    oldpythonpath <- Sys.getenv("PYTHONPATH")    newpythonpath <- Sys.getenv("RETICULATE_PYTHONPATH", unset = paste(config$pythonpath,         system.file("python", package = "reticulate"), sep = .Platform$path.sep))    local({        Sys.setenv(PYTHONPATH = newpythonpath)        on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)        py_initialize(config$python, config$libpython, config$pythonhome,             config$virtualenv_activate, config$version >= "3.0",             interactive(), numpy_load_error)    })}, error = function(e) {    Sys.setenv(PATH = oldpath)    if (is.na(curr_session_env)) {        Sys.unsetenv("R_SESSION_INITIALIZED")    }    else {        Sys.setenv(R_SESSION_INITIALIZED = curr_session_env)    }    stop(e)})
 7: initialize_python(required_module, use_environment)
 8: ensure_python_initialized(required_module = module)
 9: import(module)
10: doTryCatch(return(expr), name, parentenv, handler)
11: tryCatchOne(expr, names, parentenv, handlers[[1L]])
12: tryCatchList(expr, classes, parentenv, handlers)
13: tryCatch({    import(module)    TRUE}, error = clear_error_handler(FALSE))
14: reticulate::py_module_available("leidenalg")
15: fun(libname, pkgname)
16: doTryCatch(return(expr), name, parentenv, handler)
17: tryCatchOne(expr, names, parentenv, handlers[[1L]])
18: tryCatchList(expr, classes, parentenv, handlers)
19: tryCatch(fun(libname, pkgname), error = identity)
20: runHook(".onAttach", ns, dirname(nspath), nsname)
21: attachNamespace(ns, pos = pos, deps, exclude, include.only)
22: doTryCatch(return(expr), name, parentenv, handler)
23: tryCatchOne(expr, names, parentenv, handlers[[1L]])
24: tryCatchList(expr, classes, parentenv, handlers)
25: tryCatch({    attr(package, "LibPath") <- which.lib.loc    ns <- loadNamespace(package, lib.loc)    env <- attachNamespace(ns, pos = pos, deps, exclude, include.only)}, error = function(e) {    P <- if (!is.null(cc <- conditionCall(e)))         paste(" in", deparse(cc)[1L])    else ""    msg <- gettextf("package or namespace load failed for %s%s:\n %s",         sQuote(package), P, conditionMessage(e))    if (logical.return && !quietly)         message(paste("Error:", msg), domain = NA)    else stop(msg, call. = FALSE, domain = NA)})
26: library("leiden")
An irrecoverable exception occurred. R is aborting now ...
/home/conda/feedstock_root/build_artifacts/r-leiden_1687307043630/test_tmp/run_test.sh: line 7:   544 Segmentation fault      (core dumped) $R -e "library('leiden')"
Tests failed for r-leiden-0.4.3-r43hc72bb7e_2.conda - moving package to /home/conda/feedstock_root/build_artifacts/broken
WARNING:conda_build.build:Tests failed for r-leiden-0.4.3-r43hc72bb7e_2.conda - moving package to /home/conda/feedstock_root/build_artifacts/broken
TESTS FAILED: r-leiden-0.4.3-r43hc72bb7e_2.conda

The Conda Forge build runs on the Docker image:

quay.io/condaforge/linux-anvil-cos7-x86_64

which corresponds to the identical CentOS 7.9.2009 as OP.

mfansler avatar Jun 21 '23 01:06 mfansler

Possibly a reticulate problem. Our R 4.2 build is using reticulate v1.26 (and works), but on R 4.3 it uses v1.30. Note that v1.26 is being used is odd in itself - our default expectation is the latest build should always get picked up in testing. For R 4.3, we only have the v1.30 available.

@ayushnoori could be helpful to report your reticulate version and possibly try downgrading to an older version.

mfansler avatar Jun 21 '23 01:06 mfansler

Also, given the output we see on Conda Forge, I'd guess the failure happens here:

https://github.com/TomKellyGenetics/leiden/blob/2a2045b31f1cdd8469b283c8e39d9f8dccaa1436/R/leiden.R#L604


Edit: Actually, just noticed the traceback shows exactly the failure point. For OP, it is the above line, but for us that works and instead we fail the next test (reticulate::py_module_available("leidenalg")). Weird...

mfansler avatar Jun 21 '23 02:06 mfansler

Fortunately, the issue seems to be resolved on my end. Unfortunately, I'm not quite sure why or how.

I attempted to install Seurat and leiden (which I was installing since it is a dependency of Seurat) from source via RStudio on a new compute node (still R version 4.2.1, and still same virtual environment), and the installation proceeded uneventfully.

Here's my sessionInfo for your reference:

R version 4.2.1 (2022-06-23)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

Matrix products: default
BLAS/LAPACK: /n/app/openblas/0.3.19-gcc-9.2.0/lib/libopenblas_haswellp-r0.3.19.so

other attached packages:
[1] reticulate_1.30         leiden_0.4.3            SeuratObject_4.9.9.9085 Seurat_4.3.0

For now, I'm thrilled that the installation worked. I'll leave this issue open, though, since it seems the underlying problem may not be resolved. Time permitting, I can try and reproduce separately.

ayushnoori avatar Jun 21 '23 02:06 ayushnoori

Workaround

Was able to get things working by pre-creating an r-reticulate environment:

mamba create -yn r-reticulate -c conda-forge pandas leidenalg umap-learn

This effectively gets around the section(s) of problematic code (though perhaps kicking the can down the road for end users).

Recommendation

I would recommend the .onAttach code be updated to be more robust for non-interactive library loading testing. Specifically, I think the reticulate::py_module_available function is not as reliable to error catching as it once was (perhaps an issue for upstream?).

If you will suffer my unsolicited opinion, I regard the strategy of installing the Python packages that this requires into r-reticulate or base as having room for improvement. Namely, it would be more reliable to provide a dedicated (isolated) environment only for this package's requirements. I haven't seen this before, but the tools::R_user_dir seems highly appropriate for this as the environment could be unique and use a prefix instead of relying on a named (user-visible) environment. Maybe have a look at the "Persistent user data" section of the R Packages (2e) book.

mfansler avatar Jun 21 '23 04:06 mfansler

For the record we face the same problem at Bioconductor 3.19 on Linux ARM64 - https://bioconductor.org/checkResults/3.19/bioc-LATEST/APL/kunpeng2-install.html

 Installing package into '/home/biocbuild/R/R-4.4-devel-2023.11.02/site-library'
(as 'lib' is unspecified)
trying URL 'https://cran.rstudio.com/src/contrib/leiden_0.4.3.tar.gz'
Content type 'application/x-gzip' length 3246718 bytes (3.1 MB)
==================================================
downloaded 3.1 MB

* installing *source* package 'leiden' ...
** package 'leiden' successfully unpacked and MD5 sums checked
** using staged installation
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location

 *** caught segfault ***
address 0x90, cause 'memory not mapped'

Traceback:
 1: py_initialize(config$python, config$libpython, config$pythonhome,     config$virtualenv_activate, config$version >= "3.0", interactive(),     numpy_load_error)
 2: (function() {    Sys.setenv(PYTHONPATH = newpythonpath)    on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)    py_initialize(config$python, config$libpython, config$pythonhome,         config$virtualenv_activate, config$version >= "3.0",         interactive(), numpy_load_error)})()
 3: doTryCatch(return(expr), name, parentenv, handler)
 4: tryCatchOne(expr, names, parentenv, handlers[[1L]])
 5: tryCatchList(expr, classes, parentenv, handlers)
 6: tryCatch({    oldpythonpath <- Sys.getenv("PYTHONPATH")    newpythonpath <- Sys.getenv("RETICULATE_PYTHONPATH", unset = paste(config$pythonpath,         system.file("python", package = "reticulate"), sep = .Platform$path.sep))    local({        Sys.setenv(PYTHONPATH = newpythonpath)        on.exit(Sys.setenv(PYTHONPATH = oldpythonpath), add = TRUE)        py_initialize(config$python, config$libpython, config$pythonhome,             config$virtualenv_activate, config$version >= "3.0",             interactive(), numpy_load_error)    })}, error = function(e) {    Sys.setenv(PATH = oldpath)    if (is.na(curr_session_env)) {        Sys.unsetenv("R_SESSION_INITIALIZED")    }    else {        Sys.setenv(R_SESSION_INITIALIZED = curr_session_env)    }    stop(e)})
 7: initialize_python()
 8: ensure_python_initialized(required_module = module)
 9: import(module)
10: doTryCatch(return(expr), name, parentenv, handler)
11: tryCatchOne(expr, names, parentenv, handlers[[1L]])
12: tryCatchList(expr, classes, parentenv, handlers)
13: tryCatch({    import(module)    TRUE}, error = clear_error_handler(FALSE))
14: reticulate::py_module_available("pandas")
15: fun(libname, pkgname)
16: doTryCatch(return(expr), name, parentenv, handler)
17: tryCatchOne(expr, names, parentenv, handlers[[1L]])
18: tryCatchList(expr, classes, parentenv, handlers)
19: tryCatch(fun(libname, pkgname), error = identity)
20: runHook(".onAttach", ns, dirname(nspath), nsname)
21: attachNamespace(ns, pos = pos, deps, exclude, include.only)
22: doTryCatch(return(expr), name, parentenv, handler)
23: tryCatchOne(expr, names, parentenv, handlers[[1L]])
24: tryCatchList(expr, classes, parentenv, handlers)
25: tryCatch({    attr(package, "LibPath") <- which.lib.loc    ns <- loadNamespace(package, lib.loc)    env <- attachNamespace(ns, pos = pos, deps, exclude, include.only)}, error = function(e) {    P <- if (!is.null(cc <- conditionCall(e)))         paste(" in", deparse(cc)[1L])    else ""    msg <- gettextf("package or namespace load failed for %s%s:\n %s",         sQuote(package), P, conditionMessage(e))    if (logical.return && !quietly)         message(paste("Error:", msg), domain = NA)    else stop(msg, call. = FALSE, domain = NA)})
26: library(pkg_name, lib.loc = lib, character.only = TRUE, logical.return = TRUE)
27: withCallingHandlers(expr, packageStartupMessage = function(c) tryInvokeRestart("muffleMessage"))
28: suppressPackageStartupMessages(library(pkg_name, lib.loc = lib,     character.only = TRUE, logical.return = TRUE))
29: doTryCatch(return(expr), name, parentenv, handler)
30: tryCatchOne(expr, names, parentenv, handlers[[1L]])
31: tryCatchList(expr, classes, parentenv, handlers)
32: tryCatch(expr, error = function(e) {    call <- conditionCall(e)    if (!is.null(call)) {        if (identical(call[[1L]], quote(doTryCatch)))             call <- sys.call(-4L)        dcall <- deparse(call, nlines = 1L)        prefix <- paste("Error in", dcall, ": ")        LONG <- 75L        sm <- strsplit(conditionMessage(e), "\n")[[1L]]        w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w")        if (is.na(w))             w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L],                 type = "b")        if (w > LONG)             prefix <- paste0(prefix, "\n  ")    }    else prefix <- "Error : "    msg <- paste0(prefix, conditionMessage(e), "\n")    .Internal(seterrmessage(msg[1L]))    if (!silent && isTRUE(getOption("show.error.messages"))) {        cat(msg, file = outFile)        .Internal(printDeferredWarnings())    }    invisible(structure(msg, class = "try-error", condition = e))})
33: try(suppressPackageStartupMessages(library(pkg_name, lib.loc = lib,     character.only = TRUE, logical.return = TRUE)))
34: tools:::.test_load_package("leiden", "/home/biocbuild/R/R-4.4-devel-2023.11.02/site-library/00LOCK-leiden/00new")
An irrecoverable exception occurred. R is aborting now ...
ERROR: loading failed
* removing '/home/biocbuild/R/R-4.4-devel-2023.11.02/site-library/leiden'

The downloaded source packages are in
	'/home/biocbuild/tmp/Rtmpo60CDx/downloaded_packages'
Warning message:
In install.packages(pkg, repos = .NON_TARGET_REPOS, dependencies = FALSE,  :
  installation of package 'leiden' had non-zero exit status

martin-g avatar Nov 13 '23 10:11 martin-g