You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译R包时调用Fortran 77 BLAS的dgemv函数出现参数数量不匹配错误

编译R包时调用Fortran 77 BLAS的dgemv函数出现参数数量不匹配错误

问题描述

我有一个用了好几年的R包,最近编译时突然遇到之前没见过的错误,特别是Fortran BLAS库的函数参数好像变多了。比如dgemv以前是11个参数,现在居然要求12个,编译报错说参数不够:

matrix.c:44:83: error: too few arguments to function call, expected 12, have 11
        F77_CALL(dgemv)(transa, &nrx, &ncx, &alpha, x, &nrx, y, &ncy, &beta, z, &ncy);

我找不到这些新函数的文档,完全卡壳了。

代码是C写的,调用Fortran 77的dgemv做矩阵乘向量,下面是最小可复现示例:

C文件代码

#include <R.h>
#include <Rinternals.h>
#include <math.h>
#include <R_ext/Applic.h> /* array.c says need for dgemm */
#include <R_ext/Lapack.h> /* array.c says need for dgemm */

/* following copied from array.c */
void matprod(double *x, int nrx, int ncx,
             double *y, int nry, int ncy, double *z, double alpha, double beta)
{
  char *transa = "N";

  F77_CALL(dgemv)(transa, &nrx, &ncx, &alpha, x, &nrx, y, &ncy, &beta, z, &ncy);
}

R文件调用函数

mp <- function (x, y) {
  ## get dimensions
  dX <- dim(x)
  ly <- length(y)

  ## set up output
  z <- numeric(dX[1])

  ## perform the matrix multiplication
  matprod(as.numeric(x), as.integer(dX[1]), as.integer(dX[2]),
          as.numeric(y), as.integer(ly), 1L,
          as.numeric(z), 1.0, 0.0)

  return(z)
}

完整编译错误信息

── R CMD INSTALL ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
─  installing *source* package ‘testMWE’ ...
   ** using staged installation
   ** libs
   using C compiler: ‘Apple clang version 12.0.5 (clang-1205.0.22.9)’
   using C++ compiler: ‘Apple clang version 12.0.5 (clang-1205.0.22.9)’
   using SDK: ‘MacOSX11.3.sdk’
   clang++ -arch x86_64 -std=gnu++17 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG  -I'/Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include' -I/opt/R/x86_64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c RcppExports.cpp -o RcppExports.o
   clang -arch x86_64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG  -I'/Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include' -I/opt/R/x86_64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -fdiagnostics-color=always -c testMWE.c -o testMWE.o
   testMWE.c:13:79: error: too few arguments to function call, expected 12, have 11
     F77_CALL(dgemv)(transa, &nrx, &ncx, &alpha, x, &nrx, y, &ncy, &beta, z, &ncy);
     ~~~~~~~~~~~~~~~                                                             ^
   /Library/Frameworks/R.framework/Resources/include/R_ext/BLAS.h:107:1: note: 'dgemv_' declared here
   F77_NAME(dgemv)(const char *trans, const int *m, const int *n,
   ^
   /Library/Frameworks/R.framework/Resources/include/R_ext/RS.h:81:24: note: expanded from macro 'F77_NAME'
   #define F77_NAME(x)    F77_CALL(x)
                          ^
   /Library/Frameworks/R.framework/Resources/include/R_ext/RS.h:77:22: note: expanded from macro 'F77_CALL'
   # define F77_CALL(x)    x ## _
                           ^
   <scratch space>:83:1: note: expanded from here
   dgemv_
   ^
   1 error generated.
   make: *** [testMWE.o] Error 1
   ERROR: compilation failed for package ‘testMWE’
─  removing ‘/private/var/folders/hy/gbflvvdd5935l261dv4gtf900000gn/T/RtmpVM5ny2/devtools_install_b83f5e2c276a/testMWE’
Error in `(function (command = NULL, args = character(), error_on_status = TRUE, …`:
! System command 'R' failed
---
Exit status: 1
stdout & stderr: <printed>
---

系统信息

  • Mac running Sonoma 14.6.1
  • RStudio Version 2024.09.0+375 (2024.09.0+375)

我试过找BLAS函数的文档,也在电脑上找新函数,都没结果,可能我猜的原因不对?


解决方案及分析

问题根源

其实不是BLAS的dgemv本身参数变多了,而是R在新版本中(尤其是4.3.x及以后)对BLAS接口的封装做了调整——新增了一个用于传递Fortran字符串长度的参数。Fortran 77的字符串需要显式传递长度,旧版本的R封装可能帮你隐式处理了,但现在要求用户显式传入这个参数,这就是报错说需要12个参数的原因。

修复代码

你只需要在调用dgemv的时候,在transa参数后面加上它的长度即可。因为transa是"N",长度是1,有两种修改方式:

方式1:定义变量传递长度

void matprod(double *x, int nrx, int ncx,
             double *y, int nry, int ncy, double *z, double alpha, double beta)
{
  char *transa = "N";
  int trans_len = 1; // 新增:定义字符串长度变量

  F77_CALL(dgemv)(transa, &trans_len, &nrx, &ncx, &alpha, x, &nrx, y, &ncy, &beta, z, &ncy);
}

方式2:用复合字面量直接传递(C99及以后支持)

void matprod(double *x, int nrx, int ncx,
             double *y, int nry, int ncy, double *z, double alpha, double beta)
{
  char *transa = "N";

  F77_CALL(dgemv)(transa, &(int){1}, &nrx, &ncx, &alpha, x, &nrx, y, &ncy, &beta, z, &ncy);
}

验证与后续建议

修改完代码后重新编译,应该就能顺利通过了。如果你不确定其他BLAS函数的参数变化,可以直接查看R安装目录下的R_ext/BLAS.h文件,里面有所有BLAS函数的最新声明,能帮你快速核对参数列表。

备注:内容来源于stack exchange,提问作者rje42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:39:32