英文:
R session crashes when using .so file that uses OpenBLAS
问题
我尝试使用OpenBLAS在C++中编写一些简单的矩阵计算代码,然后将我的程序导入到R中。我没有使用任何与Rcpp相关的东西。
当单独编译时,C++程序运行完美。当我注释掉包含OpenBLAS函数的几行代码,使用R CMD SHLIB
进行编译,并使用dyn.load
导入.so文件到我的R程序时,R可以正常工作。
然而,如果我取消注释涉及OpenBLAS的部分,R每次都会崩溃。当从终端运行时,会报告以下错误消息:
R(90544,0x16bd7f000) malloc: 检测到堆损坏,释放列表在0x6000033d0620处已损坏
*** 不正确的保护值:0
R(90544,0x16bd7f000) malloc: *** 设置断点以调试malloc_error_break
zsh: 中止 R
另外,当我只运行单行OpenBLAS命令时,会出现以下错误:
*** 捕获到段错误 ***
地址0x60012e797320,原因 '无效的权限'
我是不是漏掉了什么?我确实需要一些帮助,因为我已经在这个问题上挣扎了很长时间了。谢谢大家。
英文:
I tried to write some simple matrix calculation code in c++ with OpenBLAS and then import my program into R. I did not use any Rcpp related things.
When compiled alone, the c++ program works perfectly. When I commented the few lines with OpenBLAS functions, used R CMD SHLIB
to compile it and used dyn.load
to import the .so file into my R program, R works fine.
However, if I uncommented the OpenBLAS-involved part, R crashes every time. When run from terminal, the following error message was reported:
R(90544,0x16bd7f000) malloc: Heap corruption detected, free list is damaged at 0x6000033d0620
*** Incorrect guard value: 0
R(90544,0x16bd7f000) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort R
Also, when I run only with a single line of OpenBLAS command, there was the following error:
*** caught segfault ***
address 0x60012e797320, cause 'invalid permissions'
Do I miss something? I do need some help since I struggled with this for a long time. Thank you guys.
答案1
得分: 3
我找到了一个方法。我直接使用了R中使用的LAPACK,并按照这里 medium.com/@shiansu/calling-blas-in-r-the-hard-way-da90e0206d99 中描述的步骤进行了操作。稍作调整后,我的代码终于能够运行。
建议将相应的代码添加到我的答案中可能会更好。用于矩阵乘法的示例C代码如下:
#include <R.h>
#include <Rinternals.h>
SEXP mat_mul_blas(SEXP A_, SEXP B_, SEXP m_, SEXP n_, SEXP k_) {
double* A = REAL(A_);
double* B = REAL(B_);
int m = asInteger(m_); // A中的行数
int n = asInteger(n_); // B中的列数
int k = asInteger(k_); // A中的列数和B中的行数
char* transa = "N";
char* transb = "N";
double alpha = 1.0;
double beta = 0.0;
SEXP RES_;
RES_ = PROTECT(allocMatrix(REALSXP, m, n));
double* RES = REAL(RES_);
F77_NAME(dgemm)
(transa, transb, &m, &n, &k, &alpha, A, &m, B, &k, &beta, RES, &m);
UNPROTECT(1);
return (RES_);
}
为了将C文件编译为so文件,我们可能需要在终端中运行以下命令:
R CMD SHLIB xxx.c
为了使编译顺利进行,我们可能需要配置Makeconf
文件。在我的情况下,它位于目录/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/etc/Makeconf
下,我相信在不同的计算机上会有所不同。
我希望这个更详细的答案对其他有类似问题的人有所帮助。
英文:
I found a way round. I directly use the LAPACK used by R and followed the procedure stated here medium.com/@shiansu/calling-blas-in-r-the-hard-way-da90e0206d99. With some slight adaption, my code could finally work.
It is suggested that it might be better to add the corresponding code to my answer. A sample c code for matrix multiplication is as follows:
#include <R.h>
#include <Rinternals.h>
SEXP mat_mul_blas(SEXP A_, SEXP B_, SEXP m_, SEXP n_, SEXP k_) {
double* A = REAL(A_);
double* B = REAL(B_);
int m = asInteger(m_); // The number of rows in A
int n = asInteger(n_); // The number of columns in B
int k = asInteger(k_); // The number of columns in A and rows in B
char* transa = "N";
char* transb = "N";
double alpha = 1.0;
double beta = 0.0;
SEXP RES_;
RES_ = PROTECT(allocMatrix(REALSXP, m, n));
double* RES = REAL(RES_);
F77_NAME(dgemm)
(transa, transb, &m, &n, &k, &alpha, A, &m, B, &k, &beta, RES, &m);
UNPROTECT(1);
return (RES_);
}
In order to compile the c file into so file, we might need to run the following command in the terminal
R CMD SHLIB xxx.c
In order to make the compilation smooth, we may need to configure the Makeconf
file. For my case, it is under the directory /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/etc/Makeconf
and I believe it varies among different computers.
I hope this more detailed answer is helpful for others with a similar question.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论