MATLAB parfor and C++ class mex wrappers (copy constructor required?) - oop

I'm trying to wrap a C++ class in a matlab mex wrapper using the approach outlined here. Basically, I have an initialization mex file which returns a C++ object handle:
handle = myclass_init()
I can then pass this to another mex file (e.g. myclass_amethod) which use the handle to call class methods, then ultimately to myclass_delete to free the C++ object:
retval = myclass_amethod(handle, parameter)
myclass_delete(handle)
I've wrapped this up in a MATLAB class for ease of use:
classdef myclass < handle
properties(SetAccess=protected)
cpp_handle_
end
methods
% class constructor
function obj = myclass()
obj.cpp_handle_ = myclass_init();
end
% class destructor
function delete(obj)
myclass_delete(obj.cpp_handle_);
end
% class method
function amethod(parameter)
myclass_amethod(obj.cpp_handle_, parameter);
end
end
end
Problem: this doesn't work in parallel code
This works fine in non-parallel code. However, as soon as I call it from within a parfor:
cls = myclass();
parfor i = 1:10
cls.amethod(i)
end
I get a segfault, as a copy of the class is made in the parfor loop (in each worker) but as each worker is a separate process the C++ object instance is not copied, leading to an invalid pointer.
I tried initially to detect when each class method was running in a parfor loop, and in those cases reallocate the C++ object too. However, as there is no way to check whether an object has been allocated for the current worker yet or not, this results in multiple reallocations and then just one delete (when the worker exits) resulting in a memory leak (see appendix at bottom of question for details).
Attempted solution: copy constructors and using matlab.mixin.Copyable
In C++, the way to handle this would be copy constructors (so that the C++ object is only reallocated once when the wrapper MATLAB class is copied). A quick search brings up the matlab.mixin.Copyable class type which seems to provide the required functionality (i.e. deep copies of MATLAB handle classes). Therefore, I've tried the following:
classdef myclass < matlab.mixin.Copyable
properties(SetAccess=protected)
cpp_handle_
end
methods
function obj = myclass(val)
if nargin < 1
% regular constructor
obj.cpp_handle_ = rand(1);
disp(['Initialized myclass with handle: ' num2str(obj.cpp_handle_)]);
else
% copy constructor
obj.cpp_handle_ = rand(1);
disp(['Copy initialized myclass with handle: ' num2str(obj.cpp_handle_)]);
end
end
% destructor
function delete(obj)
disp(['Deleted myclass with handle: ' num2str(obj.cpp_handle_)]);
end
% class method
function amethod(obj)
disp(['Class method called with handle: ' num2str(obj.cpp_handle_)]);
end
end
end
testing this class as above, i.e.:
cls = myclass();
parfor i = 1:10
cls.amethod(i)
end
Results in the output:
Initialized myclass with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Class method called with handle: 0.65548
Deleted myclass with handle: 0.65548
Deleted myclass with handle: 0.65548
Deleted myclass with handle: 0.65548
In other words, it seems that the copy constructor is not called when spawning workers for the parfor. Does anyone have any pointers as to what I am doing wrong, or whether there is some way to achieve the desired behaviour of reinitializing the C++ object handle when the MATLAB wrapper class is copied?
Alternative approach: detecting when running on worker
Just for reference, here is the alternative approach I'm using reallocating when in a worker:
classdef myclass < handle
properties(SetAccess=protected)
cpp_handle_
end
methods
function obj = myclass(val)
obj.cpp_handle_ = rand(1);
disp(['Initialized myclass with handle: ' num2str(obj.cpp_handle_)]);
end
% destructor
function delete(obj)
disp(['Deleted myclass with handle: ' num2str(obj.cpp_handle_)]);
end
% class method
function amethod(obj)
obj.check_handle()
disp(['Class method called with handle: ' num2str(obj.cpp_handle_)]);
end
% reinitialize cpp handle if in a worker:
function check_handle(obj)
try
t = getCurrentTask();
% if 'getCurrentTask()' returns a task object, it means we
% are running in a worker, so reinitialize the class
if ~isempty(t)
obj.cpp_handle_ = rand(1);
disp(['cpp_handle_ reinitialized to ' num2str(obj.cpp_handle_)]);
end
catch e
% in case of getCurrentTask() being undefined, this
% probably simply means the PCT is not installed, so
% continue without throwing an error
if ~strcmp(e.identifier, 'MATLAB:UndefinedFunction')
rethrow(e);
end
end
end
end
end
and the output:
Initialized myclass with handle: 0.034446
cpp_handle_ reinitialized to 0.55625
Class method called with handle: 0.55625
cpp_handle_ reinitialized to 0.0048098
Class method called with handle: 0.0048098
cpp_handle_ reinitialized to 0.58711
Class method called with handle: 0.58711
cpp_handle_ reinitialized to 0.81725
Class method called with handle: 0.81725
cpp_handle_ reinitialized to 0.43991
cpp_handle_ reinitialized to 0.79006
cpp_handle_ reinitialized to 0.0015995
Class method called with handle: 0.0015995
cpp_handle_ reinitialized to 0.0042699
cpp_handle_ reinitialized to 0.51094
Class method called with handle: 0.51094
Class method called with handle: 0.0042699
Class method called with handle: 0.43991
cpp_handle_ reinitialized to 0.45428
Deleted myclass with handle: 0.0042699
Class method called with handle: 0.79006
Deleted myclass with handle: 0.43991
Deleted myclass with handle: 0.79006
Class method called with handle: 0.45428
As can be seen above, a reallocation does indeed now occur when running in a worker. However, the destructor is only called once for every worker regardless of how many time the C++ class was reallocated, resulting in a memory leak.
Solution: using loadobj
The following works:
classdef myclass < handle
properties(SetAccess=protected, Transient=true)
cpp_handle_
end
methods(Static=true)
function obj = loadobj(a)
a.cpp_handle_ = rand(1);
disp(['Load initialized encoder with handle: ' num2str(a.cpp_handle_)]);
obj = a;
end
end
methods
function obj = myclass(val)
obj.cpp_handle_ = rand(1);
disp(['Initialized myclass with handle: ' num2str(obj.cpp_handle_)]);
end
% destructor
function delete(obj)
disp(['Deleted myclass with handle: ' num2str(obj.cpp_handle_)]);
end
% class method
function amethod(obj)
disp(['Class method called with handle: ' num2str(obj.cpp_handle_)]);
end
end
end

When you pass an object instance into the body of a PARFOR loop, the behaviour is the same as if you'd saved it to a file, and then loaded it again. The simplest solution is probably to mark your cpp_handle_ as Transient. Then, you need to implement SAVEOBJ and LOADOBJ to safely transport your data. See this page for more about customising the save/load behaviour of your class.

Related

Instantiating an object within the object declaration in kotlin

While browsing through kotlin documentation at object expressions and declarations I came across this snippet
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create()
In line 3, the create function instantiates an object MyClass()
In last line however, to call the create we already need MyClass object (don't we?).
My question is: At what point does the MyClass comes into existence?
The invocation val instance = MyClass.create() is independent of an instance of MyClass, you simply use the type as a qualifier for the method (it's like static methods in Java). Note that you can also write MyClass.Factory.create(), the companion's name is redundant when calling it from Kotlin though.
In last line however, to call the create we already need MyClass object (don't we?).
No, the last line calls .create() on the companion object of MyClass. The companion object is an instance of a separate class (it is not MyClass) and is initialized before the class is first used, so you don't need an instance of MyClass to call .create().
Note that, syntactically, .create() is called on the MyClass class name, not on an ordinary exppression like MyClass() constructor call or a myClass variable.

Init method inheritance

If I have abstract class A with an init method:
abstract class A(){
init {
println("Hello")
}
}
And then class B that extends A
class B(): A()
If I instantiate B like this
fun main(args: Array<String>){
B()
}
Does the init method in A still get run and Hello gets printed?
And if not, what do I need to do to have the init method of A get run?
Yes, an init block of a base class gets run when the derived class instance is initialized.
In Kotlin, similarly to Java, an instance of a class is constructed in the following way:
An object is allocated.
The constructor of the class is called. (a)
If the class has a superclass, the superclass constructor is called before the class construction logic is executed; (i.e., the point (a) is executed recursively for the superclass, then the execution continues from here)
If the class has property initializers or init blocks, they are executed in the same order as they appear in the class body;
If the constructor has a body (i.e. it is a secondary constructor) then the body is executed.
In this description, you can see that, when B is constructed, the constructor of A is called before B initialization logic is executed, and, in particular, all init blocks of A are executed.
(runnable demo of this logic)
A small remark on terminology: init block is not actually a separate method. Instead, all init blocks together with member property initializers are compiled into the code of the constructor, so they should rather be considered a part of the constructor.

Matlab equivalent to calling inside static class

Confer the following code:
classdef highLowGame
methods(Static)
function [wonAmount, noGuesses] = run(gambledAmount)
noGuesses = 'something';
wonAmount = highLowGame.getPayout(gambledAmount, noGuesses); % <---
end
function wonAmount = getPayout(gambledAmount, noGuesses)
wonAmount = 'something';
end
end
end
Is there a way to call a static method of the same class (inside a static) method without having to write the class name? Something like "self.getPayout(...)" - in case the class turns out to get to 500 lines and I want to rename it.
Not an answer to your question directly, but it's worth noting that you can also put "local functions" after the end of your classdef block in your class.m file, and these behave like private static methods, but you do not need to invoke them using the class name. I.e.
% myclass.m
classdef myclass
methods ( Static )
function x = foo()
x = iMyFoo();
end
end
end
function x = iMyFoo()
x = rand();
end
% end of myclass.m
As far as I can tell, "no" with a "but". In general, you can only specify the static method with the class name. However, you can fake your way around the restriction since MATLAB has feval:
classdef testStatic
methods (Static)
function p = getPi() %this is a static method
p = 3.14;
end
end
methods
function self = testStatic()
testStatic.getPi %these are all equivalent
feval(sprintf('%s.getPi',class(self)))
feval(sprintf('%s.getPi',mfilename('class')))
end
end
end
Here, class(self) and mfilename both evaluate to 'testStatic', so the functions above end up evaluating 'testStatic.getPi'.
Or, alteratively, you can write a non-static method, self.callStatic; then always use that. Inside that, just call testStatic.getPi. Then you'll only need to change that one line.

Dependent observable property in Matlab. Does it work?

In Matlab class it seems to be syntactically correct to declare property that is Dependent (computed not stored) and Observable in the same time. Consider code
properties (Access = private)
instanceOfAnotherClass
end
properties (SetAccess = private, Dependent, SetObservable)
propertyTwo
end
methods
function val = get.propertyTwo(this)
val = this.instanceOfAnotherClass.propertyOne;
end
end
Does this work as expected? That is, if the property propertyOne of an object stored in instanceOfAnotherClass is changed is there property change event triggered by propertyTwo? Note that propertyOne is not Observable.
Edit:
It does not work (as I expected). 'PostSet' event is not triggered. So how do I deal with this kind of situation? Is there a better solution then to create propertyTwo as a non Dependent and set it to the same value as 'propertyOne' every time 'propertyOne' changes?
Edit2:
In reaction to Amro's edit of his answer I will explain situation more complex.
Consider this 2 classes:
classdef AClass < handle
properties
a
end
end
classdef BClass < handle
properties (Access = private)
aClassInst
end
properties (Dependent, SetObservable, SetAccess = private)
b
end
methods
function this = BClass(aClass)
this.aClassInst = aClass;
end
function val = get.b(this)
val = this.aClassInst.a;
end
end
end
The class that uses all this code should not get access to AClass. It interacts only with instance of BClass and wants to listen to changes of property b. however if I make property a of AClass observable that would not solve my problem, would it? The 'PostSet' events are not going to propagate to property b, are they?
It might be syntactically correct, but the listener callback will never execute. Example:
classdef MyClass < handle
properties (Access = public)
a
end
properties (SetAccess = private, Dependent, SetObservable)
b
end
methods
function val = get.b(this)
val = this.a;
end
end
end
Now try:
c = MyClass();
lh = addlistener(c, 'b', 'PostSet',#(o,e)disp(e.EventName));
c.a = 1;
disp(c.b)
As you can see the 'PostSet' callback is never executed.
EDIT
The way I see it, SetObservable should really be set on a not b. Its because b is read-only and can only change if a changes. Now the PostSet event would notify us that both properties have changed.
Use the same example I used above, simply move SetObservable from b to a. Of course now you listen to the event as:
lh = addlistener(c, 'a', 'PostSet',#(o,e)disp(e.EventName));
EDIT#2
Sorry I didn't pay attention to the fact that you have composition (BClass has an instance of AClass as private property).
Consider this possible solution:
AClass.m
classdef AClass < handle
properties (SetObservable)
a %# observable property
end
end
BClass.m
classdef BClass < handle
properties (Access = private)
aClassInst %# instance of AClass
lh %# event listener on aClassInst.a
end
properties (Dependent, SetAccess = private)
b %# dependent property, read-only
end
events (ListenAccess = public, NotifyAccess = private)
bPostSet %# custom event raised on b PostSet
end
methods
function this = BClass(aClass)
%# store AClass instance handle
this.aClassInst = aClass;
%# listen on PostSet event for property a of AClass instance
this.lh = addlistener(this.aClassInst, 'a', ...
'PostSet', #this.aPostSet_EventHandler);
end
function val = get.b(this)
val = this.aClassInst.a;
end
end
methods (Access = private)
function aPostSet_EventHandler(this, src, evt)
%# raise bPostSet event, notifying all registered listeners
notify(this, 'bPostSet')
end
end
end
Basically we set property a of AClass as observable.
Next inside the constructor of BClass, we register a listener for the AClass instance passed to listen on property a changes. In the callback we notify listeners of this object that b has changed as well
Since we can't really raise a PostSet manually, I created a custom event bPostSet which we raise in the previous callback function. You can always customize the event data passed, refer to the documentation to see how.
Here is a test case:
%# create the objects
a = AClass();
b = BClass(a);
%# change property a. We will not recieve any notification
disp('a.a = 1')
a.a = 1;
%# now lets listen for the 'bChanged' event on b
lh = addlistener(b, 'bPostSet',#(o,e) disp('-- changed'));
%# try to change the property a again. We shall see notification
disp('a.a = 2')
a.a = 2;
%# remove event handler
delete(lh)
%# no more notifications
disp('a.a = 3')
a.a = 3;
The output was:
a.a = 1
a.a = 2
-- changed
a.a = 3
Notice how we only interact with the BClass instance when we register our listener. Of course since all classes derive from handle class, the instance a and the private property aClassInst both refer to the same object. So any changes to a.a are immediately reflected on b.aClassInst.a, this causes the internal aPostSet_EventHandler to execute, which in turn notify all registered listeners to our custom event.

How can I keep -Xcheckinit from interfering with the deserialization of Scala objects?

When using the -Xcheckinit compiler option and implementing my own readObject method in a serializable class, I can't call any accessor functions on fields declared in the body of my class from the readObject method. Fields declared as constructor arguments are ok. When I do try to access a field declared in the class body, I get a scala.UninitializedFieldError.
That is, the following code fails on println(y) in the readObject method, even after y has been set in the previous line!
#serializable case class XYPointWithRWAndPrint(var x: Int) {
var y = 0
#throws(classOf[java.io.IOException])
private def writeObject(out: java.io.ObjectOutputStream) {
out.writeInt(x)
out.writeInt(y)
}
#throws(classOf[java.io.IOException])
#throws(classOf[ClassNotFoundException])
private def readObject(in: java.io.ObjectInputStream) {
x = in.readInt()
println(x)
y = in.readInt()
println(y)
}
}
Why?
When using the -Xcheckinit compiler option, the compiler creates a bitmap field that it uses to check initialization.
public volatile int bitmap$0;
In the accessors, the compiler checks the bitmap:
public int y(){
if ((this.bitmap$0 & 0x1) != 0){ return this.y; }
throw new UninitializedFieldError("Uninitialized field: Test.scala: 2".toString());
}
In the constructor, the compiler updates the bitmap:
public XYPointWithRW(int x) {
Product.class.$init$(this);
this.y = 0;
this.bitmap$0 |= 1;
}
Note that it doesn't update the bitmap for constructor arguments, only for fields declared in the class body. It does this because it assumes that you will be calling the constructor and that those fields will be initialized immediately.
During deserialization however, the no-arg constructor of the first non-serializable super class is called (Object in this case), instead of the one-arg constructor shown above. Then readObject is called. The constructor above is never called. Therefore, the bitmap is never updated. Calling the accessor would fail anywhere its called, not just in the readObject method.
To work around this, you must update the bitmap manually. I've chosen to do so from the readObject method. I set all of the bits in the bitmap to 1, like so:
getClass.getField("bitmap$0").set(this, -1)
By setting all the bits to 1, it will work for all the fields (up to 32 fields anyway...what happens beyond that is anyones guess).