Package: lapack3-dev Version: 3.0.20000531a-6 Severity: normal Hi, I'm a little hesitant to file this bug report, since lapack is such a well-tested package.
BACKGROUND: The lapack function dgesdd_(), used for computing the SVD of a general matrix, requires an externally supplied workspace. One way to know how big this workspace must be is to call dgesdd_() with parameter 12, LWORK, set to -1. In this case the usual SVD commputation is not carried out. Instead, the optimal workspace size is returned through parameter 11, WORK. A correctly sized workspace can then be allocated and used in subsequent calls to dgesdd_(). PROBLEM: After upgrading to lapack3-dev, I'm observing that the initial call to dgesdd_() no longer returns a valid workspace size. Attempting to use the returned value results in an error and, apparently, a call to exit(). System info is at the end of this email. EXAMPLE: I've included a code snippet below which exercises the bug. You can compile it by saving as dgesddExample.c: > gcc dgesddExample.c -o dgesddExample -llapack You can then run it with no arguments, in which case the erronious return value from dgesdd_() will be corrected: > ./dgesddExample Warning: corrected LWORK from 1 to 27. Both calls to dgesdd() completed successfully. Or you can run it with an argument, in which case the erronious return value from dgesdd_() will not be corrected, and the second call to dgesdd_() will raise an error: > ./dgesddExample crash ** On entry to DGEBRD parameter number 10 had an illegal value Thanks for your help and hard work, David --------------------- Code starts here --------------------- /** * This file exercises a bug in the lapack routine dgesdd(), in which * the reported workspace requirement is insufficient. */ #include <malloc.h> #include <stdio.h> #include <stdlib.h> /** * This is a declaration for the LAPACK routine dgesdd(), which * computes the singular value decomposition of a matrix using a * fast divide & conquer algorithm. */ void dgesdd_(char* JOBZ, long int* M, long int* N, double* A, long int* LDA, double* S, double* U, long int* LDU, double* VT, long int* LDVT, double* WORK, long int* LWORK, long int* IWORK, long int* INFO); /** * The main() function here simply computes the SVD of a 4x3 matrix: * * * |1.0, 5.0. 9.0| * A = |2.0, 6.0, 10.0| * |3.0, 7.0, 11.0| * |4.0, 8.0, 12.0| * * When called with no arguments, the program checks the LWORK size * returned from dgesdd_(), and corrects it. If an input argument is * supplied, then the value of LWORK is not corrected, and the program * crashes. */ int main(int argc, char* argv[]) { const int A_ROWS = 4; const int A_COLUMNS = 3; const int A_SIZE = A_ROWS * A_COLUMNS; const int MINIMUM_DIMENSION = A_ROWS > A_COLUMNS ? A_COLUMNS : A_ROWS; const int MAXIMUM_DIMENSION = A_ROWS > A_COLUMNS ? A_ROWS : A_COLUMNS; /* We define a couple of constants to find the minimum acceptable */ /* size of the WORK array which will be passed to dgesdd() */ const int tempVal0 = (MAXIMUM_DIMENSION > 6 * MINIMUM_DIMENSION ? MAXIMUM_DIMENSION : 6 * MINIMUM_DIMENSION); const long int minimumLWORK = 3 * MINIMUM_DIMENSION + tempVal0; /* Arguments for lapack call. */ char JOBZ = 'N'; /* Compute no columns of U and no rows of VT. */ double A[A_SIZE]; /* We'll have a 4x3 matrix. */ double S[MINIMUM_DIMENSION]; /* We'll compute 3 singular values. */ long int IWORK[8 * MINIMUM_DIMENSION]; /* Workspace required by lapack. */ long int M = A_ROWS; long int N = A_COLUMNS; long int LDA = M; double U; /* Since JOBZ == 'N', U is not referenced. */ long int LDU = 1; double VT; /* Since JOBZ == 'N', VT is not referenced. */ long int LDVT = 1; double* WORK = (double*)malloc(sizeof(double)); long int LWORK = -1; /* Request info on optimal workspace size. */ long int INFO; /* Initialize the matrix A. */ int aIndex; for(aIndex = 0; aIndex < A_SIZE; ++aIndex) { A[aIndex] = aIndex + 1; } /* Call once to request optimal workspace size. */ dgesdd_(&JOBZ, &M, &N, A, &LDA, S, &U, &LDU, &VT, &LDVT, WORK, &LWORK, IWORK, &INFO); /* Check for errors. */ if(INFO != 0L) { fprintf(stderr, "Error: first call to dgesdd_ returns &ld.\n", INFO); exit(1); } /* Recover optimal workspace size. */ LWORK = (long int)(WORK[0]); /* Sanity check. Is the returned value of LWORK legal? */ if(LWORK < minimumLWORK) { if(argc == 1) { fprintf(stderr, "Warning: changing LWORK from %ld to %ld.\n", LWORK, minimumLWORK); LWORK = minimumLWORK; } } else { fprintf(stderr, "Submitter was mistaken: the returned value for LWORK " "is perfectly legal"); } /* Resize workspace. */ free(WORK); WORK = (double*)malloc(LWORK * sizeof(double)); /* Call dgesdd() again to do the SVD. */ dgesdd_(&JOBZ, &M, &N, A, &LDA, S, &U, &LDU, &VT, &LDVT, WORK, &LWORK, IWORK, &INFO); /* Check for errors. */ if(INFO != 0L) { fprintf(stderr, "Error: secondd call to dgesdd_ returns &ld.\n", INFO); exit(3); } // Phew! Made it. fprintf(stderr, "Both calls to dgesdd() completed successfully.\n"); exit(0); } --------------------- Code ends here --------------------- -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.9-1-686-smp Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Versions of packages lapack3-dev depends on: ii g77 4:3.4.4-5 The GNU Fortran 77 compiler ii lapack3 3.0.20000531a-6 library of linear algebra routines ii libc6-dev 2.3.5-6 GNU C Library: Development Librari ii refblas3-dev [libblas-3. 1.2-8 Basic Linear Algebra Subroutines 3 lapack3-dev recommends no packages. -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]