Генерация кода для разреженных матриц

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

Функции для создания и манипулирования разреженными матрицами перечислены в Sparse Matrices. Чтобы проверить, поддерживается ли функция для генерации кода, смотрите страницу с описанием функции. Генерация кода не поддерживает разреженные матричные входы для всех функций.

Разреженные типы данных в сгенерированном коде

Если ваш целевой язык является C, генератор кода создает определение типа для разреженных матриц, называемых sparse. В этом определении хранятся массивы индексов строк, индексов столбцов и соответствующих значений элементов для разреженной матрицы. The sparse определение типа сгенерировано в файле myFunction_types.h, где myFunction ссылается на имя функции верхнего уровня.

Если ваш целевой язык C++, генератор кода создает класс sparse в файле sparse.h.

Количество ненулевых элементов в разреженной матрице может измениться во время расчетов. По этой причине разреженные матрицы в сгенерированном коде используют массивы переменного размера и динамическое выделение памяти. Если ваш целевой язык является C, сгенерированный код реализует динамически распределенные переменные с помощью emxArray тип. Если ваш целевой язык является C++, сгенерированный код реализует динамически распределенные переменные с помощью coder::array шаблон класса.

Для примера рассмотрим функцию myDiag:

function out = myDiag(n,k)
% create diagonal sparse matrix
%#codegen
A = speye(n);
out = A.*k;
end

Сгенерируйте код для функции при помощи codegen команда:

codegen -config:lib myDiag -args {3, 5} -launchreport

Разреженный тип можно найти в файле myDiag_types.h.

Вход сигнала

Предположим, что у вас есть функция foo который принимает разреженную матрицу как вход. Эта функция умножает разреженную матрицу на матрицу тождеств и выводит продукт:

function C = foo(ASparseInput)
%#codegen
B = speye(size(ASparseInput'));
C = ASparseInput*B;

Предположим, что вы хотите сгенерировать автономные lib, dll, или exe код для использования вне MATLAB® окружение. Чтобы сгенерировать lib код, введите:

codegen -config:lib foo -args {sparse(5,5)} -launchreport

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

Например, вместо генерации кода непосредственно из foo, создайте новую функцию точки входа fooMain чтобы сгенерировать код из. Замените разреженный вход на триплетную форму разреженных данных.

function [ii,jj,out] = fooMain(i,j,v,m,n)
%#codegen
S = sparse(i,j,v,m,n);
[ii,jj,out] = find(foo(S));

Предположим, что вы хотите сгенерировать код для разреженной матрицы 5 на 5 S с числом ненулевых элементов переменного размера. Чтобы сгенерировать код, введите:

S = sparse(5,5);
[m,n] = size(S);
[i,j,v] = find(S);
i = coder.typeof(i,[inf 1]);
codegen -config:lib fooMain -args {i,i,i,m,n} -launchreport

Можно задать вход для fooMain с целым числом и типами массивов переменного размера. Если вы генерируете код непосредственно из fooнеобходимо создать вход как sparse тип.

Если вы действительно принимаете решение передать разреженную матрицу в качестве входных параметров функции точки входа, можно использовать coder.typeof чтобы инициализировать вход. Для примера, для функции foo, можно ввести:

t = coder.typeof(sparse(5,5));
codegen -config:lib foo -args {t} -launchreport

Для разреженных матриц генератор кода не отслеживает верхние границы для размерностей переменного размера. Все размерности переменного размера рассматриваются как неограниченные.

Если вы генерируете MEX-функцию для fooвходные и выходные данные должны быть преобразованы в sparse тип. Это преобразование может снизить эффективность при повторных вызовах MEX-функций или больших входах и выходах.

Вы не можете программно задать разреженные типы входа при помощи assert операторы.

Инструкции по генерации кода

Инициализируйте матрицы с помощью разреженных конструкторов, чтобы максимизировать эффективность кода. Для примера, чтобы создать матрицу тождеств 3 на 3, используйте speye(3,3) а не sparse(eye(3,3)).

Индексированное назначение в разреженные матрицы несет накладные расходы по сравнению с индексированным назначением в полные матрицы. Для примера:

S = speye(10);
S(7,7) = 42;

Как и в MATLAB, разреженные матрицы хранятся в сжатом разреженном формате столбца. Когда вы вставляете новый ненулевой элемент в разреженную матрицу, все последующие ненулевые элементы должны быть сдвинуты вниз, столбец за столбцом. Эти дополнительные манипуляции могут замедлить эффективность.

Ограничения генерации кода

Чтобы сгенерировать код, который использует разреженные матрицы, должно быть включено динамическое выделение памяти. Чтобы хранить изменяющееся количество ненулевых элементов и их значений, разреженные матрицы используют массивы переменного размера в сгенерированном коде. Для изменения параметров динамического выделения памяти см. Раздел «Управление выделением памяти для массивов переменного размера». Поскольку разреженные матрицы используют массивы переменного размера для динамического выделения памяти, ограничения на данные переменного размера также применяются к разреженным матрицам.

Вы не можете назначить разреженные данные данным, которые не разрежены. Сгенерированный код использует различные представления типов данных для разреженных и полных матриц. Чтобы преобразовать в разреженные данные и из них, используйте явное sparse и full функции преобразования.

Вы не можете задать разреженную матрицу с конкурирующими спецификациями размера. Генератор кода фиксирует размер разреженной матрицы, когда он производит соответствующее определение типов в C/C + +. Как пример, функция foo вызывает ошибку в генерации кода:

function y = foo(n)
%#codegen
if n > 0
    y = sparse(3,2);
else
    y = sparse(4,3);
end

Логическое индексирование в разреженные матрицы не поддерживается для генерации кода. Для примера этот синтаксис вызывает ошибку:

S = magic(3);
S(S > 7) = 42;

Для разреженных матриц вы не можете удалить элементы массива, назначив пустые массивы:

S(:,2) = [];

См. также

| | | | |

Похожие темы