开发者

Call graph generation from matlab src code

开发者 https://www.devze.com 2023-04-05 09:55 出处:网络
I am trying to create a function call graph for around 500 matlab src files. I am unable to find any tools which could help me do the same for multiple src files.

I am trying to create a function call graph for around 500 matlab src files. I am unable to find any tools which could help me do the same for multiple src files.

Is anyone familiar with any tools or plugins?

In case any such tools are not available, any suggestions on readin开发者_开发知识库g 6000 lines of matlab code without documentation is welcome.


Let me suggest M2HTML, a tool to automatically generate HTML documentation of your MATLAB m-files. Among its feature list:

  • Finds dependencies between functions and generates a dependency graph (using the dot tool of GraphViz)
  • Automatic cross-referencing of functions and subfunctions with their definition in the source code

Check out this demo page to see an example of the output of this tool.


I recommend looking into using the depfun function to construct a call graph. See http://www.mathworks.com/help/techdoc/ref/depfun.html for more information.

In particular, I've found that calling depfun with the '-toponly' argument, then iterating over the results, is an excellent way to construct a call graph by hand. Unfortunately, I no longer have access to any of the code that I've written using this.


I take it you mean you want to see exactly how your code is running - what functions call what subfunctions, when, and how long those run for?

Take a look at the MATLAB Code Profiler. Execute your code as follows:

>> profile on -history; MyCode; profile viewer
>> p = profile('info');

p contains the function history, From that same help page I linked above:

The history data describes the sequence of functions entered and exited during execution. The profile command returns history data in the FunctionHistory field of the structure it returns. The history data is a 2-by-n array. The first row contains Boolean values, where 0 means entrance into a function and 1 means exit from a function. The second row identifies the function being entered or exited by its index in the FunctionTable field. This example [below] reads the history data and displays it in the MATLAB Command Window.

profile on -history
plot(magic(4));
p = profile('info');

for n = 1:size(p.FunctionHistory,2)
 if p.FunctionHistory(1,n)==0
        str = 'entering function: ';
 else
        str = 'exiting function: ';
 end
 disp([str p.FunctionTable(p.FunctionHistory(2,n)).FunctionName])
end

You don't necessarily need to display the entrance and exit calls like the above example; just looking at p.FunctionTable and p.FunctionHistory will suffice to show when code enters and exits functions.


There are already a lot of answers to this question. However, because I liked the question, and I love to procrastinate, here is my take at answering this (It is close to the approach presented by Dang Khoa, but different enough to be posted, in my opinion):

The idea is to run the profile function, along with a digraph to represent the data.

profile on

Main % Code to be analized

p = profile('info');

Now p is a structure. In particular, it contains the field FunctionTable, which is a structure array, where each structure contains information about one of the calls during the execution of Main.m. To keep only the functions, we will have to check, for each element in FunctionTable, if it is a function, i.e. if p.FunctionTable(ii).Type is 'M-function'

In order to represent the information, let's use a MATLAB's digraph object:

N = numel(p.FunctionTable);

G = digraph;

G = addnode(G,N);

nlabels = {};

for ii = 1:N
    
        Children = p.FunctionTable(ii).Children;
        
        if ~isempty(Children)
            
            for jj = 1:numel(Children)
                
                G = addedge(G,ii,Children(jj).Index);
                
            end
            
        end
end

Count = 1;

for ii=1:N

    if ~strcmp(p.FunctionTable(ii).Type,'M-function') % Keep only the functions    
        
        G = rmnode(G,Count);
    
    else
        
        Nchars = min(length(p.FunctionTable(ii).FunctionName),10);
        nlabels{Count} = p.FunctionTable(ii).FunctionName(1:Nchars);
        Count = Count + 1;
             
    end
    
end

plot(G,'NodeLabel',nlabels,'layout','layered')  

G is a directed graph, where node #i refers to the i-th element in the structure array p.FunctionTable where an edge connects node #i to node #j if the function represented by node #i is a parent to the one represented by node #j.

The plot is pretty ugly when applied to my big program but it might be nicer for smaller functions:

Call graph generation from matlab src code

Zooming in on a subpart of the graph:

Call graph generation from matlab src code


I agree with the m2html answer, I just wanted to say the following the example from the m2html/mdot documentation is good:

mdot('m2html.mat','m2html.dot');
!dot -Tps m2html.dot -o m2html.ps
!neato -Tps m2html.dot -o m2html.ps

But I had better luck with exporting to pdf:

mdot('m2html.mat','m2html.dot');
!dot -Tpdf m2html.dot -o m2html.pdf

Also, before you try the above commands you must issue something like the following:

m2html('mfiles','..\some\dir\with\code\','htmldir','doc_dir','graph','on')


I found the m2html very helpful (in combination with the Graphviz software). However, in my case I wanted to create documentation of a program included in a folder but ignoring some subfolders and .m files. I found that, by adding to the m2html call the "ignoreddir" flag, one can make the program ignore some subfolders. However, I didn't find an analogue flag for ignoring .m files (neither does the "ignoreddir" flag do the job). As a workaround, adding the following line after line 1306 in the m2html.m file allows for using the "ignoreddir" flag for ignoring .m files as well:

d = {d{~ismember(d,{ignoredDir{:}})}};

So, for instance, for generating html documentation of a program included in folder "program_folder" but ignoring "subfolder_1" subfolder and "test.m" file, one should execute something like this:

m2html( 'mfiles', 'program_folder', ...  % set program folder
        'save', 'on', ...  % provide the m2html.mat
        'htmldir', './doc', ...  % set doc folder
        'graph', 'on', ...  % produce the graph.dot file to be used for the visualization, for example, as a flux/block diagram
        'recursive', 'on', ...  % consider also all the subfolders inside the program folders
        'global', 'on', ...  % link also calls between functions in different folders, i.e., do not link only the calls for the functions which are in the same folder
        'ignoreddir', { 'subfolder_1' 'test.m' } );  % ignore the following folders/files

Please note that all subfolders with name "subfolder_1" and all files with name "test.m" inside the "program_folder" will be ignored.

0

精彩评论

暂无评论...
验证码 换一张
取 消