Ошибка при параллельной обработке в Matlab

У меня есть этот (довольно длинный) код Matlab с вложенными циклами, где я хочу распараллелить основную трудоемкую итерацию. Единственная переменная, которая (очевидно) вызывает у меня проблемы, это DMax, где я получаю сообщение об ошибке:

Error: The variable DMax in a `parfor` cannot be classified.
See Parallel for Loops in MATLAB, "Overview".

Это черновик моего кода:

t0=matrix (Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
Maxiter = 1E6;
DMax = zeros(Maxiter,40);
% Other Stuff
for j=1:269 
     % Do more stuff
     for soil=1:4
        parfor i =1:Maxiter        
            k(i,soil) = a %k is a real number
            a(i,soil) = b %similar to k
            % Do a lot of stuff
            for t= (floor(t0(i,soil))+1):40
                DMax(i,t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
                % Do some more stuff
            end
        end
    end
end
for time=1:40
   % Do the final stuff
end

Я предполагаю, что проблема в том, как я определил DMax, но я не знаю, что это может быть точнее. Я уже смотрел в Интернете, но с не очень удовлетворительными результатами.


person Patapunfate    schedule 10.05.2016    source источник


Ответы (1)


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

  • Тип индексации первого уровня. Первый уровень индексации — это либо круглые скобки (), либо фигурные скобки, {}.
  • Фиксированный список индексов — внутри круглых или фигурных скобок первого уровня список индексов одинаков для всех вхождений данной переменной.
  • Форма индексации — в списке индексов для переменной ровно один индекс включает переменную цикла.
  • Форма массива — массив поддерживает постоянную форму. При присвоении переменной среза правая часть присваивания не может быть [] или '', поскольку эти операторы пытаются
    удалить элементы.

Очевидно, что свойство Список фиксированного индекса не сохраняется, поскольку вы ссылаетесь на него как DMax(i,t), где t изменяет свои значения. В документации описан аналогичный пример, обратите внимание. Таким образом, одним из обходных путей было бы использовать временную переменную внутри внутреннего цикла, а затем присвоить всю строку обратно DMax.

Также обратите внимание, что переменная a также не может быть отнесена ни к какой категории. Не говоря уже о том, что он вообще не определен в вашем примере. Пожалуйста, внимательно прочитайте руководство и убедитесь, что его можно отнести к одной из категорий. При необходимости перепишите код, например. введение новых временных переменных.

Вот код, в котором исправлено использование DMax:

Maxiter = 1E6;
t0 = randn(Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
DMax = zeros(Maxiter,40);
% Other Stuff
for j = 1:269 
     % Do more stuff
     for soil = 1:4
        parfor i = 1:Maxiter        
            k(i,soil) = a %k is a real number
            a(i,soil) = b %similar to k
            % Do a lot of stuff
            tmp = zeros(1,40);
            for t = (floor(t0(i,soil))+1):40
                tmp(t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
                % Do some more stuff
            end
            DMax(i,:) = tmp;
        end
    end
end
for time = 1:40
   % Do the final stuff
end
person nirvana-msu    schedule 10.05.2016
comment
Спасибо за ответ, теперь код работает без ошибок. Прошу прощения за вопрос, который задал, но должен сказать, что описание Mathworks мне совсем не ясно. Тем не менее, большое спасибо. Кстати, я думаю, вы пропустили «tmp (t)» в цикле for, так как я запускаю его именно так, и он отлично заменяет мой предыдущий код. - person Patapunfate; 11.05.2016
comment
Правильно, исправил мой ответ. Рад что помог) - person nirvana-msu; 11.05.2016