我有一个执行各种操作的现有 R 脚本,我希望创建一个 C 子函数来优化它的特定部分。我的目标是将这个 C 子函数集成到 R Desktop 中,以提高性能和效率。
例如,假设我想对向量 x 和 y 相乘获得的元素求和。在 R 中,我可以使用以下代码实现此目的:
R 代码
x <- c(1, 2, 3)
y <- c(4, 5, 6)
z <- sum(x * y)
使用 oneMKL 可以执行相同的操作,如下所示:
#include <stdio.h>
#include <mkl.h>
int main() {
double x[] = {1.0, 2.0, 3.0};
double y[] = {4.0, 5.0, 6.0};
double z;
// Perform vector multiplication and summation using Intel MKL
z = cblas_ddot(3, x, 1, y, 1);
printf("Result: %lf\n", z);
return 0;
}
使用 CMD 编译 .c 函数后,我得到:
C:\Program Files (x86)\Intel\oneAPI>cd C:/Users/Administrator/Desktop
C:\Users\Administrator\Desktop>icx -o example example.c /Qmkl /MD
Intel(R) oneAPI DPC++/C++ Compiler for applications running on Intel(R) 64, Version 2023.1.0 Build 20230320
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\Users\Administrator\Desktop>example.exe
Result: 32.000000
我想要做的是将 Rscript 代码的第 4 行替换为 .c 函数。我面临两个问题:
<强>1。将 C 函数转换为通用输入:
我不知道我是否正确定义了该函数。
#include <stdio.h>
#include <mkl.h>
void multiplyAndSum(double *x, double *y, int length, double *result) {
*result = cblas_ddot(length, x, 1, y, 1);
}
<强>2。在R中调用C函数:
我不知道如何在 R 中调用步骤 1 中的 .c 函数。有没有办法编译该函数并在 R Desktop 中显式运行它,而不使用命令提示符 (cmd)
拜托,我知道我的问题可能很基本,但我的知识有限。理想情况下,我将非常感谢逐步的答案。我已经在windows平台上安装了Intel oneAPI Base Toolkit。
最诚挚的问候, 阿纳斯塔西娅
最佳答案
这是问题中 C 函数的工作示例。
C 代码,文件 so_77177870.c
// file: so_77177870.c
#include <R.h>
#include <mkl.h>
void multiplyAndSum(double *x, double *y, int *length, double *result) {
*result = cblas_ddot(*length, x, 1, y, 1);
}
编译上面的代码
R CMD SHLIB so_77177870.c
这将在 Windows 中生成一个共享库,扩展名为 .dll
。
然后,在 R 中加载库并编写包装函数 dotprod
。 C 代码的返回值是它的最后一个参数。
参见Writing R Extensions, section 5.2 .
dynLoad <- function(dynlib){
dynlib <- paste0(dynlib, .Platform$dynlib.ext)
dyn.load(dynlib)
}
dynUnload <- function(dynlib){
dynlib <- paste0(dynlib, .Platform$dynlib.ext)
dyn.unload(dynlib)
}
dotprod <- function(x, y) {
.C("multiplyAndSum",
as.double(x), as.double(y),
as.integer(length(x)),
result = double(1)
)$result
}
# load the shared library, in this case so_77177870.dll
dll <- "so_77177870"
dynLoad(dll)
x <- c(1, 2, 3)
y <- c(4, 5, 6)
sum(x * y)
#> [1] 32
dotprod(x, y)
#> [1] 32
# unload the shared library when done
dynUnload(dll)
创建于 2023 年 9 月 26 日 reprex v2.0.2
关于r - 集成 C 子函数以优化 R 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77177870/