필터 지우기
필터 지우기

code generation of a function with multiple sub-functions

조회 수: 7 (최근 30일)
Kun-Lin Hsieh
Kun-Lin Hsieh 2022년 9월 21일
답변: Anil 2022년 9월 28일
Hi All,
I tried to apply code generation for a function which includes multiple sub-functions inside. The generated C code expands those sub-functions. My purpose is to perserve those sub-functions after code generation to maintain the code architecture the same with that of matlab code.
Matlab Code
function [add_out, mul_out] = addmul(a, b)
%#codegen
add_out = add_func(a,b);
mul_out = mul_func(a,b);
end
function out = add_func(a, b)
out = a + b;
end
function out = mul_func(a,b)
out = a .* b;
end
Generated C code
void addmul(const double a_data[], const int a_size[2], const double b_data[],
const int b_size[2], double add_out_data[], int add_out_size[2],
double mul_out_data[], int mul_out_size[2])
{
int i;
int loop_ub_tmp;
(void)b_size;
add_out_size[0] = 1;
add_out_size[1] = a_size[1];
loop_ub_tmp = a_size[0] * a_size[1];
for (i = 0; i < loop_ub_tmp; i++) {
add_out_data[i] = (a_data[i] + b_data[i]);
}
mul_out_size[0] = 1;
mul_out_size[1] = a_size[1];
for (i = 0; i < loop_ub_tmp; i++) {
mul_out_data[i] = a_data[i] * b_data[i];
}
}
Expected Generated C code
void add_func(double a, double b, double *out) {
*out = a + b;
}
void mul_func(double a, double b, double *out) {
*out = a * b;
}
void addmul(const double a_data[], const int a_size[2], const double b_data[],
const int b_size[2], double add_out_data[], int add_out_size[2],
double mul_out_data[], int mul_out_size[2])
{
int i;
int loop_ub_tmp;
(void)b_size;
add_out_size[0] = 1;
add_out_size[1] = a_size[1];
loop_ub_tmp = a_size[0] * a_size[1];
for (i = 0; i < loop_ub_tmp; i++) {
add_func(a_data[i], b_data[i], (double*)(add_out_data + i));
}
mul_out_size[0] = 1;
mul_out_size[1] = a_size[1];
for (i = 0; i < loop_ub_tmp; i++) {
mul_func(a_data[i], b_data[i], (double*)(add_out_data + i));
}
}

답변 (1개)

Anil
Anil 2022년 9월 28일
Hi Kun-Lin,
It is my understanding that you would like to apply code generation for a function which includes multiple sub-functions inside and prevent the inlining/expanding of sub functions. There are a couple of ways to go about this. One option is to use InlineBetweenUserFunctions options of coder config. For example, for the example provided in the question,
>> cfg = code.config('lib');
>> cfg.InlineBetweenUserFunctions = "Never";
>> codegen addmul -args {coder.typeof(1, [1 100], [0 1]), coder.typeof(1, [1 100], [0 1])} -nargout 2 -config cfg
This generates the following code:
void addmul(const double a_data[], const int a_size[2], const double b_data[],
const int b_size[2], double add_out_data[], int add_out_size[2],
double mul_out_data[], int mul_out_size[2])
{
add_func(a_data, a_size, b_data, b_size, add_out_data, add_out_size);
mul_func(a_data, a_size, b_data, b_size, mul_out_data, mul_out_size);
}
Alternatively, one can use coder.inline(‘never’) option to functions that you do not require to be inlined.
So, the example code will be as follows:
function [add_out, mul_out] = addmul(a, b)
%#codegen
add_out = add_func(a,b);
mul_out = mul_func(a,b);
end
function out = add_func(a, b)
coder.inline('never');
out = a + b;
end
function out = mul_func(a,b)
coder.inline('never');
out = a .* b;
end
However, the thing to note here is that the generated code is still not equivalent to the expected example you provided. The for loop to perform the operations are inside the functions. To generate code closer to the one you expect one must modify the code to have the for loop outside the function calls as follows,
function [add_out, mul_out] = addmul(a, b)
%#codegen
add_out = coder.nullcopy(zeros(size(a), 'like', a));
mul_out = coder.nullcopy(zeros(size(a), 'like', a));
for i = 1:numel(a)
add_out(i) = add_func(a(i),b(i));
end
for i = 1:numel(a)
mul_out(i) = mul_func(a(i),b(i));
end
end
function out = add_func(a, b)
coder.inline('never');
out = a + b;
end
function out = mul_func(a,b)
coder.inline('never');
out = a .* b;
end
Here the generated code is as follows,
void addmul(const double a_data[], const int a_size[2], const double b_data[],
const int b_size[2], double add_out_data[], int add_out_size[2],
double mul_out_data[], int mul_out_size[2])
{
int b_i;
int i;
(void)b_size;
add_out_size[0] = 1;
add_out_size[1] = a_size[1];
mul_out_size[0] = 1;
mul_out_size[1] = a_size[1];
i = a_size[1];
for (b_i = 0; b_i < i; b_i++) {
add_out_data[b_i] = add_func(a_data[b_i], b_data[b_i]);
}
i = a_size[1];
for (b_i = 0; b_i < i; b_i++) {
mul_out_data[b_i] = mul_func(a_data[b_i], b_data[b_i]);
}
}

카테고리

Help CenterFile Exchange에서 Generating Code에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by