Skip to content

LAPACKE too strict leading dimension check on LAPACKE_?gesdd_work #1125

Closed
@ajz34

Description

@ajz34

Description

In LAPACKE, for function LAPACKE_?gesdd_work, given jobz is 'N' (do not compute U and VT), and the leading dimension of VT is given to a too small value (1 for instance), then LAPACKE will error on this.

This is probably not the desired behavior. Since VT is not referenced here, the leading dimension of VT should also not be referenced, arbitary values should hold for ldvt (however, this value should still be at least 1, which is also checked in LAPACK).

Similar bug has been fixed in #534 for LAPACKE_?gesvd_work. Perhaps functions LAPACKE_?gesdd_work were just missed in that fix.

PR #1126 tries to resolve this issue.

Minimal Example

#include <iostream>
#include "lapacke.h"

int main() {
    // query test
    int m = 3, n = 2;
    double a[6];
    double s[3];
    double u[9];
    double vt[4];
    double superb[3];
    int info = 0;

    // success, dgesvd with compute_uv
    std::cout << "dgesvd with compute_uv" << std::endl;
    for (int i = 0; i < 6; ++i) a[i] = i + 1;
    info = LAPACKE_dgesvd( LAPACK_ROW_MAJOR, 'A', 'A', m, n, a, n, s, u, m, vt, n, superb);
    if (info != 0) return info;
    for (int i = 0; i < 3; ++i) {
        std::cout << "s[" << i << "] = " << s[i] << std::endl;
    }

    // success, dgesdd with compute_uv
    std::cout << "dgesdd with compute_uv" << std::endl;
    for (int i = 0; i < 6; ++i) a[i] = i + 1;
    info = LAPACKE_dgesdd(LAPACK_ROW_MAJOR, 'A', m, n, a, n, s, u, m, vt, n);
    if (info != 0) return info;
    for (int i = 0; i < 3; ++i) {
        std::cout << "s[" << i << "] = " << s[i] << std::endl;
    }

    // success, dgesvd without compute_uv, null u and vt, small ldu and ldvt
    std::cout << "dgesvd without compute_uv, null u and vt, small ldu and ldvt" << std::endl;
    for (int i = 0; i < 6; ++i) a[i] = i + 1;
    info = LAPACKE_dgesvd(LAPACK_ROW_MAJOR, 'N', 'N', m, n, a, n, s, NULL, 1, NULL, 1, superb);
    if (info != 0) return info;
    for (int i = 0; i < 3; ++i) {
        std::cout << "s[" << i << "] = " << s[i] << std::endl;
    }
    
    // success, dgesdd with compute_uv, null u and vt, [[large]] ldu and [[ldvt]]
    std::cout << "dgesdd with compute_uv, null u and vt, [[large]] ldu and [[ldvt]]" << std::endl;
    for (int i = 0; i < 6; ++i) a[i] = i + 1;
    info = LAPACKE_dgesdd(LAPACK_ROW_MAJOR, 'N', m, n, a, n, s, NULL, 1, NULL, n);
    if (info != 0) return info;
    for (int i = 0; i < 3; ++i) {
        std::cout << "s[" << i << "] = " << s[i] << std::endl;
    }
    
    // failure, dgesdd with compute_uv, null u and vt, [[small]] ldu and [[ldvt]]
    std::cout << "dgesdd with compute_uv, null u and vt, [[small]] ldu and [[ldvt]]" << std::endl;
    for (int i = 0; i < 6; ++i) a[i] = i + 1;
    info = LAPACKE_dgesdd(LAPACK_ROW_MAJOR, 'N', m, n, a, n, s, NULL, 1, NULL, 1);
    if (info != 0) return info;
    for (int i = 0; i < 3; ++i) {
        std::cout << "s[" << i << "] = " << s[i] << std::endl;
    }
}

Checklist

  • I've included a minimal example to reproduce the issue
  • I'd be willing to make a PR to solve this issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions