Edit:Pass Struct by Reference to Internal Functions for Code Generation

23 views (last 30 days)
EDIT
Found the creation of memcopy operations by doing the following
Setting names to all fieldnames of the struct with "cstructname" both in main and subfunctions allowed me to debug this problem. Since two different structs cannot have the same name.
Turns out a subfield of the struct "A" from below is the problem.
I set an upper bound for this particular subfield with coder.varsize, lets call this subfield "A.b", so for example used comment is
coder.varsize(b,[maxBNum,maxBNum],[1,1]);
A=struct("b",b,...)
When I pass "A" to myfun (which does not use subfield "b"), matlab coder cannot determine the upper bounds of subfield "b" and assumes it is unbounded. Thus assuming they are different structs. And thus unnecessary struct copy operations.
Making the upper bounds of the subield infinte solved the creation of unnecessary struct copy operations.
Example code
coder.varsize(b,[inf,inf],[1,1]);
A=struct("b",b,...)
If anybody else also encounters this problem, this approach can be used to debug the problem, although teh cause may not be the same.
But Code generation seems to have this particular unnecsesary copy operations sprinkled everywhere (at least for 2019). I see copy operations for matrix and struct operations (deleting, adding elements, manipulating values etc.), which takes a lot of computational time. This will create runtime problems for big applications.
And I know that this approach is used because priority of Code Generation is to generate reliable code, not runtime, and these copy operations ensure any unanticipated changes are handled.
I really appriciate the amazing tool that is code generation
But there still seems some improvement to be mase.
ORIGINAL
Hello
I have a persistant variable size struct array (lets call it A) that I pass to several functions (lets call them myfun) in my main file.
A small prototype for my main function is a s follows
function D = main(B,C)
persistant A
[A,D]=myfunc(A,B,C)
end
My problem arises when I pass this struct array (A) to an internal function (myfun) in the following way
function [A,D]=myfun(A,B,C)
the generated C++ code in my main file for the internal function call is like the following
ititialize temporary variable _A
copy A -> _A
myfunc(_A,B,C)
Copy _A -> A
terminate _A
these copy operations take huge amount of time.
I know that pass by referance can be enabled (and is enabled in default) for entry point functions.
I also know that if you give a variable both on input and output, it should not copy the given variable as explained here.
But these dont seem to do the trick for me.
Is there a way to force pass by reference and avoid such copy operations for internal functions a well?
PS: Sometimes code generation does not generate such copy operations but I dont know why as I dont make significant changes between code generations.
Thank you.
Matlab 2019a
Windows 10
  2 Comments
Sakshi Sharma
Sakshi Sharma on 2 Jun 2023
Hi, could you please provide the code and more details to look into the issue?
Huzeyfe KILIC
Huzeyfe KILIC on 26 Jun 2023
Hello. Unfortunitely I cannot provide the code due to an NDA agreement. I also couldn't reproduce the problem with a simplified version of the code. Is there a log or verbose option that will allow me to debug this issue? (Debug in the sense of which line matlab to generate copy operations?)

Sign in to comment.

Answers (1)

Mihir
Mihir on 27 Jun 2023
Hi there, it seems that you want to pass the parameters by reference rather than pass by value
In MATLAB, there is no direct way to force pass-by-reference for structure arguments in generated code for internal functions. The pass-by-reference behavior is only automatically applied to entry-point functions. For internal functions, the generated code will involve copying the structure arguments, which can result in performance overhead.
However, you can try the following approaches to minimize the copying operations and improve performance:
  1. Use nested functions: Instead of defining myfun as an internal function, you can define it as a nested function within the scope of the main function. This way, myfun will have access to the variables in the parent function's workspace, including the structure array A. By doing so, you can avoid the need for passing A as an argument and potentially reduce the copying operations.
function D = main(B, C)
persistent A
% Define myfun as a nested function
function D = myfun(B, C)
% Access A directly within myfun
% Modify A as needed
% Return D
end
% Call myfun
D = myfun(B, C);
end
2. Use global variables: You can declare the structure array A as a global variable in the main function and access it within myfun as well. This eliminates the need for passing A as an argument, potentially reducing copying operations.
function D = main(B, C)
global A
% Initialize A if necessary
% Call myfun
D = myfun(B, C);
end
function D = myfun(B, C)
global A
% Access A directly within myfun
% Modify A as needed
% Return D
end
Please note that using global variables can introduce other issues, such as reduced code modularity and potential conflicts if multiple functions access the same global variable. Use this approach with caution and consider the trade-offs.

Products


Release

R2019a

Community Treasure Hunt

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

Start Hunting!