Подтвердить что ты не робот

MakePSOCKcluster зависает при выигрыше x64 после вызова системы

Я испытываю трудную задачу отладки с makePSOCKcluster из пакета parallel на R x64 в Windows. Это не происходит на R i386 в Windows, ни на любом OSX или Linux. К сожалению, это не происходит последовательно, только изредка и довольно случайным образом.

Что происходит, так это то, что функция makePSOCKcluster отключает и замораживает сеанс R, но только если раньше в сеансе выполнялись вызовы (произвольные) system(). Видео и script ниже иллюстрируют проблему более четко.

Некоторые вещи, которые я пробовал без успеха:

  • Отключить антивирус/брандмауэры.
  • Ожидание пары секунд между вызовами system и makePSOCKcluser.
  • Использование различных системных вызовов.

Как бы я еще сузил это? Здесь видео и script, используемые в видео:

cmd_exists <- function(command){
  iswin <- identical(.Platform$OS.type, "windows"); 
  if(iswin){
    test <- suppressWarnings(try(system(command, intern=TRUE, ignore.stdout=TRUE, ignore.stderr=TRUE, show.output.on.console=FALSE), silent=TRUE));
  } else {
    test <- suppressWarnings(try(system(command, intern=TRUE, ignore.stdout=TRUE, ignore.stderr=TRUE), silent=TRUE));    
  }
  !is(test, "try-error")
}

options(hasgit = cmd_exists("git --version")); 
options(haspandoc = cmd_exists("pandoc --version"));  
options(hastex = cmd_exists("texi2dvi --version"));
cluster <- parallel::makePSOCKcluster(1);
4b9b3361

Ответ 1

makePSOCKCluster или, более общ makeCluster, может зависать по ряду причин при создании так называемых worker процессов, что включает в себя запуск новых сеансов R, используя команду Rscript, которая будет выполнять функцию .slaveRSOCK, который создаст соединение сокета обратно к ведущему, а затем выполнит функцию slaveLoop, где он в конечном итоге выполнит задачи, отправленные им мастером. Wehen что-то пойдет не так, когда вы начинаете какие-либо рабочие процессы, мастер будет висеть во время выполнения socketConnection, ожидая, когда рабочий подключится к нему, даже если этот рабочий, возможно, умер или даже не был успешно создан.

Использование аргумента outfile отлично, потому что оно часто обнаруживает ошибку, из-за которой рабочий процесс умирает и, следовательно, хозяин висит. Но если это ничего не показывает, перейдите в ручной режим. В ручном режиме мастер печатает команду для запуска каждого рабочего вместо выполнения самой команды. Это больше работает, но дает вам полный контроль, и вы можете даже отлаживать работу, если вам нужно.

Вот пример:

> library(parallel)

> cl <- makePSOCKcluster(1, manual=TRUE, outfile='log.txt')
Manually start worker on localhost with
   '/usr/lib/R/bin/Rscript' -e 'parallel:::.slaveRSOCK()' MASTER=localhost
PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE 

Затем откройте новое окно терминала (командную строку или что-то еще) и вставьте в эту команду Rscript. Как только вы его выполнили, makePSOCKcluster должен вернуться, так как мы запросили только одного работника. Конечно, если что-то пойдет не так, оно не вернется, но если вам повезет, вы получите сообщение об ошибке в окне терминала, и у вас будет важный ключ, который, надеюсь, приведет к решению вашей проблемы, Если вам не повезет, команда Rscript также будет висеть, и вам придется погрузиться еще глубже.

Чтобы отладить рабочего, вы не выполняете отображаемую команду Rscript, потому что вам нужен интерактивный сеанс. Вместо этого вы запускаете сеанс R с помощью команды, например:

$R --vanilla --args MASTER = localhost PORT = 10187 OUT = log.txt TIMEOUT = 2592000 МЕТОДЫ = ИСТИНА XDR = ИСТИНА

В этом сеансе R вы можете поместить контрольную точку в функцию .slaveRSOCK, а затем выполнить ее:

> debug(parallel:::.slaveRSOCK)
> parallel:::.slaveRSOCK()

Теперь вы можете начать выполнение кода, возможно, установив контрольные точки в функциях slaveLoop и makeSOCKmaster.