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

Не может открывать сокеты для параллельного кластера

Я пытаюсь использовать пакет parallel и обнаружил, что makeCluster не удается выполнить. Я проследил, чтобы строка зависала в следующей строке newPSOCKnode:

con <- socketConnection("localhost", port = port, server = TRUE, 
    blocking = TRUE, open = "a+b", timeout = timeout)

Эта команда останавливается (при условии, что время ожидания по умолчанию - большое значение). Мое подозрение заключается в том, что это связано с некоторыми "чрезмерными ИТ-правилами", изложенными на наших рабочих компьютерах, но приветствую любые предложения относительно того, как отслеживать (и исправлять) источник проблемы. Это Windows7-64, "Предприятие", R 3.0.1.

Дополнительная информация: внутри сеанса отладки я установил timeout < - 10, но он все еще зависает - как будто socketConnection оказывается где-то в ловушке, что он даже не может проверить значение тайм-аута.

Здесь мой дамп в том же месте, что и данные Ричи Хлота:

Browse[3]> ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
cmd :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=11017 OUT="| __truncated__
env :  chr "MASTER=localhost PORT=11017 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
machine :  chr "localhost"
manual :  logi FALSE
master :  chr "localhost"
methods :  logi TRUE
options : <environment: 0x000000000ccac6a0> 
outfile :  chr "/dev/null"
port :  int 11017
rank :  int 1
renice :  int NA
rscript :  chr "\"C:/Users/carl.witthoft/Documents/R/R-3.0.1/bin/x64/Rscript\""
timeout :  num 2592000
useXDR :  logi TRUE

Поэтому, помимо другого номера порта, я думаю, что все соответствует.

Следующий трюк: я открыл оболочку и запустил netsh advfirewall firewall add rule name="Open Port 11017" dir=in action=allow protocol=TCP localport=11017 и получил ответ "ОК". Я запустил netstat -a -n и нашел следующую строку:

TCP 0.0.0.0:11017 0.0.0.0:0 LISTENING

Но работающий makePSOCKcluster все еще висит в одном месте.

NEXT: Я попробовал запустить R из командной строки (через cygwin bash), а сообщение об ошибке, которое я получаю, это Error in loadhistory(file) : no history mechanism available Execution halted, после чего -C возвращает меня в R-подсказку.

4b9b3361

Ответ 1

То, что вы описываете, - это классическая проблема с кластерами PSOCK: makeCluster зависает. Он может зависать по нескольким причинам, потому что он должен создавать все процессы, называемые "рабочими" процессами, которые будут выполнять фактическую работу "кластера", и это включает в себя запуск новых сеансов R, используя команду Rscript, которая будет выполнять .slaveRSOCK, которая создаст подключение сокета к мастеру, а затем выполнит функцию slaveLoop, где в конечном итоге будет выполняться задачи, отправленные им мастером. Если что-то пойдет не так, начав любой из рабочих процессов (и поверьте мне: многое может пойти не так), мастер будет висеть при выполнении 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 

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

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

$ R --vanilla --args MASTER=localhost PORT=10187 OUT=log.txt TIMEOUT=2592000 METHODS=TRUE XDR=TRUE

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

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

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

Для получения дополнительной информации об этой проблеме см. мой ответ на аналогичный вопрос.

UPDATE

Теперь, когда эта конкретная проблема решена, я могу добавить два совета для отладки makePSOCKcluster проблем:

  • Проверьте, не работает ли что-либо в вашем .Rprofile только в интерактивном режиме.
  • В Windows используйте команду Rterm, а не Rgui, чтобы вы чаще видели сообщения об ошибках и выводили с помощью outfile=''.

Ответ 2

Тест 1: Работает ли очевидная команда?

library(parallel)    
cluster <- makePSOCKcluster("localhost")    
parSapply(cluster, 1:5, sqrt)
stopCluster(cluster)

Тест 2: заблокирован ли ваш порт?

Согласно ?makeCluster, порт по умолчанию 10187. Обратитесь к администратору сети, чтобы узнать, открыт ли этот порт.

Тест 3: Правильно ли переменные, переданные в socketConnection, выглядят правильно?

Если я сделаю debugonce(parallel:::newPSOCKnode), а затем перейдя к следующему вызову до socketConnection, рабочая область выглядит так:

ls.str()
arg :  chr "parallel:::.slaveRSOCK()"
## cmd :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\" -e \"parallel:::.slaveRSOCK()\" MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2"| __truncated__
## env :  chr "MASTER=localhost PORT=10187 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE"
## machine :  chr "localhost"
## manual :  logi FALSE
## master :  chr "localhost"
## methods :  logi TRUE
## options : <environment: 0x0000000010bf2518> 
## outfile :  chr "/dev/null"
## port :  num 10187
## rank :  int 1
## renice :  int NA
## rscript :  chr "\"C:/PROGRA~1/R/R-215~1.2/bin/x64/Rscript\""
## timeout :  num 2592000
## useXDR :  logi TRUE

Получаете ли вы то же самое?

Ответ 3

Ну, я не чувствую себя полным идиотом.

Я вернулся к разделу "Три R отладки программного обеспечения" (Retry, Reboot, Reload), а после перезагрузки моей системы и успешной работы с рабочими стартами вручную я попытался создать кластер с manual=FALSE и имел немедленный успех там также.

EDIT: я должен четко указать, что изменение моего .Rprofile от loadhistory() до if(interactive() ) loadhistory() было критическим для успешного использования функций cluster.

Я очень благодарен Ричи и Стиву за их полезные комментарии и предложения. Я, конечно, узнал кучу вещей "под капотом", поэтому опыт был для меня весьма позитивным.

(Итак, я понятия не имею, что WindowsOS thingie или сломанный вызов мешали, но все хорошо, что хорошо заканчивается)