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

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

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

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

Если ваш выходной язык является C, генератор кода создает определение типа для разреженных матриц под названием sparse. Это определение хранит массивы индексов строки, индексов столбца и соответствующих значений элемента для разреженной матрицы. 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) = [];

Смотрите также

| | | | |

Похожие темы