从 matlab src 代码生成调用图

发布于 2024-12-04 20:55:18 字数 150 浏览 2 评论 0原文

我正在尝试为大约 500 个 matlab src 文件创建函数调用图。我无法找到任何可以帮助我对多个 src 文件执行相同操作的工具。

有人熟悉任何工具或插件吗?

如果没有任何此类工具,阅读 6000 行 matlab 代码的任何建议 没有文档的欢迎。

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 reading 6000 lines of matlab code
without documentation is welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

调妓 2024-12-11 20:55:18

让我推荐 M2HTML,一个自动生成 MATLAB m- HTML 文档的工具文件。其功能列表包括:

  • 查找函数之间的依赖关系并生成依赖关系图(使用 GraphViz 的点工具)
  • 自动交叉引用函数和子函数及其在源代码中的定义

查看此 演示 页面查看此 工具

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.

围归者 2024-12-11 20:55:18

我建议考虑使用 depfun 函数来构建调用图。请参阅http://www.mathworks.com/help/techdoc/ref/depfun。 html 了解更多信息。

特别是,我发现使用 '-toponly' 参数调用 depfun,然后迭代结果,是手动构建调用图的绝佳方法。不幸的是,我无法再访问我使用它编写的任何代码。

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.

我做我的改变 2024-12-11 20:55:18

我认为你的意思是你想确切地看到你的代码是如何运行的——哪些函数调用哪些子函数,它们何时运行以及运行多长时间?

查看 MATLAB 代码分析器。按如下方式执行代码:

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

p 包含函数历史记录,来自我上面链接的同一帮助页面:

<块引用>

历史数据描述了执行过程中函数进入和退出的顺序。 profile 命令在其返回的结构的 FunctionHistory 字段中返回历史数据。历史数据是一个 2×n 数组。第一行包含布尔值,其中 0 表示进入函数,1 表示退出函数。第二行通过 FunctionTable 字段中的索引标识正在进入或退出的函数。 [下面]的这个示例读取历史数据并将其显示在 MATLAB 命令行窗口中。

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

您不一定需要像上面的示例那样显示入口和出口调用;只需查看 p.FunctionTablep.FunctionHistory 就足以显示代码何时进入和退出函数。

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.

还在原地等你 2024-12-11 20:55:18

这个问题已经有很多答案了。
然而,因为我喜欢这个问题,而且我喜欢拖延,所以这是我回答这个问题的看法(它接近 Dang Khoa 提出的方法,但在我看来,足以发布):

这个想法是运行profile 函数,以及<一href="https://www.mathworks.com/help/matlab/ref/digraph.html" rel="nofollow noreferrer">有向图 来表示数据。

profile on

Main % Code to be analized

p = profile('info');

现在 p 是一个结构。特别是,它包含字段FunctionTable,它是一个结构体数组,其中每个结构体都包含有关Main.m 执行期间的某个调用的信息。为了仅保留函数,我们必须检查 FunctionTable 中的每个元素是否是一个函数,即 p.FunctionTable(ii).Type 是否为 < code>'M-function'

为了表示信息,我们使用 MATLAB 的有向图 对象:

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 是一个有向图,其中 node #i 指的是结构体数组 p.FunctionTable,其中一条边将 node #i 连接到 node #j(如果函数由 node #i< 表示) /code> 是 节点所代表的父节点#j

当应用于我的大程序时,该图非常丑陋,但对于较小的函数来说可能会更好:

Graph

放大图表的子部分:

图小

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:

Graph

Zooming in on a subpart of the graph:

Graph Small

烟若柳尘 2024-12-11 20:55:18

我同意 m2html 的答案,我只是想说以下 m2html/mdot 文档中的示例很好:

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

但是我在导出到 pdf 方面运气更好:

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

另外,在尝试上述命令之前,您必须发出类似以下内容的命令:

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

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')
紫瑟鸿黎 2024-12-11 20:55:18

我发现 m2html 非常有帮助(与 Graphviz 软件结合使用)。但是,就我而言,我想创建文件夹中包含的程序的文档,但忽略一些子文件夹和 .m 文件。我发现,通过向 m2html 调用添加“ignoreddir”标志,可以使程序忽略某些子文件夹。但是,我没有找到用于忽略 .m 文件的模拟标志(“ignoreddir”标志也不起作用)。作为解决方法,在 m2html.m 文件中的第 1306 行之后添加以下行也允许使用“ignoreddir”标志来忽略 .m 文件:

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

例如,用于生成文件夹“program_folder”中包含的程序的 html 文档”但忽略“subfolder_1”子文件夹和“test.m”文件,应该执行如下操作:

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

请注意,所有名称为“subfolder_1”的子文件夹和所有“program_folder”内名为“test.m”的文件将被忽略。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文