I have an existing R script that performs various operations, and I'm looking to create a C sub function to optimize a specific part of it. My goal is to integrate this C sub function within R Desktop for improved performance and efficiency.
For example, let's assume that I want to sum the elements obtained by multiplying the vector x and y. In R, I can achieve this with the following code:
x <- c(1, 2, 3)
y <- c(4, 5, 6)
z <- sum(x * y)
The same operation using oneMKL can be performed like this:
#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;
}
After compiling the .c function using CMD, I get:
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
What I want to do is replace the 4th line of the Rscript code with a .c function. I'm facing two problems:
1. Convert the C Function for General Inputs:
I don't know if I have defined the function correctly.
#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. Calling the C Function in R:
I don't know how to call the .c function in step 1 within R. Is there a way to compile the function and run it explicitly within R Desktop, without using the command prompt (cmd)
Please, I understand that my question may be quite basic, but my knowledge is limited. I would greatly appreciate a step-by-step answer, ideally. I have installed Intel oneAPI Base Toolkit on windows platform.
Best regards, Anastasia
PS: My environment variables are displayed in the image below. Perhaps this information could be helpful for you to assist me.
Here is a working example with the C function in the question.
C code, file 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);
}
Compile the code above with
R CMD SHLIB so_77177870.c
This will produce a shared library, extension .dll
in Windows.
Then, in R, load the library and write a wrapper function, dotprod
. The C code's return value is its last argument.
See 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)
Created on 2023-09-26 with reprex v2.0.2