Ошибка при попытке использовать parfor (параллельный цикл) в MATLAB - PullRequest
4 голосов
/ 23 марта 2011

Я имею дело с очень большой матрицей и поэтому хотел использовать параллельные вычисления в MATLAB для работы в кластерах. Здесь я создал разреженную матрицу, используя:

Ad = sparse(length(con)*length(uni_core), length(con)*length(uni_core));

У меня есть письменная функция adj, с помощью которой я могу заполнить матрицу Ad. Каждый раз, когда цикл запускается, из функции adj я получаю квадратную симметричную матрицу, которую нужно присвоить Ad от 3682*(i-1)+1 до 3682 *(i-1)+3682 в первом индексе и аналогично во втором индексе. Это показано здесь:

parfor i = 1:length(con)
  Ad((3682*(i-1))+1:((3682*(i-1))+3682), ...
     (3682*(i-1))+1:((3682*(i-1))+3682)) = adj(a, b, uni_core);
end

В обычном цикле for он работает без проблем. Но в parfor при параллельных вычислениях я получаю сообщение об ошибке, что существует проблема в использовании нарезанных массивов с parfor.

Ответы [ 2 ]

5 голосов
/ 23 марта 2011

Выходы из контуров PARFOR должны быть либо переменными редукции (например, вычисление суммирования), либо "нарезанными". Подробнее см. на этой странице в документе.

В вашем случае вы пытаетесь сформировать «нарезанный» вывод, но ваше индексное выражение слишком сложно для PARFOR. В PARFOR секционированный вывод должен быть проиндексирован с помощью: переменной цикла для одного индекса и некоторого константного выражения для других индексов. Константное выражение должно быть либо :, end, либо буквальным скаляром. В следующем примере показано несколько нарезанных выходных данных:

x3 = zeros(4, 10, 3);
parfor ii = 1:10
    x1(ii) = rand;
    x2(ii,:) = rand(1,10);
    x3(:,ii,end) = rand(4,1);
    x4{ii} = rand(ii);
end

В вашем случае ваше индексирующее выражение в Ad слишком сложное, чтобы PARFOR мог его обработать. Вероятно, самое простое, что вы можете сделать, это вернуть вычисления в виде массива ячеек, а затем ввести их в Ad на стороне хоста, используя обычный цикл FOR, например:

parfor i = 1:length(con)
   tmpout{i} = ....;
end
for i = 1:length(con)
   Ad(...) = tmpout{i};
end
4 голосов
/ 23 марта 2011

Эдрик уже объяснил , почему вы получаете ошибку, но я хотел сделать еще одно предложение для решения.Матрица Ad, которую вы создаете, состоит из серии блоков 3682 на 3682 вдоль главной диагонали с нулями повсюду.Одним из решений является создание блоков в цикле PARFOR с сохранением их в массиве ячеек.Затем вы можете объединить их все в одну матрицу с помощью вызова функции BLKDIAG :

cellArray = cell(1,length(con));  %# Preallocate the cell array
parfor i = 1:length(con)
  cellArray{i} = sparse(adj(a,b,uni_core));  %# Compute matrices in parallel
end
Ad = blkdiag(cellArray{:});

Полученная матрица Ad будет разреженной, поскольку каждый блок был преобразован в разреженная матрица до помещения в массив ячеек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...