(j3.2006) If SIZE(B) > SIZE(A), what part of B does RESHAPE(B, SHAPE(A)) contain, if both A, B are rank N arrays ?
Robert Corbett
robert.corbett
Fri Dec 9 15:13:51 EST 2011
On 12/09/11 10:59, Toon Moene wrote:
> It might sound academic, but this question results from a real (standards'
> violation) problem I solved yesterday.
>
> Somewhere in the 3.5 million lines of code of our weather forecasting code,
> someone had written:
>
> A(:,:,:,:) = B(:,:,:,:)
>
> Looked perfectly OK, has worked for years on various platforms, until I tried
> it at home using gfortran 4.6.2.
>
> BWAM - segmentation fault.
>
> Due to the way the code was set up, I knew both arrays were allocatables, so
> my first thought was: one of them is not allocated. The second thought was: B
> is larger than A. So I added some debug prints that showed that both were
> allocated, and B was larger than A (it's shape differed in one position).
>
> So why did this "work" with the other compilers ? Fortunately, I had seen
> *that* one before; the answer is very simple: The other compilers use the
> shape of the LHS of the assignment to construct their scalarization loops, and
> gfortran uses the shape of the RHS; after all, if you have to scalarize
> expressions, in case of
>
> PRINT*, A+B+C
>
> why wouldn't you re-use that code for assignments ?
>
> So now my task was to change this non-standard code (that was working
> correctly under the assumption that the shape of the LHS determined the
> copying) into something that would work independent of this assumption.
>
> I came up with:
>
> ISHAPE = SHAPE(A) ! ISHAPE is a local 4 element integer array
> A(:,:,:,:)=B(LBOUND(B,1):ISHAPE(1)-LBOUND(B,1)+1,&
> & LBOUND(B,2):ISHAPE(2)-LBOUND(B,2)+1,&
> & LBOUND(B,3):ISHAPE(3)-LBOUND(B,3)+1,&
> & LBOUND(B,4):ISHAPE(4)-LBOUND(B,4)+1)
>
> However, today I thought: I'm just doing RESHAPE's job here - by hand.
>
> Certainly, one must be able to replace the above with the following:
>
> A = RESHAPE(B, SHAPE(A))
>
> Unfortunately, perusing paragraph 13.7.140 of the 2008 Standard (actually the
> 09-007r2 pdf), I can't convince myself that this is the case. It says
> remarkably little about RESHAPEing a larger array to a smaller: "The elements
> of the result ... are those of SOURCE in normal array element order ...".
>
> This doesn't sound like the rank N analogon of the "upper-left hand corner" of
> a rank 2 array, which the above hand-coded assignment certainly is.
>
> Can RESHAPE replace the above convolution ?
The intrinsic RESHAPE does not do what you want. The code you
presented can be simplified. Try
A = B( : SIZE(A, 1) - LBOUND(B, 1) + 1, &
: SIZE(A, 2) - LBOUND(B, 2) + 1, &
: SIZE(A, 3) - LBOUND(B, 3) + 1, &
: SIZE(A, 4) - LBOUND(B, 4) + 1)
OSS Fortran will have an easier time generating code for the
revised version. I suspect other compilers will as well.
Robert Corbett
More information about the J3
mailing list