将LAPACKE_zgetrs与LAPACK_ROW_MAJOR一起使用会导致非法内存访问

时间:2015-05-13 10:54:00

标签: c lapack lapacke

我正在尝试使用以下代码解决线性系统:

#include <stdio.h>
#include <lapacke.h>

int main () {
    lapack_complex_double mat[4];
    lapack_complex_double vec[2];
    lapack_int p[2];

    mat[0] = lapack_make_complex_double(1,0);
    mat[1] = lapack_make_complex_double(1,0);
    mat[2] = lapack_make_complex_double(1,0);
    mat[3] = lapack_make_complex_double(-1,0);

    vec[0] = lapack_make_complex_double(1,0);
    vec[1] = lapack_make_complex_double(1,0);

    LAPACKE_zgetrf(LAPACK_ROW_MAJOR, 2, 2, mat, 2, p);
    LAPACKE_zgetrs(LAPACK_ROW_MAJOR, 'N', 2, 1, mat, 2, p, vec, 2);

    printf("%g %g\n", lapack_complex_double_real(vec[0]),
        lapack_complex_double_imag(vec[0]));
    return 0;
}

由于某些原因,这导致LAPACKE_zgetrs中的非法内存访问(由valgrind检测到并且我的大程序在zgetrs崩溃,因为“glibc检测到损坏或双重免费“)。为简洁起见,我没有将此包含在我的SSCCE中,但返回的所有LAPACKE例程都返回0。

LAPACK_COL_MAJOR的相同代码运行完美,并且完美无瑕。

我的lapacke,lapack等是为Ubuntu 12.04自行构建的。我在lapack CMake文件中使用了以下设置:

BUILD_COMPLEX       ON
BUILD_COMPLEX16     ON
BUILD_DOUBLE        ON
BUILD_SHARED_LIBS   ON
BUILD_SINGLE        ON
BUILD_STATIC_LIBS   ON
BUILD_TESTING       ON
CMAKE_BUILD_TYPE    Release
LAPACKE             ON
LAPACKE_WITH_TMG    ON

和其他(优化的blas / lapack和xblas)关闭。构建期间没有错误,所有测试都成功。

我在哪里陷入困境?

编辑:我刚刚尝试使用Fedora21和打包的lapacke。它确实重现错误。

编辑2:虽然它不会重现内存失败,但它会产生错误的解决方案,即上述输入的(1 + 0I, 1 + 0I)(应为(1,0)

1 个答案:

答案 0 :(得分:0)

经过一些研究和过度思考后,我找到了罪魁祸首:

使用LAPACK_ROW_MAJOR切换ld*主要维度参数的含义。虽然普通Fortran数组的前导维度是的数量,但切换到ROW_MAJOR会将其含义切换为的数量。所以正确的调用(给出正确的结果)将是:

LAPACKE_zgetrs(LAPACK_ROW_MAJOR, 'N', 2, 1, mat, 2, p, vec, 1);

其中第二个2mat(不是行!)的数量,最后一个参数必须等于右侧的数量{{1 (不是变量的数量!)。我隔离了这个电话,因为我项目中的所有其他调用都处理了方形矩阵,所以&#34;错误&#34;由于对称性,呼叫没有任何负面影响。

像往常一样,如果您在末尾跳过列,则相应的前导尺寸会变大,就像在正常设置中跳过行一样。

显然,Fortran文档中没有提到这一点。不幸的是,我确实在Lapacke文档中没有看到这样的评论,这本可以为我节省几个小时的生命。 :)