I wrote a set of nested for loops to conduct a parameter sweep in a third party software (Lumerical, it's an FDTD package) in Matlab. This code works perfectly well, but I can't seem to get the parallel version to work. My guess is that Matlab is having issues assigning workers in the parallel case, but I'm having issues resolving this. I've copied my code for the loop below and the line in the function I use to execute each Lumerical simulation. Does anyone have any suggestions for how to resolve this?
parfor ph = 1:PH
for p = 1:P
for bi = 1:BI
for pii = 1:PI
for r =1:R
poolobj = gcp;
addAttachedFiles(poolobj, FDTD_exec_pillars_parfor.m);
pitch = [PillarHeight(ph), Pitch(p), BackgroundIndex(bi),...
PillarIndex(pii), Radius(r)];
Transdata = FDTD_exec_pillars_parfor(pitch);
cellframe2(ph,p,bi,pii,r) = Transdata;
end
end
end
end
end
% Path used to execute simulation in FDTD package within function FDTD_exec_pillars_parfor
[x1,y1]=system('"C:\Program Files\Lumerical\FDTD\bin\fdtd-solutions.exe" -run NOMAD_script.lsf');
error message:
"Error: MATLAB cannot determine whether "FDTD_exec_pillars_parfor" refers to a function or variable. See Parallel for Loops in MATLAB, "Unambiguous Variable Names"."
This error message appeared after I added the two poolobj lines in attempt to resolve this error:
"An UndefinedFunction error was thrown on the workers for 'FDTD_exec_pillars_parfor'. This might be because the file containing 'FDTD_exec_pillars_parfor' is not accessible on the workers. Use addAttachedFiles(pool, files) to specify the required files to be attached. See the documentation for 'parallel.Pool/addAttachedFiles' for more details.
Caused by: Undefined function 'FDTD_exec_pillars_parfor' for input arguments of type 'double'"
Related
I have a code in matlab (~1000 lines) that constists of about 15 functions. The code runs fine with each function as a different script, but I want to put them all into one file so I can use the publish function more easily. However, when I put them all together my 'main' function isn't recognizing the local functions. Here's what it looks like:
function full_function()
...
values = fvalues(0);
...
end
function values = fvalues(state)
...
end
When I try to run it, it gives me
"Undefined function 'fvalues' for input arguments
of type 'double'.
Error in full_function (line 32)
values = fvalues(0);"
I've looked all over for how to do local functions and I have no idea what I'm doing wrong. If I right-click on fvalues and hit 'open' it even brings me to the correct portion of the code, so I have no idea why full_function cannot read it. Please help! Thanks.
I am getting the following error while running a program.
??? Undefined function or method 'struct2table' for input arguments of type 'struct'.
Error in ==> cellarray at 13
T=struct2table(parameter,'AsArray',true);
The program is as under
a=10;
b=15;
parameter(a).alpha_star=0;
parameter(b).gamma_star=0;
x=5;
for j=1:b
for i=1:a
parameter(i).alpha_star=x+i;
end
parameter(j).gamma_star = x^2+j;
end
T=struct2table(parameter,'AsArray',true);
Can you please tell me, where am I wrong?
I am guessing you have a matlab older than R2013b, and since do not have this function (you can check that via which struct2table).
you can try to work around it by using struct2array and reshape.
you can also use
alp=[];
gam =[];
for i=1:length(parameter)
if ~isempty(parameter(i).alpha_star)
alp(end+1)=(parameter(i).alpha_star);
end
if ~isempty(parameter(i).gamma_star)
gam(end+1)=(parameter(i).gamma_star);
end
end
to extract the values to seperate arrays and
fieldnames(parameter);
to get the fieldnames, this is dirty but if it is only needed for presentation...
I have written this function, and I have already defined values for rg and Lp, but still when I run this function it returns the error : (Input argument "Lr" is undefined.
Error in ==> Bis at 12
if f(Lr,rg,Xo)*f(Lr,rg,Xf)>0)
here is the function :
function[Lp,Xo,Xf]=Bis(Lr,rg)
Xo=0;
Xf=10;
Err=0.01;
syms x;
f=inline('(sqrt((2/3)*(((x*Lr)/3)-(x*x)+((2*x*x*x)/Lr)-((2*x*x*x*x)/(Lr*Lr))+(((2*x*x*x*x)/(Lr*Lr))*exp(-Lr/x))))-rg)');
if f(Lr,rg,Xo)*f(Lr,rg,Xf)>0
disp('The values you entered are not apropriate !')
PlotLpFunction;
Lp='unknown';
elseif f(Lr,rg,Xo)*f(Lr,rg,Xf)==0
if f(Lr,rg,Xo)==0
Lp=Xo;
elseif f(Lr,rg,Xf)==0
Lp=Xf;
end
elseif f(Lr,rg,Xo)*f(Lr,rg,Xf)<0
xi=(Xf-Xo)/2;
while abs(f(Lr,rg,xi))>Err
if f(Lr,rg,xi)*f(Lr,rg,Xf)<0
Xo=xi;
xi=(Xo+Xf)/2;
elseif f(Lr,rg,xi)*f(Lr,rg,Xf)>0
Xf=xi;
xi=(Xo+Xf)/2;
end
end
Lp=xi;
end
The code executes for me on the newest version of Matlab, other than the fact that I don't have the PlotLpFunction.
My initial impression was that you forgot to send the Lr (and all other argument) into you're inlined f function, very easy to fix by adding them as arguments to the inline function. You'll find the full usage in the official documentation.
The relevant part being
inline(expr,arg1,arg2,...) constructs an inline function whose input
arguments are specified by the strings arg1, arg2,.... Multicharacter
symbol names may be used.
but it seems to form the inline just fine by itself on both Matlab 2011b and 2008b, from context presumably. Answer is accepted now, so presumably that was the problem. Can anyone else reproduce his problem? If so please provide your Matlab version or other circumstances.
So far from what I have read this error can be caused by confusing or redundant naming within the program but I don't think that is the issue here since everything is declared clearly. From what I can see in this my issue is coming from the declaration of piecewise that is then being run through integration below and therefor the program is attempting to access a array cell that doesn't exist. If this is the case I have so far been stumped at how to fix this issue. Any assistance with this problem would be greatly appreciated.
syms t k n
fct = #(t)evalin(symengine,['subs(piecewise([0 <= t and t < 2,',...
'sin((Pi*t^2)/4)],[t <= 2 and t < 3, 5*t-t^2-6], [t <=3 and t < 4, 0],',...
'[Otherwise, t-4]),t=',regexprep(mat2str(x),' ',','),')']);
evalin(symengine,'assume(k,Type::Integer)');
a = #(fct,t,k) int(fct*cos(k*pi*t/4)/4,t,-2,8);
b = #(fct,t,k) int(fct*sin(k*pi*t/4)/4,t,-2,8);
FourierSeries = #(fct,t,n) a(fct,t,0)/4 + ...
symsum(a(fct,t,k)*cos(k*pi*t/4) + b(fct,t,k)*sin(k*pi*t/4),k,1,n);
pretty(FourierSeries(t,25,1))
ezplot(FourierSeries(t,25,1),-2,8)
hold on
ezplot(fct,-2,8)
hold off
title('Partial sum with n=25')
The complete error text is as follows:
??? Attempt to reference field of non-structure array.
Error in ==> sym.int at 56
r = mupadmex('symobj::intdef',f.s,x.s,a.s,b.s);
Error in ==> #(fct,t,k)int(fct*cos(k*pi*t/4)/4,t,-2,8)
Error in ==>
#(fct,t,n)a(fct,t,0)/4+symsum(a(fct,t,k)*cos(k*pi*t/4)+b(fct,t,k)*sin(k*pi*t/4),k,1,n)
Error in ==> FourierProgram at 16 pretty(FourierSeries(t,25,1))
This was asked long ago, but I'll provide an answer since one was never given.
As your error indicates, the issue is with this line and how the anonymous function a is called:
a = #(fct,t,k) int(fct*cos(k*pi*t/4)/4,t,-2,8);
The sym/int function expects the second argument (the variable with which the integration is performed with respect to) to be a symbolic variable. However, you're calling FourierSeries(t,25,1), which passes the value 25 as the integration variable.
This bit of code should replicate the issue in your version of Matlab (back in 2011 when this was asked):
syms t k;
int(t*cos(k*pi*t/4)/4,25,-2,8)
However, in R2015a I now get a different (and a bit clearer) error message:
Cannot integrate with respect to ''. The integration variable must be a symbolic variable.
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.
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:
Zooming in on a subpart of the graph:
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.