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

Mclapply с большими объектами - "сериализация слишком велика для хранения в необработанном векторе"

Я продолжаю сталкиваться с проблемой с пакетом multicore и большими объектами. Основная идея заключается в том, что я использую функцию Bioconductor (readBamGappedAlignments) для чтения в больших объектах. У меня есть символьный вектор имен файлов, и я использовал mclapply для перебора файлов и чтения их в список. Функция выглядит примерно так:

objects <- mclapply(files, function(x) {
  on.exit(message(sprintf("Completed: %s", x)))
  message(sprintf("Started: '%s'", x))
  readBamGappedAlignments(x)
}, mc.cores=10)

Однако я продолжаю получать следующую ошибку: Error: serialization is too large to store in a raw vector. Тем не менее, кажется, что я могу читать одни и те же файлы без ошибок. Я нашел упоминание об этой проблеме здесь без разрешения.

Любые предложения параллельного решения будут оценены - это нужно делать параллельно. Я мог бы смотреть на снег, но у меня очень мощный сервер с 15 процессорами, по 8 ядер и 256 ГБ памяти, в которых я могу это сделать. Я скорее просто сделаю это на этой машине по ядрам, а не с помощью одного из наших кластеров.

4b9b3361

Ответ 1

Похоже, что целочисленный предел будет рассмотрен очень рано в R. По моему опыту, этот предел может блокировать наборы данных с менее чем 2 миллиардами ячеек (вокруг максимального целого), а функции низкого уровня, такие как sendMaster в пакете multicore полагаться на передачу необработанных векторов. У меня было около 1 миллиона процессов, представляющих около 400 миллионов строк данных и 800 миллионов ячеек в формате data.table, и когда mclapply отправлял результаты обратно, он столкнулся с этим пределом.

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

Вместо одного большого списка создайте список списков. Каждый под-список меньше, чем сломанная версия, и затем вы передаете их в mclapply split by split. Назовите это file_map. Результатом является список списков, поэтому вы можете использовать специальную функцию double concatenate do.call. В результате каждый раз, когда mclapply заканчивается, размер сериализованного необработанного вектора имеет управляемый размер.

Просто обведите более мелкие куски:

collector = vector("list", length(file_map)) # more complex than normal for speed 

for(index in 1:length(file_map)) {
reduced_set <- mclapply(file_map[[index]], function(x) {
      on.exit(message(sprintf("Completed: %s", x)))
      message(sprintf("Started: '%s'", x))
      readBamGappedAlignments(x)
    }, mc.cores=10)
collector[[index]]= reduced_set

}

output = do.call("c",do.call('c', collector)) # double concatenate of the list of lists

В качестве альтернативы сохраните вывод в базе данных по ходу, например SQLite.