Curious if there are either existing tools or best practices for permuting the axes of n-dimensional arrays like with permute in pytorch or numpy’s transpose. I’d like to be able to do e.g x.transpose(3,1,2)
to move axes around.
Related, I recently discovered the einops package in python that lets you specify tensor permutations and reshaping, but I don’t think there is a Fortran equivalent? It’s quite useful but as I’m finding out it’s a pain to convert code that uses it to code that doesn’t use it.
Maybe reshape
with the optional order
argument could do what you need?
reshape(source, shape[, pad, order)]
The NVIDIA compiler can bind the reshape
operations to the cuTENSOR library as explained here.
There was also a nice talk about tensor contractions (which include transposes) given by Patrick Seewald at FortranCon 2020. See GitHub - pseewald/fortran-einsum-example: A generic implementation of tensor einsum in Fortran.
Excellent thank you! I was looking at transpose
which only works for 2D, i didn’t realize reshape
could do this.
That einsum link looks very interesting too. I’m trying to port some python code that makes heavy use of einops and einsum and it’s been slow going moving them to more standard operations, which I want to do as an exercise anyway but I’m happy to know this is supported, especially if it’s not too much trouble to eventually move to a gpu.
I think it would be nice if we had einsum
in Fortran, similar to NumPy, TensorFlow or PyTorch:
real, allocatable :: A(:,:,:)
allocate(a(3,4,2)
! now
associate(ord => [2,1,3], s => shape(a))
A = reshape(A,s(ord),order=ord)
end associate
! if einsum were available
A = einsum('ijk->jik',A)