I think the only way (I wish I was wrong) to obtain a run-time equivalence is using Cray pointers. It's relatively easy for 3-d and 1-d arrays:
REAL, ALLOCATABLE:: a3(:,:,:) REAL:: a1(*); POINTER(pa1, a1) ... ALLOCATE(a3(i,j,k)) pa1=LOC(a3)
However, your exact sample for 3-d and 2-d arrays is still tougher to realize;
if the leading dimension of both is known at compile-time, you might write:
REAL:: a2(5000,*); POINTER(pa2, a2)
. Otherwise... I don't know.
Perhaps the cleanest way is to simply use 2-d array and to access it using varying second index when you need to "emulate" 3-d, i.e (a2(i, iStride*j+k)) where