Функция matlab cell2mat( ...) с массивом ячеек, имеющим множество разреженных матриц, неожиданно переполняет память

Я получаю странное поведение в отношении памяти с Matlab и функцией cell2mat()...

что я хотел бы сделать, это:

cell_array_outer = cell(1,N) 
parfor k = 1:N
  cell_array_inner = cell(1,M);   
  for i = 1:M
    A = do_some_math_and_return_a_sparse_matrix( );
    cell_array_inner{i} = sparse(A); % do sparse() again just to be paranoid
  end
  cell_array_outer{k} = sparse( cell2mat( cell_array_inner ) ); 
end

Giant_Matrix = cell2mat( cell_array_outer ); % DOH! 

Но, увы, строка, обозначенная "DOH", использует какой-то абсурдный объем памяти, больше, чем то, что должно закончиться, если вы сложите размеры разреженных матриц... как, например, создание слишком большой промежуточной структуры.

Следующее работает нормально, но двойное индексирование не работает с par-for, поэтому я могу использовать только одно ядро:

cell_array_giant = cell(M,N) 
for k = 1:N   % cannot use parfor with {i,k} dual indices!

  for i = 1:M
    A = do_some_math_and_return_a_sparse_matrix( );
    cell_array_giant{i,k} = sparse(A); % do sparse() again just to be paranoid
  end
end

cell_array_giant = reshape( cell_array_giant, 1, M * N )
Giant_Matrix = sparse( cell2mat( cell_array_giant ) ); % Ok... but no parfor 

Я подозреваю, что в последнем случае каждый элемент ячейки гораздо более управляем по размеру... как разреженная матрица размером 20 000x1, но в первом эти "внешние" элементы теперь имеют размер 20 000 x 5000 и почему-то не соответствуют тому, что хотелось бы Matlab поместить их в качестве временных переменных, и использование памяти выходит из-под контроля, несмотря на их чрезвычайную редкость.

Какие-либо правила, которые нужно соблюдать в отношении использования памяти и выше? Или как изменить мой parfor, чтобы он работал во втором случае? "parfor" - это что-то новое, поэтому в Интернете меньше информации, чем о других основных функциях... это гораздо эффективнее, чем запуск 8 копий Matlab!

1 ответ

Чтобы предсказать временное использование памяти, нам нужно знать больше о работе с внутренними объектами Matlab, чего я не знаю.

Для вашего второго решения вы можете использовать parfor я думаю, что если вы сделаете это во внутреннем цикле (по крайней мере, я не получаю предупреждения m-lint). При необходимости перенесите вашу проблему так, чтобы M>N, потому что вы обычно хотите parfor выполнять много быстрых вычислений вместо очень немногих длинных, чтобы получить меньший вылет, если число операций не делится на 8 (или сколько ядер вы можете запустить).

cell_array_giant = cell(M,N) 
for k = 1:N   %# cannot use parfor with {i,k} dual indices!

  parfor i = 1:M %# but you can use it here!
    A = do_some_math_and_return_a_sparse_matrix( );
    cell_array_giant{i,k} = sparse(A); %# do sparse() again just to be paranoid
  end
end

Кроме того, возможно ли построить гигантскую разреженную матрицу внутри k -петли? Это позволяет избежать изменения формы в целом. Конечно, вы сможете только parfor М-петля, поскольку в противном случае гигантский массив будет передан всем работникам, и возникнет много грусти.

Другие вопросы по тегам