Допустим, у нас есть несколько различных смежных массивов
real :: a1(2),a2(2),a3(2)
real :: b1(2,2), b2(2,2),b3(2,2)
real :: c1(3,3,3), c2(3,3,3),c3(3,3,3)
и подпрограмма
subroutine mtpy(x,y,z)
real,contiguous, intent(in) :: x(:), y(:)
real, intent(out) :: z(size(x))
z=x*y
end subroutine mtpy
Как использовать mtpy в следующих сериях вызовов:
call mtpy(a1,a2,a3)
call mtpy(b1,b2,b3)
call mtpy(c1,c2,c3)
Очевидно, это приведет к ошибкам компилятора, поскольку форма фактических и фиктивных аргументов не совпадает.В подобных случаях я обычно объявлял несколько конкретных процедур, каждая из которых обрабатывает определенную форму, а затем оборачивал их все с помощью интерфейса.Однако это довольно утомительно (представьте, что у вас огромное количество простых элементарных функций и чистых процедур, которые обрабатывают многомерные массивы (до трех измерений) как одномерные массивы, а затем предоставляют экземпляры, такие как sub_1d, sub_2d, sub_3d, .. для каждого изони, несмотря на то, что все они фактически выполняют одну и ту же работу).
Одним из частичных решений является, я полагаю, использование RESHAPE
call mtpy(reshape(b1,[4]),reshape(b2,[4]),bb)
, но могу ли я быть уверен, что компилятор (в основном меня интересует gfortran и ifort) не начнет создавать1d временных, чтобы держать измененные массивы b1 и b2?
Теперь я также знаю, что можно объявить указатель массива, например
real, pointer, contiguous :: p1(:),p2(:),p3(:)
, и сделать следующее присвоение указателя, например
p1(1:size(c1))=>c1
Однако этоНедостаток подхода заключается в том, что мне нужно объявить исходные массивы в качестве целей.Разве это не повлияет на оптимизацию, которую сможет выполнить компилятор?
Еще одно решение, я полагаю, заключается в использовании массивов предполагаемого размера, но я заметил, что Metcalf и др. Называют их использование«устарел» и, опять же, я не уверен насчет влияния на omptimisations.
Итак, есть ли простой способ обработки многомерного массива Фортрана как одного массива измерений (в подпрограмме или функции) что не накладывает ненужных предположений (таких как TARGET) на этот массив?Если бы я мог использовать RESHAPE, не опасаясь создания временных (я имею дело только с непрерывными массивами), я бы пошел на это.Есть предложения?