How to compile Matlab class into C lib? - matlab

The origin of this question is from here How to use "global static" variable in matlab function called in c.
I'm trying to encapsulate the "global variable" into an object. However I don't know how to export the matlab class to c++ using MATLAB Compiler (mcc)
To do this I just tried the standard command
Matlab Command
mcc -W cpplib:Vowel4 -T link:lib Vowel4.m
Matlab Script
classdef Vowel4
properties
x
y
end
methods
Vowel4
A
B
end
end
The generated lib is actually stand-alone functions rather than c++ class.
How can I compile classes in Matlab into c++ classes?
I've been searching for an answer but didn't find one.
Obviously the matlab command is not suitable for this scenario. However I cannot find any information on building Matlab classes into c++ classes.
========================== Edit ========================
The actual cpp code is as follows: #Alan
mclInitializeApplication(NULL, 0);
loadDataInitialize();
soundByCoefInitialize();
loadData();
mwArray F(4, 1, mxDOUBLE_CLASS);
float test[4];
for ( ;; ){
const Frame frame = controller.frame();
const FingerList fingers = frame.fingers();
if ( !fingers.empty() ){
for ( int i = 0; i < 4; i ++ ){
double v = fingers.count() > i ? (fingers[i].tipPosition().y / 50) - 2 : 0;
F(i+1,1) = v;
test[i] = v;
cout << v << ' ';
}
cout << endl;
soundByCoef(F);
}
}
Here the matlabA() corresponds to the loadData(), which loads the data, and soundByCoef(F) corresponds to the matlabB(), which do the job in the main loop.

As noted by Alan, I was only suggesting using handle class as a container for your global variables (with the benefit that such an object would be passed by reference). The created object is not intended to be directly manipulated by your C++ code (it will be stored in the generic mxArray/mwArray C/C++ struct).
As far as I know, you cannot directly compile classdef-style MATLAB classes into proper C++ classes when building shared libraries using the MATLAB Compiler. It only supports building regular functions. You could create functional interfaces to MATLAB class member methods, but that's a different story...
Perhaps a complete example would help illustrate the idea I had in mind. First lets define the code on the MATLAB side:
GlobalData.m
This is the handle class used to store the global vars.
classdef GlobalData < handle
%GLOBALDATA Handle class to encapsulate all global state data.
%
% Note that we are not taking advantage of any object-oriented programming
% concept in this code. This class acts only as a container for publicly
% accessible properties for the otherwise global variables.
%
% To manipulate these globals from C++, you should create the class API
% as normal MATLAB functions to be compiled and exposed as regular C
% functions by the shared library.
% For example: create(), get(), set(), ...
%
% The reason we use a handle-class instead of regular variables/structs
% is that handle-class objects get passed by reference.
%
properties
val
end
end
create_globals.m
A wrapper function that acts as a constructor to the above class
function globals = create_globals()
%CREATE_GLOBALS Instantiate and return global state
globals = GlobalData();
globals.val = 2;
end
fcn_add.m, fcn_times.m
MATLAB functions to be exposed as C++ functions
function out = fcn_add(globals, in)
% receives array, and return "input+val" (where val is global)
out = in + globals.val;
end
function out = fcn_times(globals, in)
% receives array, and return "input*val" (where val is global)
out = in .* globals.val;
end
With the above files stored in current directory, lets build the C++ shared library using the MATLAB Compiler:
>> mkdir out
>> mcc -W cpplib:libfoo -T link:lib -N -v -d ./out create_globals.m fcn_add.m fcn_times.m
You should expect the following generated files among others (I'm on a Windows machine):
./out/libfoo.h
./out/libfoo.dll
./out/libfoo.lib
Next, we could create a sample C++ program to test the library:
main.cpp
// Sample program that calls a C++ shared library created using
// the MATLAB Compiler.
#include <iostream>
using namespace std;
// include library header generated by MATLAB Compiler
#include "libfoo.h"
int run_main(int argc, char **argv)
{
// initialize MCR
if (!mclInitializeApplication(NULL,0)) {
cerr << "Failed to init MCR" << endl;
return -1;
}
// initialize our library
if( !libfooInitialize() ) {
cerr << "Failed to init library" << endl;
return -1;
}
try {
// create global variables
mwArray globals;
create_globals(1, globals);
// create input array
double data[] = {1,2,3,4,5,6,7,8,9};
mwArray in(3, 3, mxDOUBLE_CLASS, mxREAL);
in.SetData(data, 9);
// create output array, and call library functions
mwArray out;
fcn_add(1, out, globals, in);
cout << "Added matrix:\n" << out << endl;
fcn_times(1, out, globals, in);
cout << "Multiplied matrix:\n" << out << endl;
} catch (const mwException& e) {
cerr << e.what() << endl;
return -1;
} catch (...) {
cerr << "Unexpected error thrown" << endl;
return -1;
}
// destruct our library
libfooTerminate();
// shutdown MCR
mclTerminateApplication();
return 0;
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)run_main, 0, NULL);
}
Lets build the standalone program:
>> mbuild -I./out main.cpp ./out/libfoo.lib -outdir ./out
And finally run the executable:
>> cd out
>> !main
Added matrix:
3 6 9
4 7 10
5 8 11
Multiplied matrix:
2 8 14
4 10 16
6 12 18
HTH

Following on from the thread in the previous post, the suggestion wasn't to wrap your functions in a class, but rather to use a class to pass about the global variable which compiling leaves you unable to use.
classdef Foo < handle
properties
value
end
methods
function obj = Foo(value)
obj.value = value;
end
end
end
Note: the class Foo extends the handle class in order to make it pass by reference, rather than pass by value. See: the comparison between handle and value classes.
function foo = matlabA()
foo = new Foo(1);
end
function matlabB(foo)
foo.value
end
As far as I know, the matlab compiler doesn't compile the code as such, but rather packages it with a copy of the MATLAB Component Runtime and writes some wrapper functions to handle invoking said runtime on the code from c/c++.
I would recommend avoiding jumping back and forth between matlab and c/c++ too much; there is bound to be some overhead to converting the datatypes and invoking the MCR. All I really use it for is wrapping up a complex but self-contained matlab script (i.e.: doesn't need to interact with the c/c++ code mid way through said script) as a function, or packaging up code for deployment to environments which don't have a full copy of matlab.
As an interesting side note: if you are calling C++ from within Matlab, and that C++ code needs access to a global variable, things are much easier. You can simply do this by wrapping your C++ code into a mexFunction and compiling that. In the places you need to access a variable which is in the Matlab workspace, you can do so using the mexGetVariablePtr which will return a read-only pointer to the data. The variable you are accessing can be in either the global workspace, or that of the function which called your mexFunction.
With this approach I would suggest liberally comment the variable that you are getting in both the C++ and Matlab code, as the link between them may not be obvious from the Matlab side; you wouldn't want someone to come along later, edit the script and wonder why it had broken.
In this case it seems that the C++ side doesn't really need access to the data, so you could refactor it to have matlab do the calling by wrapping the "get current position of fingers" code into a mexFunction, then have matlab do the loop:
data = loadData();
while(~stop) {
position = getFingerPositionMex();
soundByCoef(position, data);
}
Assuming you don't modify the data within soundByCoef Matlab will use pass by reference, so there will be no copying of the large dataset.

Related

System Verilog to Specman E

What is the equivalent syntax in Specman E for $readmemh(file,array) and similar system tasks and functions in System verilog?
I am working in converting the existing System verilog code into Specman E ,I have converted and implemented most of the concepts except few system methods like below .Please help me to implement methods like below in Specman E.
$readmemh(file_s,data_2d_i);//For converting SV code into Specman E
In the vr_ad Package there is an equivalent method. Assuming you have a vr_ad_mem object called data_2d_i, you can e.g. call
data_2d_i.readmemh(file_s,0,1000,0,1000);
To read addresses 0..1000 from that file into memory.
Example:
import vr_ad/e/vr_ad_top;
extend sys {
mem: vr_ad_mem;
keep mem.addressing_width_in_bytes == 1;
keep mem.size == 1000;
run() is also {
var data_2d_l: list of byte;
-- read first 16 bytes of mem-file and store the result in a list
mem.readmemh("mem.txt", 0, 15, 0, 15);
data_2d_l = mem.fetch(0, 16);
print data_2d_l;
};
};

Call a script with definitions in a function

We have a script that defines values to names similar to #define in c. For example:
script.m:
ERR_NOERROR = 0;
ERR_FATAL = 1;
This script already exists and is used for value replacement when reading data from files.
Now we have a function (or more) that does some analysis and we would like to use the same definition in this function to avoid magic numbers. But when the script is called from the function we get an error.
Attempt to add "ERR_NOERROR" to a static workspace.
See MATLAB Programming, Restrictions on Assigning to Variables for details.
And this does not help much in the understanding of the problem.
The question is how can we make these definitions visible/usable in the functions with having to copying it every time.
Example:
function foo = bar(a)
run(script.m) %also tried running it without the run command
if a == ERR_NOERROR
foo = 5;
else
foo = 6;
end
end
edit:
There was a nested function,below in the function which I was not aware of. This explains the problem.
This kind of scoping error happens when you use nested or anonymous function within a function. The solution is well documented.
To your case, you can avoid nested function, or "Convert the script to a function and pass the variable using arguments", as the documentation suggests.
EDIT: I should have made it clear that the error occurs even if the script is not called within the nested function. Similar scenario is that, in debug mode (by setting up a break point), it will be an error if one tries to create a temporal variable to test something.
This is not a direct answer, rather a recommendation to switch to another method, which will not be mixing scope and workspace.
Instead of defining your constant in a script, you could make a class containing only constant properties. ex: code for error_codes.m:
classdef error_codes
% ---------------------------------------------------------------------
% Constant error code definition
% ---------------------------------------------------------------------
properties (Constant = true)
noerror = 0 ;
fatal = 1 ;
errorlvl2 = 2 ;
errorlvl3 = 3 ;
warning = -1 ;
% etc ...
end
end
I use this style for many different type of constants. For tidiness, I groups them all in a Matlab package directory (The directories which starts with a + character.
The added benefit of using constant class properties is the safety that the values cannot be changed in the middle of the code (your variables defined in a script could easily be overwritten by a careless user).
So assuming my file error_codes.m is placed in a folder:
\...somepath...\+Constants\error_codes.m
and of course the folder +Constants is on the MATLAB path, then to use it as in your example, instead of calling the script, just initialise an instance of the class, then use the constant values when you need them:
function foo = bar(a)
ERR = Constants.error_codes ;
if a == ERR.noerror
foo = 5;
else
foo = 6;
end
or it can works in switch statement too:
switch a
case ERR.noerror
foo = 5 ;
case ERR.warning
foo = 42 ;
case ERR.fatal
foo = [] ;
end

External Functions: Alternative Method to use .dll from a C-script

This is a companion question to External Functions: Reference headers in C-script to compiled dll.
That stack overflow question is using a Modelica external function call to a c-script. That c-script then uses c-functions contained within a .dll. Below is the initial preferred method I had attempted and a working attempt that I do not prefer.
Initial Attempt:
The following code would not work. My assumption was since I loaded the .dll Library libgsl in Modelica I could then simply use headers in the C-script to use function calls from that .dll. However, the dslog.txt file indicated that it couldn't recognize gsl_sf_bessel_j0. Apparently, the C-script doesn't know anything about the libgsl.dll that I specified in Modelica.
Modelica Function:
function chirp
input Modelica.SIunits.AngularVelocity w_start;
input Modelica.SIunits.AngularVelocity w_end;
input Real A;
input Real M;
input Real t;
output Real u "output signal";
external "C" u=chirp(w_start,w_end,A,M,t)
annotation(Library="libgsl", Include="#include \"chirp.c\"");
end chirp;
C-Script:
#include <gsl/gsl_sf_bessel.h>
double chirp2(double w1, double w2, double A, double M, double time)
{
double res;
double y;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
y = gsl_sf_bessel_j0(res);
return y;
}
Working Attempt:
In order to use a .dll in an external function call using a C-script I found it necessary to independently load the library using the LoadLibrary command.
Is this method really necessary? This is much more complicated that my initial attempt I hoped would work where I was thinking Modelica contained the necessary "know-how" to load the .dll.
Bonus: It appears there exists a way to send error messages back to Modelica. void ModelicaVFormatError(const char* string, va_list). Know of a reference example of its usage so I can replace the printf statements which don't seem to send anything back to Modelica?
Modelica Function:
function chirp
input Modelica.SIunits.AngularVelocity w_start;
input Modelica.SIunits.AngularVelocity w_end;
input Real A;
input Real M;
input Real t;
input String fileName= Modelica.Utilities.Files.loadResource("modelica://ExternalFuncTest/Resources/Library/libgsl.dll") "Full file name for GSL library";
output Real u "output signal";
external "C" u=chirp(w_start,w_end,A,M,t)
annotation(Include="#include \"chirp.c\""); // <-- Removed Library reference
end chirp;
C-Script:
#include <windows.h>
#include <stdio.h>
typedef double (__cdecl *BESSEL)(const double);
double chirp3(double w1, double w2, double A, double M, double time, const char* fileName)
{
HINSTANCE hinstLib;
BESSEL bessel_J0;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(fileName);
// If the handle is valid, try to get the function address.
double res;
double y = 0;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
if (hinstLib != NULL)
{
bessel_J0 = (BESSEL) GetProcAddress(hinstLib, "gsl_sf_bessel_j0");
// If the function address is valid, call the function.
if (NULL != bessel_J0)
{
fRunTimeLinkSuccess = TRUE;
printf("Success loading library method.\n"); //<-- Alternative to send message back to Modelica log file?
y = bessel_J0(res);
} else
{
printf("Failed to load library\n"); //<-- Alternative to send message back to Modelica log file?
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
return y;
}

Deploy an matlab file to executable

I want to deploy an m file into an executable. I am using mcc command: mcc -m epidemic.m. Epidemic is my function which takes no arguments and returns a vector and write that vector to txt. Mcc creates epidemic.exe and when I am running that exe it creates the txt file however it seems that it doesnt return values (the return value of .exe). I am trying to run the exe from matlab using:
cmd = ['epidemic.exe '];
system(cmd);
It return cmdout " and status 0. How can I take the returned values of the .exe?
When you compile matlab code like:
function [out1, out2] = epidemic(in1, in2, in3)
%[
...
%]
to standalone (mcc -m epidemeic.m), Matlab produces somehow the following pseudo c-code and compiles it to .exe:
int main(int argc, char** argv)
{
// Load compiled code produced by mcc
HMCRInstance* hInst = loadByteCodeProducedByMccFromResources();
// Similar to have wrote in matlab "epidemic(argv[0], argv[1], ...)"
// 1) Without asking for any argument output
// 2) Argument inputs are passed as strings
int errorCode = mclFevalFromExeArg(hInst, "epidemic", argc, argv);
return errorCode; // only indicates if call to 'mclFEvalFromExeArg'
// succeded, it does not relate to out1, out2 at all.
}
NB: If you want to see the exact code produced by mcc, use mcc -W main -T codegen epidemic.m
So, directly compiling to standalone, you cannot work with outputs of your Matlab function. If you need to play around with output arguments of epidemic, either
[Simple solution] Consider saving outputs to files or display them to shell console using disp (NB: you can use isdeployed in your .m file to check if you're running from matlab or from compiled code).
[Advanced solution] Consider compiling your code to shared library (mcc -l epidemic.m) instead of standalone (mcc -m epidemeic.m)
NB: When you compile your code to shared library, mcc will produce a dll that exports the following function:
extern LIB_epidemeic_C_API
bool MW_CALL_CONV mlxEpidemic(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
nrhs/prhs are the number of input arguments and their values (as mxArray type). And nlhs/plhs are the ouput arguments you want to have when calling epidemic. Up to you to do the marshaling between mxArray and equivalent C native type.
EDIT
As you indicate that epidemic returns a vector of values, you can display them from standalone like this:
function [output] = epidemic(v1, v2, v3)
%[
% When called from system cmd line, v1, v2, v3 are passed
% as string. Here is how to convert them to expected type if required
if (ischar(v1)), v1 = str2double(v1); end
if (ischar(v2), v2 = str2double(v2); end
if (ischar(v3)), v3 = str2double(v3); end
...
output = ...;
...
if (isdeployed())
disp(output);
end
%]
An exe does not have a return value, you need to find another way to transport the data back, for example via console outputs or text files. What you get is the error code and error message.

cannot update class definition in Matlab

I am running into an infuriating problem with Matlab, and an earlier answer to apparently the same problem didn't help me, unfortunately. I apologize that the question is rather long - you need quite a bit of information to reproduce the problem (I tried to trim it as much as I could...)
The problem is this: No matter what I do, after I have used a class I cannot "make Matlab forget". Values used seem to be persistent, and edits to the class definition won't "stick". In the latter case, the error message is:
Warning: The class file for 'myClass' has been changed; but the change
cannot be applied because objects based on the old class file still
exist. If you use those objects, you might get unexpected results. You
can use the 'clear' command to remove those objects. See 'help clear'
for information on how to remove those objects.
I get that message even after
>> clear all
>> clear functions
>> clear ans
Somehow the class definition is persistent despite my attempts to clear it. To make matters worse, when I modify a value of an instance of the class, then clear it, the value is somehow not "forgotten". To illustrate, here is the source code of myClass:
% a simple class definition that shows the problem that I cannot
% figure out how to redefine a class without restarting Matlab
classdef myClass < handle
properties
precursors = {'none'};
numPre = {1};
value = 1;
end
methods
function obj = myClass(pre, num, val)
% constructor
if nargin > 0
obj.precursors = pre;
obj.numPre = num;
obj.value = val;
end
end
function v = sumVal(obj)
% find the sum of the value of all precursors
n = numel(obj.precursors);
v = 0;
for ii = 1:n
pc = obj.precursors{ii};
if isa(pc, 'myClass')
if ii==1
v = 0;
end
v = v + sumVal(pc) * obj.numPre{ii};
else
v = obj.value;
end
end
end
end
% only the following named instances may exist:
enumeration
grandpa ({'none'}, {1}, 1)
father ({myClass.grandpa}, {3}, -1)
son ({myClass.father}, {2}, -1)
end
end
In a fresh instance of Matlab, I do the following:
>> son = myClass.son;
>> sumVal(son)
ans =
6
>> grandpa = myClass.grandpa;
>> grandpa.value = 5;
>> sumVal(son)
ans =
30
So far, so good. The sumVal function discovers the fathers and grandfathers, and the sumVal is computed correctly (6 * 1 in the first case, 6 * 5 in the second case).
Now I delete "everything" (I think):
>> clear all
>> clear functions
>> clear ans
And I create just one variable:
>> son = myClass.son;
Now comes the kicker - the unexpected answer
>> sumVal(son)
ans =
30
When I inspect the variables loaded, I find
>> whos
Name Size Bytes Class Attributes
son 1x1 112 myClass
There is no grandpa instance, and the class definition file was not touched. Yet, the value of grandpa (which I created, then deleted) is somehow persistent.
And when I make a small change to the myClass.m file, and try to create a new variable (after a clear all), I get the message shown above. All of which leads me to my question:
Where is Matlab hiding an instance of my class so that variables are persistent after a clear all, and how do I clear the workspace (without restarting) so the class definition is "reset"?
I don't know if it matters, but I'm using Matlab 7.14.0.739 (R2012a)
You have an intermediate instance myClass.father that is not being destroyed by MATLAB. You have to deleteit yourself
>> clear grandpa
>> delete(son.precursors{1})
>> clear son
>> clear classes
>> son = myClass.son
son =
son
>> sumVal(son)
ans =
6
Edit:
Alternatively, you can add a destructor to your class
function delete(obj)
if isa(obj.precursors{1}, 'myClass')
delete(obj.precursors{1});
end
end
and use delete(son) instead of leaving it to clear function to destroy. You can extend this to your case and recursively delete all instances in your tree.
Those instances are "hiding" in the myClass enumeration class itself. Matlab is storing a reference to each of those named instances so when you reference them like myClass.father you get the same object back, instead of it constructing a new one. Probably similar to how values are stored in Constant properties on classes.
If you have any other classes that refer to the myClass.xxx enumerated instances in Constant properties, enumerations, or persistent variables, they could also be holding on to references to them.
Try doing clear classes a few times in a row instead of just once.
To help debug this, you could put a couple debugging printf() statements in the constructor and destructor for this class, so you can see when the instances are really created and cleaned up.
function obj = myClass(pre, num, val)
% constructor
if nargin > 0
obj.precursors = pre;
obj.numPre = num;
obj.value = val;
end
printf('myClass: created (%d, %d, nargin=%d)\n', obj.numPre, obj.value, nargin);
end
function delete(obj)
printf('myClass: deleting (%d, %d)\n', obj.numPre, obj.value);
end