众所周知,基础R使用BLAS进行计算加速。在我的代码中,我想使用基本R中的那些函数,并且可能是它使用BLAS的包。如何获得完全使用BLAS的R函数列表?或者我如何检查我想在我的代码中使用的函数是否使用BLAS(ATLAS,LAPACK等)?
答案 0 :(得分:0)
这不是一个完整的答案,因为我不是这方面的专家。但是,也许你或其他人可以采取一些这些开始的想法,并从中创建一个解决方案(如果你可以发布那么会很棒!)
只有调用C代码的函数才能使用BLAS。因此,找出这些功能可能是第一步。
capture.output(print( FUN ))
为函数定义了一个字符串向量(每行一个元素)所以列出所有按.Internal
,.Primitive
等定义的函数。以下内容:
# Set this to the package you want to screen
envName <- 'base'
# Get the environment for the given name
env <- pos.to.env(which(search() == paste0('package:',envName)))
# Return TRUE if `string` contains `what`
contains <- function(string, what){
length(grep(what, string, fixed = TRUE)) != 0
}
# Build up a matrix which contains true if an element is defined in terms
# of the following functions which indicate calls to C code
signalWords <- c( '.Primitive', '.Internal', '.External'
, '.Call' , '.C' , '.Fortran' )
envElements <- ls(envir = env)
funTraits <- matrix(FALSE, nrow = length(envElements), ncol = length(signalWords),
dimnames = list(envElements, signalWords))
# Fill up the values of the matrix by reading each elements' definition
for (elementName in envElements){
element <- get(elementName, envir = env)
if(!is.function(element)){
next
}
fun.definition <- capture.output(print(element))
for(s in signalWords){
if(contains(fun.definition, s)){
funTraits[elementName, s] <- TRUE
}
}
}
当函数调用外部C函数(而不是.Primitive
函数)时,它看起来像这样:
dnorm
## function (x, mean = 0, sd = 1, log = FALSE)
## .External(C_dnorm, x, mean, sd, log)
## <bytecode: 0x1b1eebfc>
## <environment: namespace:stats>
然后追捕.External
调用的对象。它具有相应C函数的名称。使用PACKAGE:::OBJECT$name
查找:
stats:::C_dnorm$name
## [1] "dnorm"
进一步了解:How can I view the source code for a function?,它还提供了有关在何处查找已编译函数的源代码的信息,以及How to see the source code of R .Internal or .Primitive function?
最后,您必须以某种方式筛选C代码及其为BLAS例程调用的所有函数...
您可以开发一个具有BLAS名称的DLL,但只需记录其使用情况,并在将调用转发给真正的BLAS例程之前从其中调用它... LD_PRELOAD
UNIX环境变量可以用于加载此库而不是BLAS。这仅在编译R以将BLAS加载为动态链接库时才有效。
https://blog.netspi.com/function-hooking-part-i-hooking-shared-library-function-calls-in-linux/
另请参阅:Why can R be linked to a shared BLAS later even if it was built with `--with-blas = lblas`?