Re: Array puzzle



Roy Lewallen wrote:
| I'm a relatively inexperienced Fortran programmer, so please go gently.
|
| While looking through the IVF documentation, I learned that it's
| inefficient to pass an assumed shape or allocatable array to a
| procedure, inside of which it's referenced as a non-deferred shape
| array. Further reading discourages using assumed size arrays. So I
| looked through the very old code I'd been using for some time, and found
| this:

Um, could you please point to that particular piece of documentation?
It doesn't seem quite true, especially regarding allocatable arrays
(which, once allocated, behave quite like "normal" explicit-shape
arrays).

The basic issue at stake is *contiguity* of the array [section] passed
as the real argument for an assumed-size or explicit-shape dummy. If the
section (can be proven to be) discontiguous, a "copy-in/copy-out" to/from
a stack temporary must be generated, causing a performance penalty in most
cases. For assumed-shape dummies, that is [almost] never an issue.

Now, how is that contiguity tested is an issue for itself. I find
a blanket statement of "inefficient" to be too vague and imprecise to
be useful. I don't know the details of current IVF implementation, but
here's few things I learned from experience:

* CVF (even latest versions) had some improvements, but was far from
perfect. The compiler would sometimes blatantly assume that any
array section passed to assumed-size dummy should be subject to copy-in/
copy-out (e.g. I still have a workaround code against stack overflow
for WRITE(42) Bytes(:), where Bytes is a local big allocatable array).
IOW, the "contiguity test" was performed only on compile-time, and
very conservatively.

* IVF was supposed to improve gradually, but I don't know the details.
Supposedly, it employs *run-time* contiguity test, taking the
copy-in/copy-out path IIF the actual array is discontigous. IOW,
it should "do the right thing" even with:

READ (*,*) iSize, iStride
ALLOCATE(Array(iSize))
CALL AssumedSize(Array(1::iStride))

SUBROUTINE AssumedSize(Array)
REAL:: Array(*)

(I'll do the test myself also)

In any case, there is option /check:arg_temp_created which will tell you
whenever in run-time an array temporary argument has been created.
(the last one in "Fortran/Run-time" category if you're using VS IDE).
You can use it to verify code performance.

| The original code had basically explicit shape arrays, passed into
| procedures as automatic or assumed-size arrays. Example:

| It works fine for procedures like P1, where the rank of the array inside
| the procedure is the same as the array in the calling program. The
| problem comes with subroutine P2 in the example above, where the rank of
| the array inside the procedure is different from the rank of the array
| passed in by the calling program. I made INTERFACE blocks, but found
| that the rank in the interface block has to match both the rank inside
| the procedure and the rank of the array in the calling program or
| procedure. If I simply make all the ranks one, an error occurs at the
| B(3,4) statement.
|
| Is there a way to do this, that is, to pass an assumed shape array into
| a procedure where the array inside is a different rank than in the
| calling procedure? Even if the effort of changing things isn't worth the
| trouble, I'd like to learn more about this.

The example you provide is standard-conforming, and uses
"sequence association" between elements of arrays of different rank. The
following works for me on IVF 0.0.029 for Windows:

Program Old
REAL A
INTEGER N
DIMENSION A(30)

INTERFACE
SUBROUTINE P2(B,N)
REAL B
INTEGER N
DIMENSION B(N,*)
END SUBROUTINE
END INTERFACE

A=0
N=6
CALL P2(A,N)
WRITE(*,*) A(:)

END PROGRAM Old
!-----------------
SUBROUTINE P2(B,N)
REAL B
INTEGER N
DIMENSION B(N,*)

B(3,4) = 12
END SUBROUTINE

Such sequence association of arguments is, of course, allowed only
for assumed-size arguments.

--
Jugoslav
___________
www.xeffort.com

Please reply to the newsgroup.
You can find my real e-mail on my home page above.
.



Relevant Pages

  • Part 4 of Short Steps Toward Generic Programming: KIND Genericity
    ... In this part I will again be discussing a feature that has been ... KIND and select the appropriate instance at compile-time in the ... Assumed Rank Arrays ... argument that don't require knowledge of the rank of the array. ...
    (comp.lang.fortran)
  • can this code be improved
    ... // the new array containing unique numbers only ... int number = 0; ... boolean dupLocated=false; ... Rank 1 number is 43 ...
    (comp.lang.java.programmer)
  • Re: Ranking Without Sorting
    ... you have just reinvented the rank sort. ... >> 'rank' array you want. ... >> Doing a 'heap sort', for example, where the heap holds the index into ...
    (comp.programming)
  • Re: Display the max, then the next down, then the next down, etc.
    ... > I just had to fix a couple of cell references. ... > the ROWwill give you the second lowest rank, and so on down the line. ... > The IF/ROW functions will return an array to feed into LARGE. ... The COUNTIF will count only one ...
    (microsoft.public.excel.misc)
  • Re: Ranking Without Sorting
    ... >> contradicted in my first post where I gave an example of how to rank ... > It seems quite clear to me that your 'ranking' array contains the exact ... The ranking array is completed from left to right as it might in a selection sort and unlike insertion sort. ...
    (comp.programming)