Появится следующее сообщение:
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.
В отчете по созданию кода просмотрите специализации функций. Если вы видите, что размер аргумента изменяется для каждой специализации функции, попробуйте следующее решение:
Принудительная рекурсия времени выполнения путем задания размера входной переменной.
Рассмотрим эту функцию:
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 параметр конфигурации.