Диагностируйте переменные в parfor - циклы

Гарантируйте, что parfor - переменные цикла являются последовательными увеличивающимися Целыми числами

Переменные цикла в parfor - цикл должны быть последовательными увеличивающимися целыми числами. Поэтому следующие примеры возвращают ошибки:

parfor i = 0:0.2:1      % not integers
parfor j = 1:2:11       % not consecutive
parfor k = 12:-1:1      % not increasing
Можно зафиксировать эти ошибки путем преобразования переменных цикла в допустимую область значений. Например, можно зафиксировать пример нецелого числа можно следующим образом:
iValues = 0:0.2:1;
parfor idx = 1:numel(iValues)
i = iValues(idx);
...
end

Избегайте переполнения в parfor - циклы

Если MATLAB® обнаруживает, что parfor - переменная цикла может переполниться, это сообщает об ошибке.

Условие переполненияПримерРешение

Длина parfor - область значений цикла превышает максимальное значение типа переменной цикла.

Здесь, MATLAB сообщает об ошибке потому что length(-128:127)>maxint('int8'):

parfor idx=int8(-128:127)
    idx;
end

Используйте больший тип данных для parfor - переменная цикла. Если вы хотите сохранить исходный тип данных в своих вычислениях, преобразуйте parfor - переменная цикла в цикле parfor.

parfor idx=-128:127
    int8(idx);
end

Начальное значение parfor - область значений цикла равняется минимальному значению типа переменной цикла.

Здесь, MATLAB сообщает об ошибке потому что 0=intmin('uint32'):

parfor idx=uint32(0:1)
    idx;
end

  • Используйте больший тип данных с более низким минимальным значением, как в предыдущем решении.

  • Постепенно увеличьте область значений значений. Например:

    parfor idx=uint32(0:1)+1
        idx-1;
    end

Решите переменные проблемы классификации в parfor - циклы

Когда MATLAB распознает имя в parfor - цикл как переменная, переменная классифицируется на одну из нескольких категорий, показанных в следующей таблице. Убедитесь, что ваши переменные исключительно классифицируются и удовлетворяют требования категории. parfor - циклы, которые нарушают требование, возвращают ошибку.

КлассификацияОписание
Переменные циклаИндексы цикла
Нарезанные переменныеМассивы, сегменты которых управляются различными итерациями цикла
Широковещательно передайте переменныеПеременные задали перед циклом, значение которого требуется в цикле, но никогда не присваивается в цикле
Переменные сокращенияПеременные, который накапливает значение через итерации цикла, независимо от порядка итерации
Временные переменныеПеременные, созданные в цикле, и не, получили доступ вне цикла

Чтобы узнать, какие переменные вы имеете, исследуйте фрагмент кода. Все переменные классификации в таблице представлены в этом коде:

Если вы сталкиваетесь с переменными проблемами классификации, рассматриваете эти подходы, прежде чем вы обратитесь к более трудному методу преобразования тела parfor - цикл в функцию.

  • Если вы используете вложенный for - цикл, чтобы индексировать в нарезанный массив, вы не можете использовать тот массив в другом месте в parfor - цикл. Код слева не работает, потому что A нарезан и индексирован во вложенном for - цикл. Код справа работает, потому что v присвоен A вне вложенного цикла. Можно вычислить целую строку, и затем выполнить однократное присвоение в нарезанный вывод.

    НедопустимыйДопустимый
    A = zeros(4, 10);
    parfor i = 1:4
        for j = 1:10
            A(i, j) = i + j;
        end
        disp(A(i, 1))
    end
    A = zeros(4, 10);
    parfor i = 1:4
        v = zeros(1, 10);
        for j = 1:10
            v(j) = i + j;
        end
        disp(v(1))
        A(i, :) = v;
    end

  • Код слева не работает, потому что переменная x в parfor не может быть классифицирована. Эта переменная не может быть классифицирована, потому что существует несколько присвоений на различные части x. Поэтому parfor не может определить, существует ли зависимость между итерациями цикла. Код справа работает, потому что вы полностью перезаписываете значение x. parfor может теперь решить однозначно, что x является временной переменной.

    НедопустимыйДопустимый
    parfor idx = 1:10
      x(1) = 7;
      x(2) = 8;
      out(idx) = sum(x);
    end
    parfor idx = 1:10
      x = [7, 8];
      out(idx) = sum(x);
    end

  • Этот пример показывает, как нарезать поле структурированного массива. Смотрите struct для деталей. Код слева не работает, потому что переменная a в parfor не может быть классифицирована. Эта переменная не может быть классифицирована, потому что форма индексации не допустима для нарезанной переменной. Первый уровень индексации не является нарезанной операцией индексации, даже при том, что поле x a, кажется, нарезано правильно. Код справа работает, потому что вы извлекаете поле struct в отдельную переменную tmpx. parfor может теперь решить правильно, что эта переменная нарезана. В целом вы не можете использовать поля struct s или свойств объектов как нарезанные переменные ввода или вывода в parfor.

    НедопустимыйДопустимый
    a.x = [];
    parfor idx = 1:10
      a.x(idx) = 7;
    end
    tmpx = [];
    parfor idx = 1:10
      tmpx(idx) = 7;
    end
    a.x = tmpx;

Массивы структур в циклах parfor

Создание структур как временные файлы

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

НедопустимыйДопустимый
parfor i = 1:4
   temp.myfield1 = rand();
   temp.myfield2 = i;
end 
parfor i = 1:4
    temp = struct();
    temp.myfield1 = rand();
    temp.myfield2 = i;
end
parfor i = 1:4
    temp = struct('myfield1',rand(),'myfield2',i);
end

Разрезание полей структуры

Вы не можете использовать поля структуры в качестве нарезанных массивов ввода или вывода в parfor - цикл. Другими словами, вы не можете использовать переменную цикла, чтобы индексировать элементы поля структуры. В коде слева, обе строки в цикле генерируют ошибку классификации из-за индексации. В коде справа, как обходное решение для нарезанного вывода, вы используете отдельные нарезанные массивы в цикле. Затем вы присваиваете поля структуры после того, как цикл будет завершен.

НедопустимыйДопустимый
parfor i = 1:4
    outputData.outArray1(i) = 1/i;
    outputData.outArray2(i) = i^2;
end 
parfor i = 1:4
    outArray1(i) = 1/i;
    outArray2(i) = i^2;
end
outputData = struct('outArray1',outArray1,'outArray2',outArray2); 

Обходное решение для нарезанного входа должно присвоить поле структуры отдельному массиву перед циклом. Можно использовать тот новый массив для нарезанного входа.

inArray1 = inputData.inArray1;
inArray2 = inputData.inArray2;
parfor i = 1:4
    temp1 = inArray1(i);
    temp2 = inArray2(i);
end

Преобразование Тела parfor - Цикл в Функцию

Если все остальное перестало работать, можно обычно решать переменные проблемы классификации в parfor - циклы путем преобразования тела parfor - цикл в функцию. В коде слева, Анализатор кода отмечает проблему с помощью переменной y, но не может разрешить его. В коде справа, вы решаете эту проблему путем преобразования тела parfor - цикл в функцию.

НедопустимыйДопустимый
function parfor_loop_body_bad

data = rand(5,5);
means = zeros(1,5);
parfor i = 1:5
  % Code Analyzer flags problem 
  % with variable y below  
    y.mean = mean(data(:,i));
    means(i) = y.mean;
end
disp(means);
function parfor_loop_body_good

data = rand(5,5);
means = zeros(1,5);
parfor i = 1:5
    % Call a function instead
    means(i) = computeMeans(data(:,i));
end
disp(means);

% This function now contains the body
% of the parfor-loop
function means = computeMeans(data)
y.mean = mean(data);
means = y.mean;
Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.
    0.6786    0.5691    0.6742    0.6462    0.6307

Однозначные имена переменных

Если вы используете имя, которое MATLAB не может однозначно отличить как переменная в parfor - цикл во время синтаксического анализа, MATLAB принимает, что вы ссылаетесь на функцию. Затем во времени выполнения, если функция не может быть найдена, MATLAB генерирует ошибку. Смотрите Имена переменных (MATLAB). Например, в следующем коде f(5) мог обратиться или к Пятому элементу массива под названием f, или к функции с именем f с аргументом 5. Если f ясно не задан как переменная в коде, MATLAB ищет функциональный f на пути, когда код запускается.

parfor i = 1:n
   ...
   a = f(5);
   ...
end

Прозрачный parfor - циклы

Тело parfor - цикл должно быть прозрачным: все ссылки на переменные должны быть “видимы” в тексте кода. Для получения дополнительной информации о прозрачности, смотрите, Гарантируют Прозрачность в циклах parfor или spmd Операторах.

Глобальные и персистентные переменные

Тело parfor - цикл не может содержать объявления переменной persistent или global.

Похожие темы