Consider the following subroutine, which calculates a sparse matrix product in a Poisson equation solver.
SUBROUTINE mut_A_sparse(n, w, v)
INTEGER, INTENT(IN) :: n
REAL, INTENT(IN) :: w(n*n)
REAL, INTENT(OUT) :: v(n*n)
v = -EOSHIFT(w, -n) - EOSHIFT(w, -1) + 4*w - EOSHIFT(w, 1) - EOSHIFT(w, n)
v((n + 1):n*n:n) = v((n + 1):n*n:n) + w(n:(n*n - 1):n)
v(n:(n*n - 1):n) = v(n:(n*n - 1):n) + w((n + 1):n*n:n)
END SUBROUTINE mut_A_sparse
I'm not sure what this compiles to. Will the compiler store the intermediate result of -EOSHIFT(w, -n)
to some temporary array, or calculate it on the fly for each index of v
? The TA told me it is the latter case, but as far as I know, EOSHIFT
is not ELEMENTAL
, so how does the compiler know calculating it on the fly will not cause accidentally quadratic complexity?
Additionally, what about array slices? I wonder if the following creates an array temporary. I am asking because passing sliced arrays to functions/procedures will induce a copy during argument binding, but what about primitive operators like + - * /
?
z(::2) = a(::2) + b(::2) + c(::2)
I guess I should read the assembly, but the assembly output is a complete mess beyond my comprehension.