For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2005 > new intrinsics









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author new intrinsics
Toby White

2005-02-01, 4:00 pm


While post-F2003 enhancements are being discussed, I thought
I'd add to the confusion by asking if the following proposal
would be thought useful by anyone else, and if so whether it's
the sort of thing that might make it into a F200x standard.

I often find myself wanting to do what I think of as "half a PACK";
that is, I want the positions of the true elements in mask,
condensed down to an array of that length. In F95, this was fairly
cumbersome to write; but with F2003 functions, one can easily
write:

Function PackLoc(mask)
Integer, Allocatable :: PackLoc(:)
Logical :: mask(:)

Integer :: i, j

Allocate(PackLoc(Count(mask)))
j=1

Do i=LBound(mask),UBound(mask)
If (mask(i)) Then
PackLoc(j)=i
j=j+1
EndIf
EndDo
End Function PackLoc

Clearly that's not the most efficient implementation for large arrays,
but it shows what I mean. It would be nice to have this as a standard
intrinsic in order that a) I don't have to put it in every code I write
and b) the compiler would probably be better at implementing it
efficiently than I would.

I'm not quite sure if or how it ought to generalize to multi-dimensional
arrays, but I haven't had much need of that.

Toby

--
Dr. Toby White
Dept. of Earth Sciences, Downing Street, Cambridge CB2 3EQ. UK
Dick Hendrickson

2005-02-01, 4:00 pm



Toby White wrote:
> While post-F2003 enhancements are being discussed, I thought
> I'd add to the confusion by asking if the following proposal
> would be thought useful by anyone else, and if so whether it's
> the sort of thing that might make it into a F200x standard.
>
> I often find myself wanting to do what I think of as "half a PACK";
> that is, I want the positions of the true elements in mask,
> condensed down to an array of that length. In F95, this was fairly
> cumbersome to write; but with F2003 functions, one can easily
> write:
>
> Function PackLoc(mask)
> Integer, Allocatable :: PackLoc(:)
> Logical :: mask(:)
>
> Integer :: i, j
>
> Allocate(PackLoc(Count(mask)))
> j=1
>
> Do i=LBound(mask),UBound(mask)
> If (mask(i)) Then
> PackLoc(j)=i
> j=j+1
> EndIf
> EndDo
> End Function PackLoc


I haven't thought about this much (and haven't tried it
either), bout wouldn't something like

PackLoc = Pack ([ (I, I = LBound(mask),UBound(mask))], mask)

do what you want? Create the list of integers and select
the ones you want. Let automatic allocation Do The Right
Thing for the left hand side.

It's probably not very efficient for large arrays, especialy
if the integer array won't fit in the cache. But,
one-liners are always neat.

I'm not so sure that your efficiency worries are valid.
Compilers are awful good at optimizing DO loops and modern
computers have pretty good branch prediction logic. If
it were an intrinsic function, there's no guarantee that
the underlying code would be any better than straightforward
Fortran.

Dick Hendrickson

>
> Clearly that's not the most efficient implementation for large arrays,
> but it shows what I mean. It would be nice to have this as a standard
> intrinsic in order that a) I don't have to put it in every code I write
> and b) the compiler would probably be better at implementing it
> efficiently than I would.
>
> I'm not quite sure if or how it ought to generalize to multi-dimensional
> arrays, but I haven't had much need of that.
>
> Toby
>


Toby White

2005-02-01, 4:00 pm

Dick Hendrickson <dick.hendrickson@att.net> writes:

> I haven't thought about this much (and haven't tried it
> either), but wouldn't something like
>
> PackLoc = Pack ([ (I, I = LBound(mask),UBound(mask))], mask)
>
> do what you want? Create the list of integers and select
> the ones you want. Let automatic allocation Do The Right
> Thing for the left hand side.


So it would. That's handy. I knew someone would immediately point
out an easy way to do it! (with [ -> (/ for f95, presumably).
But, as you say, not efficient for large arrays.

> I'm not so sure that your efficiency worries are valid.
> Compilers are awful good at optimizing DO loops and modern
> computers have pretty good branch prediction logic. If
> it were an intrinsic function, there's no guarantee that
> the underlying code would be any better than straightforward
> Fortran.


My concern was that for a large array, you
probably wouldn't want to iterate twice across the whole
array (once for the Count, once for the assignment); you'd
want to do it a chunk at a time, reallocating when you overflowed;
so the putative implementation would want to look something like

If (Size(array) < CACHE_SIZE))
... naive implementation
Else
... more complicated implementation(s) that rely
on knowing the machine architecture fairly well
EndIf

and I'd rather not try to optimize the second branch on several
different machines when I can get a compiler vendor to do it
for me :-) I don't *think* it likely that a compiler would guess
that it could transform the code like that - but maybe I'm
underestimating modern compilers.

Toby

--
Dr. Toby White
Dept. of Earth Sciences, Downing Street, Cambridge CB2 3EQ. UK
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com