Диагностируйте переменные в 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 \in 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 \in parfor не может быть классифицирован. Эта переменная не может быть классифицирована, потому что форма индексации не допустима для нарезанной переменной. Первый уровень индексации не является нарезанной операцией индексации, даже при том, что поле x из a кажется, нарезан правильно. Код справа работает, потому что вы извлекаете поле struct в отдельную переменную tmpx. parfor может теперь решить правильно, что эта переменная нарезана. В общем случае вы не можете использовать поля structs или свойства объектов как нарезанные переменные ввода или вывода в 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

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

Вы не можете создать структуру в a 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

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

Вы не можете использовать поля структуры в качестве нарезанных массивов ввода или вывода в a 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);
end
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);
end

% This function now contains the body
% of the parfor-loop
function means = computeMeans(data)
    y.mean = mean(data);
    means = y.mean;
end
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 генерирует ошибку. Смотрите Имена переменных. Например, в следующем коде f(5) мог отослать любого к Пятому элементу массива под названием f, или к функции с именем f с аргументом 5. Если f ясно не задан как переменная в коде, MATLAB ищет функциональный f на пути, когда код запускается.

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

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

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

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

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

Похожие темы