Использование parfor на подматрице в matlab

#for-loop #parallel-processing #matlab

#для цикла #параллельная обработка #matlab

Вопрос:

У меня есть фрагмент кода, который делит матрицу изображений img на небольшие фрагменты и работает над ними параллельно. Но Matlab говорит, что parfor цикл не может быть использован, потому что способ outC{i,j} индексируется. Как мне это исправить?

Подматрицы имеют разный размер. Если img=[4x7] , то

 C=[3x3 3x3 3x1;
   1x3 1x3 1x1]
  

Кстати, я не уверен, что использование массива ячеек здесь хорошая идея. Если нет, не стесняйтесь давать предложения о том, как также разделить img .

 C=mat2cell(img, rowSplit, colSplit);
[rowc,colc]=size(C);
outC=cell(rowc,colc);
parfor i=1:rowc
    for j=1:colc
       outC{i,j}=doWork(C{i,j}); 
    end
end
  

Ответ №1:

Вы можете использовать линейную индексацию как для ввода, так и для вывода.

Сначала я делаю вид, что вводил вашу форму, и простую doWork функцию:

 >> C= {rand(3) rand(3) rand(3,1); rand(1,3) rand(1,3) rand(1)};
>> C
C = 
    [3x3 double]    [3x3 double]    [3x1 double]
    [1x3 double]    [1x3 double]    [    0.3922]
>> doWork = @(x)2*x;
  

Затем используйте линейную индексацию:

 >> outC=cell(size(C));
>> parfor ci=1:numel(C)
     outC{ci} = doWork(C{ci});
   end
  

Быстрая проверка, что это сработало:

 >> outC{2,1}./C{2,1}
ans =
     2     2     2
  

Ответ №2:

Хотя здесь есть много ответов, которые помогут использовать parfor блок для выполнения того, что вам нужно, я бы подумал, что еще лучшим решением может быть использование вместо него блока spmd.

Вместо того, чтобы разбивать ваше изображение на более мелкие части в массиве ячеек, рассмотрите вместо этого возможность преобразования его в распределенный массив, возможно, распределяя теми же частями, что вы делаете в данный момент. Внутри spmd блока вы можете выполнить свою doWork функцию, и она будет применена к любой части (совместно) распределенного массива, присутствующей на этом рабочем элементе. Наконец, вы можете собрать результаты и собрать их обратно клиенту.

Я нахожу spmd более сложным для понимания, чем parfor , но это очень мощно, как только вы получите представление об этом; и я бы подумал, что этот пример может быть очень удобно выражен в такой форме.

Комментарии:

1. Не могли бы вы привести пример кода? У меня есть изображение, к которому я хочу применить фильтр. Например, фильтр радиуса 5. Каков был бы наилучший способ его обработки? Спасибо.

Ответ №3:

Просто создайте вектор выходных данных и используйте reshape впоследствии, чтобы превратить его в матрицу.

Комментарии:

1. Не могли бы вы показать, как это можно сделать? Подматрицы имеют разный размер, например, img = [4×7] становится C = [3×3 3×3 3×1;1×3 1×3 1×1].

2. @Usavich: Я имел в виду массив ячеек. Работает ли это, если вы написали, outC{i j*colc} = ... а затем вызвали reshape ?