📄 readme
字号:
>>Not too bad: almost three times better than both native and mcc compiledMatlab.NOTES: Should there be an error during conversion, the user will begiven a choice whether to try to continue, or start a keyboardenvironment to try to see what the problem is. This (approximate - nocomments are included) line number of the *.m file will help to knowwhat line is in question and also provides feedback on the progress ofthe converter.As another example, consider the routine zsdmn2.m which computesexpansion coefficients for spheroidal wave functions. Again, usematlab2fmex_save to save a workspace:>> matlab2fmex_save('out=zsdmn2(0,10,200+200i,500,1,100,zeros(102,1));');>> First, let's run the original:>> tt=cputime;out=zsdmn2(0,10,200+200i,500,1,10000,zeros(10002,1));cputime-ttans = 0.64>>Now convert it:>> matlab2fmex('zsdmn2',[0 0 0 0 1 0 0 0 0 0]);And now run it:>> tt=cputime;out=zsdmn2(0,10,200+200i,500,1,10000,zeros(10002,1));cputime-ttans = 0.03>> This yields a better speedup:>> 0.64/.03 21.3333333333333REMARK: Matlab functions which don't have an equivalent fortran intrinsic anddo not yet have a conversion routine built in are dealt with in one oftwo ways:1) Call Matlab back from the converted file, or2) Use slatec to provide a few more functions.The second category contains functions such as the bessel functions (it is an ongoingprocess to convert all functions possible to native fortran throughlibraries). Obviuously, to use these the user must have the slatec and lapack librariesinstalled in their system somewhere.Note: some functions such as inv and fft are so optimized in Matlabthat they are intentionally left as callbacks as the compiled fortranwould not offer substantial performance increases.To illustrate, consider the next example which is gasket.m from the Matlab examplesdirectory, but slightly contrived in order to demonstrate some of the capabilities ofmatlab2fmex. imsize was added so that theImage output variable could be dynamically sized,and randsize was added as an input for the size of theRand. Without randsize, the size oftheRand would be statically defined. This procedure of putting in dummy variables isnecessary whenever an output or internal variable has to be sized depending on the inputvalues, but none of the input variables themselves are of the same size.function theImage = gasket(numPoints,imsize,randsize)%GASKET An image of a Sierpinski Gasket.theImage = zeros(1000,1000);corners = ([866 1;1 500;866 1000].')';startPoint = [866 1];theRand = ceil(rand(numPoints,1)*3);for i=1:numPoints startPoint = floor((corners(theRand(i),:)+startPoint)/2); theImage(startPoint(1),startPoint(2)) = 1;endplot(theRand);startPoint(1,1:2)=max(corners);disp(['startPoint=',num2str(startPoint)]);theImage(theImage>0)=asech(1/2);In Matlab this takes:>> n=5000000;imsize=zeros(1,1000);t=cputime;g=gasket(n,imsize,zeros(n,1));cputime-tstartPoint=866 1000ans = 10.46>> After adding imsize and randsize to the input variable list and savingthe workspace with>> n=500000;imsize=zeros(1,1000);>> matlab2fmex_save('g=gasket(n,imsize,zeros(n,1));')we use matlab2fmex:>> matlab2fmex('gasket');Converting --- gasket.m ==> gasket.f90 ==> gasket.mex Starting compilation of gasket.f Creating mexcallback module... Creating mexoperators module... Creating mexfunctions module...Calling mex to compile the output at gasket.f ==> mex gasket.f mexfunctions.f mexoperators.f mexcallback.f -lslatec -llapack >> Then we have:>> n=5000000;imsize=zeros(1,1000);t=cputime;g=gasket(n,imsize,zeros(n,1));cputime-t startPoint= 866.000000000000 1000.00000000000 ans = 1.46>> NOTE: The call to the Matlab function rand was converted as a callbackto Matlab, so that the rand statement is actually performed in theMatlab environment and the results will be exactly the same as if fromthe Matlab prompt. 'plot' was also called as a callback.REMARK: matlab2fmex uses the temporary varaibles mxTR1, mxTR2, ... andmxTC1, mxTC2, ... (as in the example above) when a converted functionreturns a result whose size is unknown when called (such as the matlabcallback rand, in gasket). This is to avoid memory leaks when using pointers as return objects in Fortran90. REMARK: One possible advantage when using matlab2fmex in that littleor no effort may be put into vectorizing the *.m file because a goodoptimizing Fortran90 compiler will optimize these things for you.Another example is internew.m, which is too long to list here,yet shows some of the different capabilities of matlab2fmex. Notable inthis example are: -- a single varaible on a line by itself (i on line 6) is displayed with its value by the mex-file as well. -- error messages are converted into fortran90 error message calls -- other converted function such as linspace, min, max.For internew.m we have:>> load internew;Z=ones(length(bf),length(bf));vs=zeros(pos^2,pos^2);as=zeros(1,pos+1);t=cputime;>> t=cputime;Z=internew(v,c,bf,bfdir,clim,E0,k,pos,omega,mu0,epsilon0,vs,as,Z);cputime-ti = 10i = 20i = 30ans = 6.85>> Now try matlab2fmex:>> matlab2fmex('internew');But I get some compiler errors:Converting --- internew.m ==> internew.f ==> internew.mexmatlab2fmex.m ==> mex internew.f mexfunctions.f mexoperators.f mexcallback.f f90: Error: internew.f, line 276: Each ac-value expression in an array-constructor must have the same type and type parameters. [PAD_ZP] pad_p=mxa((/pad_xp,pad_yp,pad_zp/))--------------------------------^f90: Error: internew.f, line 283: Each ac-value expression in an array-constructor must have the same type and type parameters. [PAD_ZPP] pad_pp=mxa((/pad_xpp,pad_ypp,pad_zpp/))-----------------------------------^f90: Error: internew.f, line 287: Each ac-value expression in an array-constructor must have the same type and type parameters. [SPACE_ZP] space_p=mxa((/space_xp,space_yp,space_zp/))--------------------------------------^... mex: compile of 'internew.f' failed.??? Error using ==> mexUnable to complete successfullyError in ==> /home/barrowes/compiler/matlab2fmex.mOn line 2099 ==> eval(['mex ',filenamef,' mexfunctions.f mexoperators.f mexcallback.f',libraries]);This is because the converter decided pad_zp, for example, was aninteger (1x1 variables with integer values are assigned asintegers), while it decided pad_xp and pad_yp were reals. Then whenfortran attempts to put them in the same array, it has an error. This problem can be solved by not allowing integers in the convertedroutine by setting want_in to 0 instead of 1 (default).>> matlab2fmex('internew',[0 0 0 0 1 0 0 0 0]); ^ | here is want_in set to 0Now we get no errors. Upon running the fortran90 mex file:>> load internew;Z=ones(length(bf),length(bf));vs=zeros(pos^2,pos^2);as=zeros(1,pos+1);t=cputime;Z=internew(v,c,bf,bfdir,clim,E0,k,pos,omega,mu0,epsilon0,vs,as,Z);cputime-t i 10.0000000000000 i 20.0000000000000 i 30.0000000000000 ans = 0.85About a 7-10 times speedup.To illustrate converting multiple *.m files into the same mex file,consider internew_sep.m. internew_sep.m calls a separate m-file internew_pad.m: pad_xp=internew_pad(bf,clim,pos,1,i,i1); pad_yp=internew_pad(bf,clim,pos,2,i,i1); pad_zp=internew_pad(bf,clim,pos,3,i,i1);internew_pad.m is:function pad=internew_pad(bf,clim,pos,dim,i,j);if dim==1 pad=abs(clim(bf(i,j),2)-clim(bf(i,j),1))/pos/2;elseif dim==2 pad=abs(clim(bf(i,j),4)-clim(bf(i,j),3))/pos/2;elseif dim==3 pad=abs(clim(bf(i,j),6)-clim(bf(i,j),5))/pos/2;endTo convert these, there must exist both internew_sep.mat andinternew_pad.mat workspace files in the same directory.Running as native Matlab takes about 8 seconds.To convert these functions to 1 mex file internew_sep.mex withinternew_pad included as a Fortran90 subroutine (again with no integers):matlab2fmex({'internew_sep' 'internew_pad'},[0 0 0 0 1 0 0 0 0 0]);Whereas before, the filename input was simply a string, now it is acell array of strings. If we wanted different converter flags for eachfunction we would specify matlab2fmex({'internew_sep' 'internew_pad'},{[0 0 0 0 1 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 1]});Now converting:>> matlab2fmex({'internew_sep' 'internew_pad'},[0 0 0 0 1 0 0 0 0]);Converting --- internew_sep.m ==> internew_sep.f ==> internew_sep.mexmatlab2fmex.mConverting --- internew_pad.m ==> internew_pad.f ==> internew_pad.mexMaking subroutinematlab2fmex. ==> mex internew_sep.f mexfunctions.f mexoperators.f mexcallback.f >> load internew_sep;Z=ones(length(bf),length(bf));vs=zeros(pos^2,pos^2);as=zeros(1,pos+1);t=cputime;Z=internew_sep(v,c,bf,bfdir,clim,E0,k,pos,omega,mu0,epsilon0,vs,as,Z);cputime-t i 10.0000000000000 i 20.0000000000000 i 30.0000000000000 ans = 0.71>> A sppedup of about 11 times.The subroutine (a function in this case due to the single output argument) is found in themodule mexfunctions in internew_sep.f90. One possible use for the converter would besimply to make Fortran90 subroutines from Matlab code. Note that all the dummy argumentsin these procedures are assumed shape real or complex arrays.In an effort to make the process of saving the workspace a littleeasier, I have written a small program matlab2fmex_save.m which helpin saving the workspace. Consider the function lqmns.m used in the vsph_pro.m program. On anormal run through lqmns.m some of the variables do not getinstantiated and thus a simple "save lqmns" at the end of the programwill cause an error when matlab2fmex tries to convert it (matlab2fmexneeds every possibly declared variable in the program to be in thesave file). Specifically, the following assignments should be made after atypical call to lqmns.m:qm1=1.1;qg0=qf0;qg1=qf1;qh0=qf0;qh1=qf1;qh2=qf2;l=2;q0l=1.1;q1l=1.1;qmk=1.1;km=1.1;Then the workspace should be saved.matlab2fmex_save works by inserting the line:%matlab2femx_saveinto lqmns.m, then matlab2fmex_save is called with a sample call tothe program lqmns.m as a string argument. matlab2fmex_save will thenexecute lqmns.m and save the workspace for you, optionally calling thelqmns_save.m script (if it exists and just after the %matlab2femx_saveinsertion or at the end) just before saving.So if we make a script lqmns_save.m which contains:qm1=1.1;qg0=qf0;qg1=qf1;qh0=qf0;qh1=qf1;qh2=qf2;l=2;q0l=1.1;q1l=1.1;qmk=1.1;km=1.1;and add:%matlab2femx_savesomewhere in lqmns.m (this line may be omitted if you would put it atthe end of the file anyway), and we now run:matlab2fmex_save('lqmns(0,20,1.5,zeros(21,1))')then lqmns.mat will be saved and conversion can proceed.8. REVISION HISTORY: See changelog
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -