
最近在整理与我自己的代码库,然后练习函数式编程。由于很早就使用Rproject的方式进行各个项目的处理与管理,在测试使用source()+指定新环境导入包含函数的R脚本后,一天内就又转换到使用Rstudio创建Rpackage devtool的R环境的方式。同时我是在我的R项目内嵌套该R包,因此项目中所有引用的函数,我可以通过ctrl+左键双击的方式,直接打开对应的R脚本文件(我搜索了一下,似乎没有任何人报告这种Rstudio中对相关文件的打开方式),便于修订与更改。
AI给的提示信息

在了解相关架构后,也是修订代码遇到的问题,就是NMF包。我不知道有多少人遇到这个问题,其在28版本的核心数量,是无论你设置什么都被强制改为2,非常恶心。很多人的做法是强制回退到25版本,但是有时候R包更新,又强制依赖更新回去,这个来来回回总不是个事。因此今天我把28的源码下载下来,然后查看了github上的20源码,也强制更新了25版本,也看了一下源码。用AI判断了一下,28版本就是强制锁定所有的核心都是2,无论你在设置全局变量'cores'的数值,还是每一个调用时设置的nmf.getOption('cores'),全部都被强制修改为2,所以无论怎么修改都是这样子。
不知道26版本开始,经过了谁的手,恶意非常重,因为他不仅仅修改了getMaxCores 函数,还修改了 setupBackend,getmaxcores修改如下所有,然后对于setupbackend,就是直接修改参数即可。 在文档中找到 if( spec > 2L ),你会看到他甚至注释了Limit number of cores to 2,真的该死呦。我是将对应的数值直接替换为了 getMaxCores(limit=T),测试后我的电脑能够跑满CPU。之前只是修改了getmaxcores,没想到还要修改setupBackend。
他还直接加了相应代码,对比图如下,真不知道他遭遇了什么,这么恨。。。。

以下是这getmaxcores几个版本的源码以及我自己的测试
```bash 28版本
getAnywhere(getMaxCores)
A single object matching ‘getMaxCores’ was found
It was found in the following places
namespace:NMF
with value
function (limit = TRUE)
{
nt <- n <- parallel::detectCores()
if (n > 2)
n <- 2
if (n > 2 && isCHECK()) {
message("# NOTE - CRAN check detected: limiting maximum number of cores [2/",
nt, "]")
n <- 2L
}
n
}
<bytecode: 0x000001ee17366130>
<environment: namespace:NMF>
> parallel::detectCores()
[1] 32
```
25版本
```bash
library(NMF)
NMF - BioConductor layer [OK] | Shared memory capabilities [NO: windows] | Cores 31/32
Attaching package: ‘NMF’
The following object is masked from ‘package:generics’:
fit
getAnywhere(getMaxCores)
A single object matching ‘getMaxCores’ was found
It was found in the following places
namespace:NMF
with value
function (limit = TRUE)
{
nt <- n <- parallel::detectCores()
if (limit) {
if (!is.null(nc <- getOption("cores")))
n <- nc
else if (!is.null(nc <- nmf.getOption("cores")))
n <- nc
else if (n > 2)
n <- n - 1L
}
if (n > 2 && isCHECK()) {
message("# NOTE - CRAN check detected: limiting maximum number of cores [2/",
nt, "]")
n <- 2L
}
n
}
<bytecode: 0x000001ee1fef5080>
<environment: namespace:NMF>
```
以下是我用AI进行修改的代码,
```bash
#' 智能核心数管理函数(增强版)
#'
#' @param limit 是否应用限制逻辑(默认TRUE)
#' @return 推荐的可用核心数
getMaxCores <- function(limit = TRUE) {
# 获取系统总核心数
nt <- n <- parallel::detectCores()
message("检测到系统总核心数: ", nt)
# 记录初始核心数
initial_n <- n
# 仅在需要限制时应用智能策略
if (limit) {
message("应用核心数限制策略...")
# 1. 优先检查全局选项
if (!is.null(nc <- getOption('cores'))) {
message("→ 使用全局选项 'cores' 设置: ", nc, " 核心")
n <- nc
}
# 2. 检查NMF专用选项
else if (!is.null(nc <- nmf.getOption('cores'))) {
message("→ 使用NMF专用选项 'cores' 设置: ", nc, " 核心")
n <- nc
}
# 3. 默认策略:保留一个空闲核心
else if (n > 2) {
message("→ 应用默认策略: 保留1个空闲核心 (", n, " → ", n-1, ")")
n <- n - 1L
}
else {
message("→ 未应用额外限制 (核心数 ≤ 2)")
}
}
else {
message("未应用任何限制策略 (limit = FALSE)")
}
# CRAN检查处理
cran_check <- identical(Sys.getenv("_R_CHECK_LIMIT_CORES_"), "true")
if (cran_check) {
message("检测到CRAN检查环境 (_R_CHECK_LIMIT_CORES_ = true)")
}
# 应用CRAN限制
if (n > 2 && cran_check) {
message("→ CRAN限制生效: 最大核心数限制为2 (当前: ", n, " → 2)")
n <- 2L
}
# 输出最终结果
if (initial_n != n) {
message("最终核心数: ", n, " (初始: ", initial_n, ", 总核心: ", nt, ")")
} else {
message("最终核心数: ", n, " (未改变)")
}
return(n)
}
```

文件路径是NMF,R,parallel.R,getMaxCores,如果不想麻烦,可以直接用25版本的源码替换,然后再添加回压缩文件,最后使用压缩包的方式进行安装。MD5检测肯定不会过,如果太在意就不要改了,可以去尝试用25版本的parallel.R替换,然后复制对应的MD5码。
修复完成后的调用
