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

Я получаю странное поведение в отношении памяти с 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 000 x 1, но в первом эти "внешние" элементы теперь имеют размер 20 000 x 5000 и почему-то не соответствуют Matlab хотел бы поместить их в качестве временных переменных, и использование памяти выходит из-под контроля, несмотря на их чрезвычайную редкость.

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

1 Ответ

0 голосов
/ 30 октября 2010

Чтобы предсказать временное использование памяти, нам нужно знать больше о работе с внутренними объектами 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 M-цикл, так как в противном случае гигантский массив будет передан всем работникам, и будет много грусти.

...