Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29236 Discussions

A problem with double precision version of an IMSL routine

Intel_C_Intel
Employee
856 Views

Hello,

When running the enclosed code in single precision I get the following output (IVF 9.1.037 Pro using IMSL):

Q= 0.9797987 errest= 5.8414125E-06

When changing to double precision (single precision statements commented out in the enclosed) I get the following output:

*** TERMINAL ERROR 4 from DQ2AGS. The error tolerance arguments ERRABS and
*** ERRREL are both equal to zero. At least one of them must be
*** greater than zero.
Here is a traceback of subprogram calls in reverse order:
Routine name Error type Error code
------------ ---------- ----------
DQ2AGS 5 4 (Called internally)
DQDAGS 0 0
USER 0 0

Compilation and link are with no errors.

I would appreciate any help,

Yair

=========================================================================================================================

use QDAGS_INT
include 'link_f90_static.h' ! for IMSL routines
!implicit real*4 (a-h,o-z)
implicit real*8 (a-h,o-z)
sigx=700.
R=7000.
D=100./sigx
ERRABS = 0.
ERRREL = 0.001
!CALL QDAGS (FUN, 0., R/sigx, Q, ERRABS, ERRREL, ERREST)
CALL DQDAGS (FUN, 0., R/sigx, Q, ERRABS, ERRREL, ERREST)
print *,'Q=',Q,' errest=',errest
contains
function FUN
! FUN = exp(-D**2/2)*exp(-r**2/2)*BSJ0(r*D)*r
FUN = dexp(-D**2/2)*dexp(-r**2/2)*DBSJ0(r*D)*r
end function FUN
end

0 Kudos
3 Replies
Steven_L_Intel1
Employee
856 Views
I won't be able to try this until Monday, but I have a good guess as to the problem:

If you're going to use the QDAGS_INT module, do NOT call DQDAGS, which is a Fortran 77 interface.with different arguments. Just call QDAGS with the REAL*8 arguments, which is a generic interface. Also, make that 0. in the call 0.0D0.
0 Kudos
yair999
Beginner
856 Views

You were right, it now works. So now to another related question: I've tried to switch from single to double precision using /real_size:64 compiler option without changing the source but failed. What would be the way for a minimal change in source using compiler options?

Thank you,

Yair

0 Kudos
Steven_L_Intel1
Employee
856 Views
For the program that you showed, with REAL*4 declarations, there is no way to do this. /real_size:64 changes the size of "default real", which is what you get when you say REAL (with no modifier) or for real constants. It has no effect on declarations (explicit or implicit) that have a size or kind specifier.

If you're going to use IMPLICIT, which I strongly recommend against, then say "IMPLICIT REAL". The better choice is to code using a kind specifier based on a PARAMETER constant that you can then easily change in one place. For example:

module my_kinds
integer, parameter :: MR = SELECTED_REAL_KIND(6) ! REAL(4)
end module my_kinds

program main
use my_kinds
real(MR) :: A,B,C
...

Now all you have to do to switch to double precision is chantge the module to use SELECTED_REAL_KIND(15). You will also need to be careful to use generics and not specific routine names and to consistently use the MR kind for constants (3.4_MR for example.)

In general, you cas't easily take code written for a specific REAL kind (eg. REAL*4) and switch it to use a different kind.
0 Kudos
Reply