Re: DPROD issues
- From: "James Van Buskirk" <not_valid@xxxxxxxxxxx>
- Date: Mon, 19 May 2008 19:56:20 -0600
"Richard Maine" <nospam@xxxxxxxxxxxxx> wrote in message
news:1ih4ooc.19sxqj61s8hr1sN%nospam@xxxxxxxxxxxxxxxx
The standard doesn't talk about compiler switches, so one can't really
say what is "supposed" to happen. In fact, a switch like that typically
makes a compiler nonstandard in that mode. That's because default real
and default integer do not take the same amount of memory as required by
the compiler. I have also seen multiple variations in the fine points of
implementation of such switches; treatment of specific intrinsics is one
such fine point that I've seen variations in.
In ifort we can make default INTEGER and LOGICAL sizes be 64 bits via
the switch /integer_size:64, as well as making default real size 64 bits
(/real_size:64) and double precision size 128 bits (/double_size:128).
This satisfies storage association rules.
That being said, to the extent that such a switch makes an 8-byte real
be the default real, then that 8-byte real *IS* single precision in such
a mode. "Single precision" doesn't inherently mean 32 bits. It appears
above as if you are using it with that meaning, which I find quite
confusing in context. Thus, yes, I'd expect appropriate versions of all
the specific intrinsics (pretty much all of them; this isn't specific to
DPROD). I'd also expect double precision to then be 16 bytes.
I was trying to avoid using terms like REAL*4 and REAL*8 but clarity
was lost in the attempt.
But I have seen plenty of implementations where neither of those things
happen. In some cases, such switch does little more than have the effect
of a preprocessor that changes all kindless real declarations to double
precision. In other cases, when used in conjunction with a simillar
option for integers, the compiler is pretty much still standard
conforming, with all that implies.
Such variation (including the variant of compilers that don't support
such a thing at all) is why I discourage the use of such options. There
are times when such an option can be handy for a quick fix when porting
3rd-party code. I've used them myself. (Discouragement is not the same
thing as an absolute ban). But I would not consider writing new code
that depended on such an option, and I also keep in mind the
nonportability implied by the variation in details of implementation.
But the specific function names don't seem to get changed around.
Here is an example with ifort:
C:\gfortran\clf\dprod_test>type dprod_test.f90
program test
implicit none
intrinsic dprod
intrinsic sin
real x
real y
x = 3.14
y = 2.86
call sub1a(x,sin)
call sub2a(x,y,dprod)
call sub1b(x,sin)
call sub2b(x,y,dprod)
end program test
subroutine sub1a(x,fun)
implicit none
integer, parameter :: s = kind(1.0)
real(s) x
real(s) fun
write(*,*) kind(x), kind(fun(x))
write(*,*) x, fun(x)
end subroutine sub1a
subroutine sub2a(x,y,fun)
implicit none
integer, parameter :: s = kind(1.0)
integer, parameter :: d = kind(1.0d0)
real(s) x
real(s) y
real(d) fun
write(*,*) kind(x), kind(y), kind(fun(x,y))
write(*,*) x, y, fun(x,y)
end subroutine sub2a
subroutine sub1b(x,fun)
implicit none
integer, parameter :: s = kind(1.0)
integer, parameter :: p = selected_real_kind(6,30)
real(s) x
real(p) a
real(p) fun
a = x
write(*,*) kind(a), kind(fun(a))
write(*,*) a, fun(a)
end subroutine sub1b
subroutine sub2b(x,y,fun)
implicit none
integer, parameter :: s = kind(1.0)
integer, parameter :: d = kind(1.0d0)
integer, parameter :: p = selected_real_kind(6,30)
integer, parameter :: q = selected_real_kind(15,300)
real(s) x
real(s) y
real(p) a
real(p) b
real(q) fun
a = x
b = y
write(*,*) kind(a), kind(b), kind(fun(a,b))
write(*,*) a, b, fun(a,b)
end subroutine sub2b
C:\gfortran\clf\dprod_test>ifort /integer_size:64 /real_size:64
/double_size:128
dprod_test.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:dprod_test.exe
-subsystem:console
dprod_test.obj
C:\gfortran\clf\dprod_test>dprod_test
8 8
3.14000000000000 5.166810852704215E-315
8 8 16
3.14000000000000 2.86000000000000
5.368184143533821386815131334324100E-4940
4 4
3.140000 1.5925480E-03
4 4 8
3.140000 2.860000 8.98039997062682
You can see that the answers are garbage when default real inputs
are used for the function passed when it's SIN or DPROD, but when
REAL*4 inputs are used and the output of SIN interpreted as REAL*4
and that of DPROD as REAL*8, we get quite sensible results. To
maintain standard conformance, perhaps ifort should be remapping
the names and passing DSIN and DDPROD (the latter I just now made
up). Intel's docs for DPROD say that it has no generic function
associated with it, but also give an example of a generic
invocation. :)
Intel's docs for /real_size say:
"These compiler options can affect the result type of intrinsic
procedures, such as CMPLX, FLOAT, REAL, SNGL, and AIMAG, which
normally produce single-precision REAL or COMPLEX results. To prevent
this effect, you must explicitly declare the kind type for arguments
of such intrinsic procedures.
For example, if real_size 64 is specified, the CMPLX intrinsic will
produce a result of type DOUBLE COMPLEX (COMPLEX(KIND=8)). To prevent
this, you must explicitly declare any real argument to be
REAL(KIND=4), and any complex argument to be COMPLEX(KIND=4)."
Which in itself is rather amusing, the CMPLX intrinsic not relying
on the KINDs of arguments X and Y, but exclusively on the value
of the KIND argument.
OK, I get your point about switches to change the kind of default
REAL variables in that we seem to be encountering gaps in
documentation and possibly in implementation. Also it supports your
dislike for specific function names for the intrinsics (not mentioned
previously in this thread) in that when their required purpose is
invoked, there doesn't seem to be compiler support in some of the
difficult cases.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
.
- References:
- DPROD issues
- From: James Van Buskirk
- Re: DPROD issues
- From: Richard Maine
- DPROD issues
- Prev by Date: Re: encoding="utf-8" and formatted direct access
- Next by Date: Re: encoding="utf-8" and formatted direct access
- Previous by thread: Re: DPROD issues
- Next by thread: Creating .so file to call from IDL
- Index(es):
Relevant Pages
|
|