Bioconductor / basilisk.utils

Clone of the Bioconductor repository for the basilisk.utils package.
https://bioconductor.org/packages/devel/bioc/html/basilisk.utils.html
GNU General Public License v3.0
1 stars 5 forks source link

Fallback/conda version of R missing 'nameOfClass' object #8

Closed csoneson closed 1 year ago

csoneson commented 1 year ago

Hi @LTLA - we're running into an issue with the fallback mechanism implemented in basilisk.utils (which otherwise has been extremely helpful for us).

We believe the issue stems from the R version that is installed in the fallback conda environment (4.2.3, imposed by the hard-coded reticulate version 1.26) being too old, and thus missing the nameOfClass() object in the base namespace (which was introduced in R 4.3.0, and the S3 method for python types was added in reticulate 1.29). The error we see is the same as described in this issue (our main R version is 4.3.1, so there it's all good - the error only appears when the fallback is activated).

Not sure what the best solution is - perhaps to update the pinned version of r-reticulate to 1.30, or maybe one could check whether reticulate is available in the R library when the fallback environment is created, and install that version if possible. What do you think?

Small reproducible example:

envp <- file.path(tempdir(), "tf-env")
basilisk::setupBasiliskEnv(
    envpath = envp, 
    packages = "tensorflow==2.10"
)
cl <- basiliskStart(envp, testload = "tensorflow")

gives (after activating the fallback):

Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  one node produced an error: object 'nameOfClass' not found whilst loading namespace 'reticulate'

Thanks in advance, Charlotte

LTLA commented 1 year ago

Not sure exactly where the problem comes from. If the fallback is invoked, it should be using its own (old) version of reticulate. The error suggests that a new version of reticulate is being mixed in with the old fallback R version, but I don't see where this could happen. Need to catch the 🚌 now...

LTLA commented 1 year ago

Your example works fine for me on my work machine when I force the fallback to be triggered.

Can you debug() and figure out exactly what breaks?

csoneson commented 1 year ago

Thanks for looking into this. We have made some further troubleshooting and it seems to come down to having either R_LIBS_SITE or R_LIBS_USER set - in either of these cases, basilisk would find the wrong version of reticulate (i.e., the one from the site/user library) when attempting to attach the namespace here. There may be multiple ways of solving it - one thing that worked for us was to add an additional line that would first load the namespace (as loadNamespace() has a lib.loc argument, which could be set to the library subdirectory of R.home(), which is correctly identified in the fallback process) before attaching it. E.g., replacing the current line with something like

hm <- clusterCall(proc, R.home)
clusterCall(proc, loadNamespace, package = "reticulate", lib.loc = file.path(hm[[1]], "library"))
clusterCall(proc, attachNamespace, ns = "reticulate")
LTLA commented 1 year ago

Can you make a PR with that fix? I would also suggest seeing if we can bundle these commands together to reduce the amount of clusterCall()s we have to make. For example, would something like this work:

clusterCall(proc, function() {
    library("reticulate", character.only=TRUE, lib.loc = file.path(R.home(), "library"))
})

This should be executed in the fallback context, so R.home() should point to the right place. I think.

csoneson commented 1 year ago

PR opened - I tested your suggestion above and it works well.

LTLA commented 1 year ago

It is done, pushed on release and devel.