-
Notifications
You must be signed in to change notification settings - Fork 424
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
Add (s,d)ROUNDUP_LWORK functions to fix the workspace computation #605
Add (s,d)ROUNDUP_LWORK functions to fix the workspace computation #605
Conversation
Codecov Report
@@ Coverage Diff @@
## master #605 +/- ##
=======================================
Coverage 0.00% 0.00%
=======================================
Files 1894 1896 +2
Lines 199133 199143 +10
=======================================
- Misses 199133 199143 +10
Continue to review full report at Codecov.
|
Please see my comment to #600 If integer LWORK overflow then adding EPS won't help. |
…PS)) Test results: SROUNDUP_LWORK(0) = 0.00000000 SROUNDUP_LWORK(1) = 1.00000000 SROUNDUP_LWORK(317) = 317.000000 DROUNDUP_LWORK(0) = 0.0000000000000000 DROUNDUP_LWORK(1) = 1.0000000000000000 DROUNDUP_LWORK(317) = 317.00000000000000 Tests with X = 16777216 = 2**24 X-2 = 16777214; SROUNDUP_LWORK(X-2) = 16777214.0 X-1 = 16777215; SROUNDUP_LWORK(X-1) = 16777215.0 X = 16777216; SROUNDUP_LWORK(X ) = 16777218.0 X+1 = 16777217; SROUNDUP_LWORK(X+1) = 16777218.0 X+2 = 16777218; SROUNDUP_LWORK(X+2) = 16777220.0 Tests with X = 9007199254740992 = 2**53 X-2 = 9007199254740990; SROUNDUP_LWORK(X-2) = 9007200328482816.0 X-1 = 9007199254740991; SROUNDUP_LWORK(X-1) = 9007200328482816.0 X = 9007199254740992; SROUNDUP_LWORK(X ) = 9007200328482816.0 X+1 = 9007199254740993; SROUNDUP_LWORK(X+1) = 9007200328482816.0 X+2 = 9007199254740994; SROUNDUP_LWORK(X+2) = 9007200328482816.0 Tests with X = 9007199254740992 = 2**53 X-2 = 9007199254740990; DROUNDUP_LWORK(X-2) = 9007199254740990.0 X-1 = 9007199254740991; DROUNDUP_LWORK(X-1) = 9007199254740991.0 X = 9007199254740992; DROUNDUP_LWORK(X ) = 9007199254740994.0 X+1 = 9007199254740993; DROUNDUP_LWORK(X+1) = 9007199254740994.0 X+2 = 9007199254740994; DROUNDUP_LWORK(X+2) = 9007199254740996.0
419261a
to
cea9568
Compare
Two commits with updates in the ROUNDUP_LWORK functions:
With (1), the roundup routines always return a floating-point number that is an integer. I do that by checking whether SROUNDUP_LWORK .GE. REAL(RADIX(0.0E+0))**DIGITS(0.0E+0) The latter is valid for the single-precision case. I used a similar test for the double-precision case. The code in MAGMA uses DLAMCH('E'). I am not sure this is the correct option. I ran a few tests (below) and saw that one must use EPSILON(0) (or 2*LAMCH(EPS)) to get the desired rounding up. Some tests: I compiled the LAPACK with
just to be sure the output has only 0 decimal parts. The gist also applies the CEILING and FLOOR to the result t guarantee there is no decimal part. |
Verifying the round down/up in the conversion from INTEGER(8) to REAL and DOUBLE PRECISION:
|
Another related test shows how PROGRAM test_convert
IMPLICIT NONE
INTEGER(4) intX
INTEGER(8) X
REAL realX
DOUBLE PRECISION dbleX
INTRINSIC REAL, DBLE, HUGE
realX = REAL(HUGE(intX))
dbleX = DBLE(HUGE(intX))
WRITE(*,992) HUGE(intX), realX, INT(realX,4), REAL(INT(realX,4))
WRITE(*,992) HUGE(intX), dbleX, INT(dbleX,4), DBLE(INT(dbleX,4))
realX = REAL(HUGE(intX)) * 2
dbleX = DBLE(HUGE(intX)) * 2
WRITE(*,992) HUGE(intX), realX, INT(realX,4), REAL(INT(realX,4))
WRITE(*,992) HUGE(intX), dbleX, INT(dbleX,4), DBLE(INT(dbleX,4))
realX = REAL(HUGE(X))
dbleX = DBLE(HUGE(X))
WRITE(*,993) HUGE(X), realX, INT(realX,8), REAL(INT(realX,8))
WRITE(*,993) HUGE(X), dbleX, INT(dbleX,8), DBLE(INT(dbleX,8))
realX = REAL(HUGE(X)) * 2
dbleX = DBLE(HUGE(X)) * 2
WRITE(*,993) HUGE(X), realX, INT(realX,8), REAL(INT(realX,8))
WRITE(*,993) HUGE(X), dbleX, INT(dbleX,8), DBLE(INT(dbleX,8))
992 FORMAT( I11, "; ", F13.1, "; ", I11, "; ", F13.1 )
993 FORMAT( I20, "; ", F22.1, "; ", I20, "; ", F22.1 )
END PROGRAM test_convert Output (compiled with
|
What about forcing round up only if
This test can be less performant than testing |
51eee01
to
913ca15
Compare
913ca15
to
c7400e5
Compare
Regarding MAGMA, after precision-generation,
This works up to lwork around 2^53 (33,554,432 GiB in single). Using 1 + epsilon, for epsilon = 1.19e-07 as defined by Fortran, C, C++, Matlab, etc. works for even larger lwork (I checked up to 2^61). Note slamch("eps") returns unit roundoff, u = 5.96e-08, which is epsilon/2. |
Thanks for the clarification, @mgates3 ! |
[edited]
Description
There is a known bug in LAPACK related to workspaces smaller than the value computed by the routine. This is because the routines use a floating-point variable to return the integer workspace size. See #600. The intent here is to mitigate the problem of overestimating the workspace when doing the conversion INTEGER -> REAL (or DOUBLE PRECISION) highlighted in #600. I do not solve the problem of a possible overflow in LWORK.
This PR applies the same strategy from the MAGMA package to solve the issue (See #600 (comment) from @mgates3).
Checklist