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