2014-02-08 2 views
2

Мне нужно отладить программу, которая включает в себя forall блоков. Внутри них находятся подпрограммы или функции pure. Для того, чтобы временно отключить pure предикат я использую C препроцессор, как в следующий вопрос, поставленный мною:Gfortran: Обработать все блоки, как и блоки.

Gfortran: Treat pure functions as normal functions for debugging purposes?

Проблема теперь в том, что если подпрограммы или функции внутри forall блока не pure I получить компиляцию ошибок. Есть ли возможность лечения этих ошибок

Error: Reference to non-PURE function 'pvkp' at (1) inside a FORALL block 

только как предупреждения или есть, может быть легко возможность использовать C препроцессор для поворота

forall (i=1:n) 
    ... 
end forall 

в

do i=1,n 
    ... 
end do 

Любые идеи оценили!

+3

Учитывая, что 'forall' [не делает то, что он должен был делать] (http://stackoverflow.com/questions/4122099/do-fortran-95-constructs-such-as-where-forall-and -spread-general-result-in-fa/4141572 # 4141572) (а также [этот] (http://stackoverflow.com/questions/8602596/fortran-forall-restrictions)), почему бы просто не заменить все 'forall 'с' do' в любом случае? –

+0

Я полностью понимаю концепцию 'forall'. Я считаю, что блоки 'forall' фактически улучшат скорость моей программы (после ее отладки). – Wauzl

+0

Надеюсь, вы планируете * тестировать * свое утверждение и не бегать с ним исключительно на веру. В любом случае, вы можете проверить выход ассемблера, чтобы убедиться, что он действительно использует 'forall', а не просто преобразовывает его в' do ... enddo'. –

ответ

2

Одним из упрощений является использование цикла do concurrent вместо блока forall. Это уменьшает количество связанных изменений, необходимых в коде: нужно только изменить спецификацию цикла, а не изменить end forall на end do.

подход не гордиться, используя cpp, и подходит только для простых случаев:

#ifdef DEBUG 
#define conloop(var, lower, upper) do var=lower, upper 
#else 
#define conloop(var, lower, upper) do concurrent (var=lower:upper) 
#endif 

    conloop(i,1,n) ! Either a DO or DO CONCURRENT depending on DEBUG 
    ... 
    end do 
end 

выше действительно имеют очевидное расширение для использования forall конструкции (с дополнительной #define для концовки) если это действительно то, что вы хотите. С другой стороны, хотя и более утомительным производить, используя такие вещи, как

#ifdef DEBUG 
do i=1,n 
#else 
forall (i=1:n) 
#endif 
    ... 
#ifdef DEBUG 
end do 
#else 
end forall 
#end 

Это ужасно, но я полагаю, что это верно для всех подходов до процессора. Это позволяет более сложные маски и более локализован.

+0

И, как говорит Кайл Канос, можно получить читаемый код, просто придерживаясь 'do', за исключением редких случаев, когда компилятор не делает хорошую работу. – francescalus

+0

В итоге я определил 'conloop' и' endconloop'. – Wauzl

Смежные вопросы