Ошибка %dopar% после нескольких итераций

Я пытался запустить параллельный цикл foreach в R, он отлично работает примерно десять итераций, но затем вылетает, показывая ошибку:

Error in { : task 7 failed - "missing value where TRUE/FALSE needed"
Calls: %dopar% -> <Anonymous>
Execution halted

Я добавляю результаты каждого цикла в файл, который показывает, что результат соответствует ожиданиям. Мой сценарий выглядит следующим образом, используя функцию combn_sub из этого поста:

LBRA <- fread(
 input      = "LBRA.012",
 data.table = FALSE)
str_bra <- nrow(LBRA)

br1sums <- colSums(LBRA)
b1non <- which(br1sums == 0)

LBRA_trim <- LBRA[,-b1non]

library(foreach)
library(doMC)
registerDoMC(28)

foreach(X = seq(2, (nrow(LBRA)-1))) %dopar% {
  com <- combn_sub(
   x    = nrow(LBRA),
   m    = X,
   nset = 1000)

  out_in <- matrix(
   ncol = 2,
   nrow = 1)
   colnames(out) <- c("SNPs", "k")

    for (A in seq(1, ncol(com))){
      rowselect <- com[, A]

      sub <- LBRA_trim[rowselect, ]
      subsum <- colSums(sub)

      length <- length(which(subsum != 0)) - 1
      out_in <- rbind(out_in, c(length, X))
    }

  write.table(
   file   = "plateau.csv",
   sep    = "\t",
   x      = out_in,
   append = TRUE)
}

person JohnnyTooBad    schedule 08.02.2016    source источник
comment
Вы пытались запустить первые 10 итераций без использования %dopar%, чтобы увидеть, на какой строке происходит сбой? Я предполагаю, что в этой строке данных есть что-то, что отличается от других строк данных, которые не учитываются.   -  person tblznbits    schedule 08.02.2016
comment
Запись в файл из параллельного цикла кажется мне нецелесообразной.   -  person Roland    schedule 08.02.2016
comment
Явно создайте свой многоядерный кластер перед вызовом registerDoMC(28) и укажите файл журнала. Так вы сможете видеть, что происходит: cluster <- makeCluster(28, outfile="MulticoreLogging.txt"); registerDoMc(cluster);   -  person Mekki MacAulay    schedule 08.02.2016


Ответы (2)


У меня была аналогичная проблема с моим вызовом foreach...

tmpcol <- foreach(j = idxs:idxe, .combine=cbind) %dopar% { imp(j) }

Error in { : task 18 failed - "missing value where TRUE/FALSE needed"

Изменение параметра .errorhandling игнорирует только ошибку

tmpcol <- foreach(j = idxs:idxe, .combine=cbind, .errorhandling="pass") %dopar% { imp(j) }

Warning message:
In fun(accum, result.18) :
  number of rows of result is not a multiple of vector length (arg 2)

Я предлагаю запустить функцию в вашем вызове foreach для X=7. Проблема в моем случае заключалась в том, что моя функция imp(j) выдавала ошибку (для j=18 она зависала при вычислении NA), что приводило к расплывчатому выводу foreach.

person Nathan Dyjack    schedule 24.10.2016

Как указывает @Roland, очень плохая идея писать в файл в цикле foreach. Даже при записи в режиме append отдельные ядра будут пытаться записывать в файл одновременно и могут затирать ввод друг друга. Вместо этого запишите результаты оператора foreach с помощью параметра .combine="rbind", а затем запишите в файл после цикла:

cluster <- makeCluster(28, outfile="MulticoreLogging.txt");
registerDoMc(cluster);

foreach_outcome_table <- foreach(X = seq(2, (nrow(LBRA)-1)), .combine="rbind") %dopar% {

  print(cat(paste(Sys.info()[['nodename']], Sys.getpid(), sep='-'), "now performing loop", X, "\n"));

  com <- combn_sub(x = nrow(LBRA), m = X, nset = 1000);

  out_in <- matrix(ncol = 2,nrow = 1);

  colnames(out_in) <- c("SNPs", "k");

  for (A in seq(1, ncol(com))){
    rowselect <- com[, A];

    sub <- LBRA_trim[rowselect, ];
    subsum <- colSums(sub);

    length <- length(which(subsum != 0)) - 1;
    out_in <- rbind(out_in, c(length, X));
  }
  out_in;
}
write.table(file = "plateau.csv",sep = "\t", x = foreach_outcome_table, append = TRUE);

Кроме того, вы можете заменить внутренний цикл for на вложенный цикл foreach что, вероятно, было бы более эффективным.

person Mekki MacAulay    schedule 08.02.2016
comment
Спасибо за совет. Мой первоначальный скрипт не выполнял запись в файл внутри цикла, но я добавил его, чтобы увидеть, в какой момент произошел сбой. - person JohnnyTooBad; 09.02.2016
comment
В этом есть смысл. Многоядерное ведение журнала при создании кластера — лучший вариант для уменьшения коллизий. Вы даже можете указать идентификаторы отдельных ядер, чтобы понять, какое из них что делает. Я пишу обновления статуса из цикла foreach, используя print(cat(paste(Sys.info()[['nodename']], Sys.getpid(), sep='-'), "now performing action X")); или что-то подобное для отслеживания. - person Mekki MacAulay; 09.02.2016