Отворете MP, ако OpenMP:друго

Проблем: Имам някакъв код, който аз и няколко други пишехме, взех кода и го накарах да използва mpi и openmp със страхотни резултати (помага, че го изпълнявам на Blue Gene/Q).

Едно нещо, на което не съм фен, е, че сега не мога да компилирам кода без директивата -openmp, защото, за да постигна необходимото ускоряване, използвах редуциращи променливи. Пример:

!$OMP parallel do schedule(DYNAMIC, 4) reduction(min:min_val)
....
    min_val = some_expression(i)
....
!$OMP end parallel do
result = sqrt(min_val)

Търся нещо като:

!$OMP if OMP:
!$OMP min_val = some_expression(i)
!$OMP else:
if ( min_val .gt. some_expression(i) ) min_val = some_expression(i)
!$OMP end else

Някой знае ли нещо подобно? Забележете, че без -openmp редовете !$OMP се игнорират и кодът работи нормално с правилния, ъъъъъ щото, отговор.

Благодаря,

(Да, това е FORTRAN код, но е почти идентичен с C и C++)


person ShaBANG    schedule 14.01.2014    source източник
comment
Все пак не бих използвал тагове C и C++, така или иначе ще накарате хората да го използват от тага openmp.   -  person Vladimir F    schedule 15.01.2014
comment
Работата с таговете е, че има тривиално решение в C и C++, използващо нормалния препроцесор и _Pragma. Не съм сигурен дали съществува подобно решение за Fortran.   -  person Konrad Rudolph    schedule 15.01.2014
comment
@KonradRudolph Доста обичайна практика е да се използват предварително обработени изходни файлове на FORTRAN (обикновено разширението им започва с главно 'F' вместо с малко). Следователно решението може да бъде толкова тривиално, колкото в C.   -  person Massimiliano    schedule 15.01.2014
comment
@Massimiliano Не се съмнявам в това, просто казвам, че освен ако Fortran няма концептуално много подобен препроцесор на C, решението е малко вероятно да бъде прехвърлимо и че c и c++ не бяха полезни.   -  person Konrad Rudolph    schedule 15.01.2014


Отговори (2)


Ако желаете да използвате предварително обработен изходен файл на FORTRAN, винаги можете да разчитате на макроса _OPENMP, който ще бъде дефиниран, когато използвате OpenMP. Най-простият пример е:

program pippo

#ifdef _OPENMP
print *, "OpenMP program"
#else
print *, "Non-OpenMP program"
#endif

end program pippo

Компилиран с:

gfortran -fopenmp main.F90

програмата ще даде следния резултат:

OpenMP program

Ако не желаете да използвате предварително обработени изходни файлове, тогава можете да зададете променлива с помощта на FORTRAN условна компилация sentinel:

program pippo

  implicit none

  logical :: use_openmp = .false.

  !$ use_openmp = .true.
  !$ print *, "OpenMP program"
  if( .not. use_openmp) then
     print *, "Non-OpenMP program"
  end if

end program pippo
person Massimiliano    schedule 14.01.2014

На точния ти въпрос:

!$ whatever_statement

ще използва този оператор само когато е компилиран с OpenMP.


В противен случай, във вашия конкретен случай, не можете ли просто да използвате:

!$OMP parallel do schedule(DYNAMIC, 4) reduction(min:min_val)
....
    min_val = min(min_val, some_expression(i))
....
!$OMP end parallel do

result = sqrt(min_val)

?

Използвам това нормално със и без -openmp доста често.

person Vladimir F    schedule 14.01.2014
comment
А, това отговаря на част от въпроса ми за изпълнение на код само ако е компилирана openmp програма. Все още е любопитно в по-общ случай да не се изпълнява поведението по подразбиране. (Да, вашият отговор все пак отговаря чудесно на този конкретен случай) - person ShaBANG; 15.01.2014