Pierre Hugonnet wrote:
> robin wrote:
> >
> > Pierre Hugonnet wrote:
> >
> > > If you have a little moment, please could you write
> > > for me a library containing the previously described example of "mysum",
> > > with a generic interface, which is portable (assuming 24 digits
> > > precision exists), and which does not use more
> > > memory and CPU than necessary. I'm almost sure that you can
> > > not meet all of these requirements, but let's see...
> >
> > What specifically is the requirement? It's a bit vague now that
> > you've changed the specifications.
> >
> > And is that 24 decimal digits or binary digits? And is that
> > default real?
>
> The specifications are:
> write a function which sums a 1D real array, using an accumulator
> whose precision is large enough (let's say at least twice the precision
> of the *original* array) to reduce round-off problems.
> write several versions for the different possible real kinds.
Now it's several versions?
And now it's the different possible real kinds?
I'm sorry, this is a very rubbery specification. It keeps changing.
> in the calling program I have:
>
> REAL(selected_real_kind(p=6)) :: a6(n)
> REAL(selected_real_kind(p=12)) :: a12(n)
> ...
> s6 = mysum(a6)
> s12 = mysum(a12)
>
>
>
> The library must:
> -be portable (same code on any machine)
> -have a generic interface for the routines
> -be the more possible memory and CPU efficient
Did you not read the summary of this discussion a little while back?
What you just requested contradicts that.
> Let's assume for this example that a kind with at least
> 24 _decimal_ digits precision exist on all target machines.
Let's see what your problem was before: It was
6 digits and 12 digits. Two procedures. Here is what you wrote:
==================start of quote=====================
[ Pierre's] my problem:
INTERFACE mysum
MODULE PROCEDURE mysum_single, mysum_double
END INTERFACE
SUBROUTINE mysum_single(a)
REAL :: a(:)
DOUBLE PRECISION :: accu
accu = 0.0
DO i=1,size(a)
accu = accu + a(i)
END DO
mysum_single = accu
END SUBROUTINE
I want to process data with 6 digits accuracy: in the main I declare
REAL(selected_real_kind(6)) :: array(n)
On a 32bits machine where REAL is 6 digits and DOUBLE 12 digits,
array(:) is REAL:
the routine sums array using a 12 digits accumulator to reduce
round-off problems. This is exactly what I want.
On a 64bits machine where REAL would be 15 digits and DOUBLE 30 digits,
array(:) is still REAL:
the routines sums array using a 30 digits accumulator. I will
give a good result, but 30 digits is much more than I actually
need, leading to wasted CPU time.
The solution could be:
REAL(selected_real_kind(p=12)) :: accu
But now It doesn't work if I process data with 12 digits
accuracy (REAL(selected_real_kind(12)) :: array(n)) :
I really need a 24 digits accumulator.
I'm sorry, but I don't see any solution to this. I you
have one, I'm very interested in...
> > But now I can't define a generic name, since the kinds are
> > identical.
>
> We showed you how to resolve this before.
Not at all: I showed that either you define the libraries with
REAL and DOUBLE PRECISION, then you can have generic interfaces but
little control over the used precisions, or you
define libraries with SELECTED_***, then you have the full control of
the precisions but without generic interfaces.
===============end of quote========================
You need to specify your requirement in a clear, consistent, and
unambiguous form. And in a form that does not contradict what
you wrote before.
> Best regards, and good luck :-)
> | Pierre Hugonnet
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|