используя пользовательскую функцию внутри цикла - PullRequest
0 голосов
/ 27 марта 2020

У меня есть pde, чтобы решить. Для оптимизации я использую циклы Форалла и внутри l oop переменные изменяются с помощью определенной пользователем функции следующим образом.

forall(i=2:n-1,j=2:n-1, w(i,j).gt.wmax/1000)
    k3(i,j)=w(i,j)+h*k(x(i),t)
end forall

Здесь k (x, t) внешне определенная функция, которую я определил ранее.

Приходит ошибка:

 Reference to impure function ‘k’ at (1) inside a FORALL block

Я использую gfortran. Какое решение, если мне нужна пользовательская функция внутри l oop? Возможно ли это вообще внутри, или мне нужно сделать что-то другое, что также оптимизирует? Если возможно что-то еще, пожалуйста, объясните это тоже.

1 Ответ

2 голосов
/ 27 марта 2020

Проблема в том, что вы ссылаетесь на нечистую функцию с именем k внутри блока FORALL. Чтобы заставить это работать, когда вы пишете свою функцию, вы должны сделать ее чистой и иметь интерфейс в области видимости в точке, которую вы называете в l oop - pure - это утверждение, что функция не будет (среди прочего ) изменить свои аргументы, которые, если бы это произошло, могли заставить параллельную обработку конструкции Форалла давать неправильные ответы. Если бы вы дали полную, минимальную программу, показывающую вашу проблему, я бы показал вам изменения, которые вам нужно внести, но, как и вы, нет, я не могу.

Но на самом деле это , НЕ используйте FORALL. Почти наверняка ваша программа не будет работать быстрее, чем при использовании простого do l oop, и, возможно, медленнее. В то время Форалл казался хорошей идеей, но по ряду причин она на самом деле не сработала - я отмечаю в последнем издании «Современное объяснение Фортрана» Меткалфа, Рейда и Коэна, классическую книгу c о Фортран, они помечают его как устаревший. Вместо этого я бы посмотрел на более современный Do Concurrent или, возможно, лучше всего, научился бы распараллеливать ваш l oop с OpenMP.

...