Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
ajz34 opened this issue May 12, 2025 · 0 comments
Open
2 tasks done

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

ajz34 opened this issue May 12, 2025 · 0 comments

Comments

@ajz34
Copy link

ajz34 commented May 12, 2025

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant