Вы видите сообщение, такое как:
Compile-time recursion limit reached. Size or type of input #1 of function 'foo' may change at every call.
Compile-time recursion limit reached. Value of input #1 of function 'foo' may change at every call.
С рекурсией во время компиляции генератор кода производит несколько версий рекурсивной функции вместо того, чтобы производить рекурсивную функцию в сгенерированном коде. Эти версии известны как функциональные специализации. Генератор кода не может использовать рекурсию во время компиляции для рекурсивной функции в MATLAB® код, поскольку количество специализаций функций превышает предел.
Чтобы решить проблему, попробуйте одно из следующих решений:
Для этого сообщения:
Compile-time recursion limit reached. Value of input #1 of function 'foo' may change at every call.
Используйте это решение:
Рекурсия во время прогона силы путем обработки Входа значения как неконстантного.
Для этого сообщения:
Compile-time recursion limit reached. Size or type of input #1 of function 'foo' may change at every call.
В отчете генерации кода проверьте специализацию функции. Если вы видите, что размер аргумента меняется для каждой специализации функции, попробуйте это решение:
Рекурсия во время выполнения силы путем создания входной переменной - Size.
Рассмотрим эту функцию:
function y = call_recfcn(n) A = ones(1,n); x = 100; y = recfcn(A,x); end function y = recfcn(A,x) if size(A,2) == 1 || x == 1 y = A(1); else y = A(1)+recfcn(A(2:end),x-1); end end
Второй вход в recfcn
имеет постоянное значение 100. Генератор кода определяет, что количество рекурсивных вызовов является конечным, и пытается создать 100 копий recfcn
. Это количество специализаций превышает предел рекурсии во время компиляции. Чтобы форсировать рекурсию во время выполнения, дайте команду генератору кода обработать второй вход как неконстантное значение при помощи coder.ignoreConst
.
function y = call_recfcn(n) A = ones(1,n); x = coder.ignoreConst(100); y = recfcn(A,x); end function y = recfcn(A,x) if size(A,2) == 1 || x == 1 y = A(1); else y = A(1)+recfcn(A(2:end),x-1); end end
Если генератор кода не может определить, что количество рекурсивных вызовов конечное, он производит рекурсивную функцию во время выполнения.
Рассмотрим эту функцию:
function z = call_mysum(A) %#codegen z = mysum(A); end function y = mysum(A) coder.inline('never'); if size(A,2) == 1 y = A(1); else y = A(1)+ mysum(A(2:end)); end end
Если вход в mysum
является фиксированным размером, генератор кода использует рекурсию во время компиляции. Если A
достаточно велик, количество специализаций функций превышает предел времени компиляции. Чтобы заставить генератор кода использовать преобразование во время выполнения, сделайте вход mysum
переменный размер при помощи coder.varsize
.
function z = call_mysum(A) %#codegen B = A; coder.varsize('B'); z = mysum(B); end function y = mysum(A) coder.inline('never'); if size(A,2) == 1 y = A(1); else y = A(1)+ mysum(A(2:end)); end end
Предел рекурсии во время компиляции по умолчанию 50 достаточно велик для большинства рекурсивных функций, которые требуют рекурсии во время компиляции. Обычно увеличение предела не устраняет проблему. Однако, если вы можете определить количество рекурсивных вызовов и хотите рекурсию во время компиляции, увеличьте предел. Для примера рассмотрим эту функцию:
function z = call_mysum() %#codegen B = 1:125; z = mysum(B); end function y = mysum(A) coder.inline('never'); if size(A,2) == 1 y = A(1); else y = A(1)+ mysum(A(2:end)); end end
Можно определить, что генератор кода производит 125 копий mysum
функция. В этом случае, если вы хотите рекурсию во время компиляции, увеличьте предел рекурсии во время компиляции до 125.
Чтобы увеличить предел рекурсии во время компиляции:
В командной строке в объекте строения генерации кода увеличьте значение CompileTimeRecursionLimit
Параметр конфигурации.
В приложении MATLAB Coder™ увеличьте значение настройки Compile-time recursion limit.