Bug 16157 - Wrong declarations of dlaed2 and dlaed3 in R_ext/Lapack.h
Summary: Wrong declarations of dlaed2 and dlaed3 in R_ext/Lapack.h
Status: CLOSED FIXED
Alias: None
Product: R
Classification: Unclassified
Component: Low-level (show other bugs)
Version: R 3.1.2
Hardware: All All
: P5 enhancement
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2015-01-14 14:50 UTC by Joong-Ho Won
Modified: 2015-12-14 13:46 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joong-Ho Won 2015-01-14 14:50:52 UTC
LAPACK functions DLAED2 and DLAED3 are declared with wrong interface in R_ext/Lapack.h:

/* DLAED2 - merge the two sets of eigenvalues together into a */
/* single sorted set */
La_extern void
F77_NAME(dlaed2)(const int* k, const int* n, double* d,
		 double* q, const int* ldq, int* indxq,
		 double* rho, const int* cutpnt, double* z,
		 double* dlamda, double* q2, const int *ldq2,
		 int* indxc, int* w, int* indxp, int* indx,
		 int* coltyp, int* info);
/* DLAED3 - find the roots of the secular equation, as defined by */
/* the values in double* d, W, and RHO, between KSTART and KSTOP */
La_extern void
F77_NAME(dlaed3)(const int* k, const int* kstart,
		 const int *kstop, const int* n,
		 double* d, double* q, const int* ldq,
		 const double* rho, const int* cutpnt,
		 double* dlamda, int* q2, const int* ldq2,
		 int* indxc, int* ctot, double* w,
		 double* s, const int* lds, int* info);

It appears that the current (R 3.1.2) declarations of these functions in this header file are taken from LAPACK 2.0; see http://wwwuser.gwdg.de/~parallel/parallelrechner/scalapack/manpages/lapack/manl/dlaed2.l and http://wwwuser.gwdg.de/~parallel/parallelrechner/scalapack/manpages/lapack/manl/dlaed3.l

R 3.1.2 uses LAPACK 3.1 and above -- see https://github.com/wch/r-source/tree/trunk/src/modules/lapack

Indeed calling DLAED2 and DLAED3 using the above (wrong) interface caused an error. The correct interface can be found at http://www.netlib.org/lapack/explore-html/d6/daa/dlaed2_8f.html and http://www.netlib.org/lapack/explore-html/d3/de3/dlaed3_8f.html

While these functions are used rarely outside of DLAED1, as the header exposes them to public, the wrong declarations are better to be fixed.

Current workaround is not to include R_ext/Lapack.h and declare required LAPACK functions individually following the LAPACK 3.1 standard.
Comment 1 Brian Ripley 2015-01-16 10:05:11 UTC
Please supply a patch, which would make your intentions clear.
Comment 2 Joong-Ho Won 2015-01-16 14:02:45 UTC
Prof. Ripley:

Sure. Below is the patch created using diff.

--- Lapack.h	2013-09-25 20:59:05.000000000 +0900
+++ Lapack_patch.h	2015-01-16 22:59:57.000000000 +0900
@@ -1694,22 +1694,20 @@
 /* DLAED2 - merge the two sets of eigenvalues together into a */
 /* single sorted set */
 La_extern void
-F77_NAME(dlaed2)(const int* k, const int* n, double* d,
+F77_NAME(dlaed2)(const int* k, const int* n, const int* n1, double* d,
 		 double* q, const int* ldq, int* indxq,
-		 double* rho, const int* cutpnt, double* z,
-		 double* dlamda, double* q2, const int *ldq2,
-		 int* indxc, int* w, int* indxp, int* indx,
+		 double* rho, double* z,
+		 double* dlamda, double* w, double* q2,
+		 int* indx, int* indxc, int* indxp,
 		 int* coltyp, int* info);
 /* DLAED3 - find the roots of the secular equation, as defined by */
 /* the values in double* d, W, and RHO, between KSTART and KSTOP */
 La_extern void
-F77_NAME(dlaed3)(const int* k, const int* kstart,
-		 const int *kstop, const int* n,
+F77_NAME(dlaed3)(const int* k, const int* n, const int* n1,
 		 double* d, double* q, const int* ldq,
-		 const double* rho, const int* cutpnt,
-		 double* dlamda, int* q2, const int* ldq2,
-		 int* indxc, int* ctot, double* w,
-		 double* s, const int* lds, int* info);
+		 const double* rho, double* dlamda, double* q2, 
+		 int* indx, int* ctot, double* w,
+		 double* s, int* info);
 /* DLAED4 - subroutine computes the I-th updated eigenvalue of a */
 /* symmetric rank-one modification to a diagonal matrix whose */
 /* elements are given in the array d, and that	 D(i); < D(j); for */
Comment 3 Brian Ripley 2015-01-17 07:32:07 UTC
Thanks, inline patches rarely work but it made the intention clear.

Fixed now.