exponenta event banner

Устранение неполадок переменных в parfor- Петли

Убедитесь, что parfor-Контурные переменные являются последовательными увеличивающимися целыми числами

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

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Переменная -loop может переполняться, она сообщает об ошибке.

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

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

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

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

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

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

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

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

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

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

  • Увеличьте диапазон значений. Например:

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

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

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

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

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

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

  • При использовании вложенного for-loop для индексирования в разрезованный массив, этот массив нельзя использовать в другом месте в 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 теперь можно правильно определить, что эта переменная разделена. Как правило, нельзя использовать поля 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-loop с использованием назначения точечных обозначений. В коде слева обе строки внутри цикла генерируют ошибку классификации. В коде справа в качестве обхода можно использовать 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);
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-loop, во время синтаксического анализа MATLAB предполагает, что вы ссылаетесь на функцию. Затем во время выполнения, если функция не может быть найдена, MATLAB генерирует ошибку. См. раздел Имена переменных. Например, в следующем коде f(5) может ссылаться либо на пятый элемент массива с именем fили к функции с именем f с аргументом 5. Если f не определен четко как переменная в коде, MATLAB ищет функцию f на пути при запуске кода.

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

Прозрачный parfor- петли

Тело parfor-loop должен быть прозрачным: все ссылки на переменные должны быть «видимыми» в тексте кода. Дополнительные сведения о прозрачности см. в разделе Обеспечение прозрачности в пакетах-петлях или инструкциях spmd.

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

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

Связанные темы