Я работаю над проектом, который требует больших матриц с большим количеством нулей. К сожалению, поскольку некоторые из этих матриц могут иметь более 1e10 элементов, работа со «стандартными» R-матрицами не является опцией из-за ограничений RAM. Кроме того, мне нужно работать с несколькими ядрами, так как вычисление может занять довольно много времени, а на самом деле не должно.Работа с несколькими ядрами и разреженными матрицами в R
До сих пор я работал с пакетом foreach
и преобразовывал результаты (которые входят в стандартные матрицы) в разреженные матрицы впоследствии. Я не могу не думать, что должен быть более умный способ.
Вот минимальный пример того, что я делал до сих пор:
cl <- makeSOCKcluster(8)
registerDoSNOW(cl)
Mat <- foreach(j=1:length(lambda), .combine='cbind') %dopar% {
replicate(iter, rpois(n=1, lambda[j]))
}
Mat <- Matrix(Mat, sparse=TRUE)
stopCluster(cl)
В лямбдах все довольно мало, так что только каждый 5-й элемент или так отличен от нуля, что делает его разумным магазин результаты в разреженной матрице.
К сожалению, теперь необходимо увеличить количество итераций от 1e6 до не менее 1e7, так что матрица, создаваемая петлей foreach
, слишком велика для хранения в 8 ГБ ОЗУ. Теперь я хочу разделить задачи на шаги, каждая из которых имеет 1е6 итерации, и объединить их в единую разреженную матрицу.
теперь у меня есть следующие как идея:
library(Matrix)
library(snow)
cl <- makeSOCKcluster(8)
iter <- 1e6
steps <- 1e5
numsteps <- iter/steps
draws <- function(x, lambda, steps){
replicate(n=steps, rpois(n=1, lambda=lambda))
}
for(i in 1:numsteps){
Mat <- Matrix(0, nrow=steps, ncol=96, sparse=TRUE)
Mat <- Matrix(
parApply(cl=cl, X=Mat, MARGIN=2, FUN=draws, lambda=0.2, steps=steps)
, sparse = TRUE)
if(!exists("fullmat")) fullmat <- Mat else fullmat <- rBind(fullmat, Mat)
rm(Mat)
}
stopCluster(cl)
Он отлично работает, но я должен был исправить лямбда до некоторого значения. Для моего приложения мне нужны значения в i-й строке, исходящие из распределения пуассонов со средним значением, равным i-му элементу вектора лямбда. Очевидно, он отлично работал в цикле foreach
., Но мне еще предстоит найти способ заставить его работать в цикле приложения.
Мои вопросы:
- Можно ли иметь функцию применять «знать», на котором ряд его работы и передать соответствующий аргумент функции?
- Есть ли способ работать с foreach и разреженными матрицами без необходимости создания стандартной матрицы и преобразования ее в разреженный на следующем шаге?
- Если не указано выше, есть ли способ вручную назначить задачи подчиненным процессам R - то есть, могу ли я конкретно сказать, что процесс работает над столбцом 1, другой - для работы с столбцом 2 и т. Д. каждый из которых создает разреженный вектор и объединяет их только на последнем шаге.