PARALLEL.RU

Дискуссионный клуб по параллельным вычислениям
Текущее время: 21 ноя 17 17:10

Часовой пояс: UTC + 4 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: 27 мар 08 16:59 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
Помогите выйти из параллельного цикла....
пишу:
Код:
!$OMP PARALLEL DO
Loop_pq: do m=0,M_max,1
...
...
      if ( zabs(ye_circ_out-Y_old)<errrel )  exit Loop_pq
...
...
end do  Loop_pq
$OMP END PARALLEL DO

Т.е. по достижению необходимой точности можно выходить из цикла, не добивая ряд до конца. Но компилятор говорит:

Error: A RETURN, EXIT or CYCLE statement is not legal in a DO loop associated with a parallel directive.

Пробовал писать goto, делать кусок с ифом !$OMP CRITICAL и ставить !$OMP BARRIER - получается таже ошибка... Как выйти?

если убрать имя цикла,то получается другая ошибка:

Код:
1>Compiling with Intel(R) Fortran Compiler 10.1.019 [IA-32]...
1>ye_circ.f90
1>fortcom: Fatal: There has been an internal compiler error (C0000005).


Компилируется это все из-под MSVS2005 с параметрами:
/nologo /O3 /Og /QaxT /QxT /Qparallel /Qpar_threshold:2 /Qopenmp /module:"Release\\" /object:"Release\\" /libs:dll /threads /c /Qfpp

Пробовал версию IFC 10.1.014 - тот же результат... В программе использую IMSL 6.0
Можно как-нибудь это вылечить? Спасибо! :-)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 27 мар 08 18:11 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Либо сделать цикл последовательным, либо не выходить из него досрочно. Иначе никак.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 27 мар 08 18:19 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
уууу. :(( спасибо за ответ...
это плохо...значит наверно придется думать как запараллелить внутренность цикла...
больше совсем-совсем ничего нету, имно как-то это не совсем логично, что нельзя досрочно выйти из цикла даже при наличии !$OMP BARRIER...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 27 мар 08 20:39 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Если заранее известно, на какой итерации это надо сделать, то можно просто уменьшить границу цикла. А если это становится известно где-то по дороге в цикле, то такой цикл просто нельзя параллелить, это некорректно работать будет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 28 мар 08 6:32 
Не в сети

Зарегистрирован: 12 янв 06 11:26
Сообщения: 98
Откуда: Хабаровск, ВЦ ДВО РАН
Предположу, что может помочь вместо exit Loop_pq поставить m=M_max+1


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 28 мар 08 10:50 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Стандарты Фортран-90 и ниже запрещают изменять значение переменной цикла во время работы цикла. Так что если даже компилятор и не ругнется, результат будет непредсказуемым, что еще больше усугубится в случае параллельного цикла.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 31 мар 08 17:42 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
Спасибо за добрые слова. :-)
подумав немного переписал кусочек с циклом.
Хочу сделать выход из параллельно цикла при условии, что
m>M_max и
zabs(ye_circ_out-Y_old) > errrel
Это цирк какой-то...:)
пишу...

Код:
USE OMP_LIB
INTEGER THREADS, M_up/0/
     ye_circ_out = 10000.0d0
     Y_old          = 0.0
     call OMP_SET_NUM_THREADS(2)
     THREADS = OMP_GET_NUM_THREADS( )

do while (((zabs(ye_circ_out-Y_old)) > errrel).OR.(M_up<=M_max))
    Y_old=ye_circ_out
    M_up = M_up + THREADS
!$OMP PARALLEL
!$OMP DO SCHEDULE (STATIC, THREADS)
do m=M_up-THREADS,M_up,1
....
ЦЫКЛ ...чего-то считаем...
....
end do
!$OMP END PARALLEL


компилируем......
иии....
Код:
1>Compiling with Intel(R) Fortran Compiler 10.1.019 [IA-32]...
1>ye_circ.f90
1>fortcom: Fatal: There has been an internal compiler error (C0000005).
1>compilation aborted for C:\_user\Visual Studio 2005\Projects\ye_circ\ye_circ\ye_circ.f90 (code 1)
1>


неизменный результат...
неглючит только если отключить OpenMP, но кому оно тогда надо...
как бы вывести.... :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 1 апр 08 8:42 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Тут могу только посоветовать попробовать какой другой компилятор или другую версию. Ибо Internal Compiler Error - это ошибка в самом компиляторе, и ее обойти можно только наугад. Ну или посикав в соотвествующих ресурсах производителя компилятора (или спросив его поддержку).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 1 апр 08 14:15 
Не в сети

Зарегистрирован: 11 дек 02 19:37
Сообщения: 869
Откуда: НИВЦ МГУ
А "END DO" присутствует?

Кроме того, меня несколько удивила конструкция
Код:
!$OMP DO SCHEDULE (STATIC, THREADS)
do m=M_up-THREADS,M_up,1


Т.к. первая нить ВСЕГДА выполняет все итерации. Вы уверены, что именно этого хотели?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 1 апр 08 14:41 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
Serg_Zhum писал(а):
А "END DO" присутствует?

Да, конечно, пропустил, когда постил..:
Код:
    end do
!$OMP END PARALLEL
end do

так выглядит конец.

Serg_Zhum писал(а):
Кроме того, меня несколько удивила конструкция
Код:
!$OMP DO SCHEDULE (STATIC, THREADS)
do m=M_up-THREADS,M_up,1


Т.к. первая нить ВСЕГДА выполняет все итерации. Вы уверены, что именно этого хотели?


Эээ, вот цитата из местной статьи:
Цитата:
Параллельные циклы
DO ... [ENDDO]
Определяет параллельный цикл.

Клауза SCHEDULE определяет способ распределения итераций по нитям:
STATIC,m - статически, блоками по m итераций

моя переменная THREADS = тому числу, которое я установил выше call OMP_SET_NUM_THREADS(2), т.е. может быть несколько нерационально написано, но имно правильно, что должны быть 2 нити как раз на 2 итерации в цикле...
Я просто пока больше никакого способа реализации досрочного выхода из параллельного цикла не придумал... вот маюсь... :-)

то coctic: пытаюсь общаться с intel-ом, с миру по нитке....


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 1 апр 08 16:10 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Pir0texnik писал(а):
Цитата:
Параллельные циклы
DO ... [ENDDO]
Определяет параллельный цикл.

Клауза SCHEDULE определяет способ распределения итераций по нитям:
STATIC,m - статически, блоками по m итераций

моя переменная THREADS = тому числу, которое я установил выше call OMP_SET_NUM_THREADS(2), т.е. может быть несколько нерационально написано, но имно правильно, что должны быть 2 нити как раз на 2 итерации в цикле...


Ну все правильно. На первую нить распрделеится THREADS нитей, а на остальные просто нечего будет распределять.

Цитата:
Я просто пока больше никакого способа реализации досрочного выхода из параллельного цикла не придумал... вот маюсь... :-)

Не туда думаете. Если Вам нужен досрочный выход из параллельного цикла, то что-то в корне неверно. Параллельный цикл на то и параллельный, что все его итерации можно исполнять независимо. А если их можно исполнять независимо, то и их количество известно заранее, и никаких досрочных выходов не нужно. А если они не независимы, то цикл нельзя исполнять в параллельном режиме.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 1 апр 08 17:04 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
coctic писал(а):
Ну все правильно. На первую нить распрделеится THREADS нитей, а на остальные просто нечего будет распределять.

эээ, так мне ж всего-то надо, что бы было 2 потока... 2 ядра - два потока... В диспетчере задач идет загрузка 100%... Или я чего-то не понимаю?

Цитата:
Я просто пока больше никакого способа реализации досрочного выхода из параллельного цикла не придумал... вот маюсь... :-)

Не туда думаете. Если Вам нужен досрочный выход из параллельного цикла, то что-то в корне неверно. Параллельный цикл на то и параллельный, что все его итерации можно исполнять независимо. А если их можно исполнять независимо, то и их количество известно заранее, и никаких досрочных выходов не нужно. А если они не независимы, то цикл нельзя исполнять в параллельном режиме.[/quote]

Так, а как же тогда ряды-то считать?! В один поток?! неее.....
имно совсем не факт, что "Параллельный цикл на то и параллельный, что все его итерации можно исполнять независимо." Да итерации независимы, но с какого-то момента больше их считать не нужно только и всего.
в общем для себя я это решил сделать таки макаром:
Код:
     
M_up =0
THREADS = OMP_GET_NUM_PROCS( )
     call OMP_SET_NUM_THREADS(THREADS)
do while ((err > errrel).AND.(M_up<=M_max))
   M_up = M_up + THREADS   
!$OMP PARALLEL default(shared) PRIVATE(aa,bb,m)
!$OMP DO SCHEDULE (STATIC, 2)
do m=M_up-THREADS,M_up,1

цикл будет крутиться в столько потоков - сколько ядер пока либо точность не достигнется, либо кол-во итераций не перевалит за предел.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 3 апр 08 8:38 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Pir0texnik писал(а):
эээ, так мне ж всего-то надо, что бы было 2 потока... 2 ядра - два потока... В диспетчере задач идет загрузка 100%... Или я чего-то не понимаю?
цикл будет крутиться в столько потоков - сколько ядер пока либо точность не достигнется, либо кол-во итераций не перевалит за предел.

То число, что после STATIC - это не во сколько потоков надо крутить цикл, а сколько итераций надо за один раз распределять на один поток. Если итераций много, а потоков 2, то для равномерной загрузки подойдет любое число от 1 до (число итераций/число потоков). Естественно, наклдадные расходы будут различаться.

Pir0texnik писал(а):
Так, а как же тогда ряды-то считать?! В один поток?! неее.....

А как Вы сумму этого ряда считате? S = S + a[i]? Если так, то такой цикл нельзя делать параллельным - будет получаться неправильный результат. Тогда нужно менять алгоритм, и переходить к чему-то вроде схемы сдваивания или чему-то подобному.
Или что подразумевается под "считать ряды"?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 3 апр 08 16:53 
Не в сети

Зарегистрирован: 27 мар 08 16:39
Сообщения: 11
coctic писал(а):
А как Вы сумму этого ряда считате? S = S + a[i]? Если так, то такой цикл нельзя делать параллельным - будет получаться неправильный результат.

что имеется в виду под a[i]? нечто (функция) зависящее он индекса цикла, эл-т массива? почему будет неправильный результат?

coctic писал(а):
То число, что после STATIC - это не во сколько потоков надо крутить цикл, а сколько итераций надо за один раз распределять на один поток. Если итераций много, а потоков 2, то для равномерной загрузки подойдет любое число от 1 до (число итераций/число потоков). Естественно, наклдадные расходы будут различаться.

эээ, я понял, что я недопонял смысл SHEDULE, но.. почему же тогда у меня загрузка 100%... В цикле всегда 2 итерации, всего два потока и на поток в соответствии с ней я кидал получается как раз эти 2 итерации... Вторая нить по идее должна была стоять и загрузка была б 50%...

coctic писал(а):
Или что подразумевается под "считать ряды"?


вот, например, самое простое: посчитать число "e" с какой-то наперед заданной относительной ошибой...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 4 апр 08 8:58 
Не в сети

Зарегистрирован: 5 мар 05 14:01
Сообщения: 74
Pir0texnik писал(а):
что имеется в виду под a[i]? нечто (функция) зависящее он индекса цикла, эл-т массива? почему будет неправильный результат?

Да, под a[i] полразумевается либо элемент массива, либо какая-то функция, вычисляемая на i-й итерации.
А неправильно вот почему: s=s+a[i] - операция неатомарная. Соответственно может случиться, что обе нити одновременносанчала прочитают значение S, потом прибавит каждая свое значение a[i], потом обе запишут результат назад в S. Соответственно, один из результатов не будет записан (на его место ляжет другой), и одно из слагаемых потеряется.
Как вариант, можно обвесить накопление суммы $OMP CRITICAL, чтобы избежать такого эффекта. Но надо смотреть, а насколько тяжелые там остальные вычисления, и вообще имеет ли смысл так делать.
Pir0texnik писал(а):
эээ, я понял, что я недопонял смысл SHEDULE, но.. почему же тогда у меня загрузка 100%... В цикле всегда 2 итерации, всего два потока и на поток в соответствии с ней я кидал получается как раз эти 2 итерации... Вторая нить по идее должна была стоять и загрузка была б 50%...

Ну, во-первых, компилятор может считать себя умнее программиста и соптимизировать. Во-вторых, это могут быть глюки того, что показывает эти самые проценты. В третьих, дополнительная нить может быть занята под какие-то организационные нужды. Да мало ли чего можно придумать.
coctic писал(а):
вот, например, самое простое: посчитать число "e" с какой-то наперед заданной относительной ошибой...

Ну я бы делал примерно так: параллельно считаем некое фиксированное число итераций (не забываем про критическую секцию для накопления суммы), потом делаем еще один шаг последовательно для определения точности, если точность недостаточная - снова идем на параллельную часть.
Или же параллельно в массиве насчитывать сколько-то членов ряда, потом их последовательно суммировать, чтобы избежать накладных расходов на критическую секцию, проверять точность, ну и далее по циклу.
Можно и еще придумать.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB