MATLAB Answers

Overload operator doesn't work into workers

1 view (last 30 days)
Andrea Stevanato
Andrea Stevanato on 25 Jun 2018
Edited: Guillaume on 26 Jun 2018
I overloaded the plus operator for my class, but it doesn't work into parfor loop. The error is the following
Error using + (line 32)
Dot indexing is not supported for variables of this type.
Function is the following
function this = plus(this, offspring)
this.Individuals(end+1:end+numel(offspring.Individuals)) = offspring.Individuals;
end
Why it doesn't work in the parfor but work correctly in the for loop?

  1 Comment

Andrea Stevanato
Andrea Stevanato on 25 Jun 2018
Classes are placed in different files
classdef ClassA < handle
properties
value = []
end
methods
function obj = ClassA(val)
obj.value = val;
end
end
end
classdef ClassB < handle
properties
a = [];
end
methods
function obj = ClassB(A)
obj.a = A;
end
function obj = plus(obj, A)
obj.a(end+1:end+numel(A)) = A;
end
end
end
Here the test
>> a = ClassA(10);
>> b = ClassB(a);
>> for i = 1:3
b = b+a;
end
>> parfor i = 1:3
b = b+a;
end
Error:
An UndefinedFunction error was thrown on the workers for 'plus'. This might be because the file containing 'plus' 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 'plus' for input arguments of type 'ClassA'.
Edit: I have already tried to do the following commands without success.
>> addAttachedFiles(gcp(), 'ClassA.m')
>> addAttachedFiles(gcp(), 'ClassB.m')

Sign in to comment.

Answers (2)

Sayyed Ahmad
Sayyed Ahmad on 26 Jun 2018
class handel is a pointer of Memory. To better understand try this codes
a = ClassA(10);
b = ClassB(a);
a.value
b.a.value
a.value=20
b.a.value
so you Change in each time the value in the same Memory. if you did not useing of handle class your code will work.

  1 Comment

Andrea Stevanato
Andrea Stevanato on 26 Jun 2018
I need handle class in my code, but now i don't have anymore this error but other. If i use b = b+a into for loop it's work but if i run b = b+a into parfor loop i get error
Too many input arguments.
the same code, the only change is for with parfor.

Sign in to comment.


Guillaume
Guillaume on 26 Jun 2018
I don't know the reason for the particular error you get but you will always get an error anyway since your code is not parallelisable. You're growing an array by an arbitrary size at each step of the loop. In a parfor loop all steps of the loop occur at the same time, hence you would be growing the same array in parallel without anyway to reconcile all the grown arrays:
  • for loop
i = 1:
b.a = [b.a a(1)]
i = 2:
b.a = [b.a a(1) a(2)]
i = 3:
b.a = [b.a a(1) a(2) a(3)]
  • parfor
i = 1 i = 2 i = 3
b.a = [b.a a(1)] b.a = [b.a a(2)] b.a = [b.a a(3)
put together: b.a = ????

  2 Comments

Andrea Stevanato
Andrea Stevanato on 26 Jun 2018
b.a = [a(index1) a(index2) a(index3)] with arbitrary order. Even if i tried to do it without handle object and i get this error:
>> parfor i = 1:5
c = c+a;
end
Too many input arguments.
The same code works with for loop
Edit: I'm wrong i get the same error with and without handle!
Guillaume
Guillaume on 26 Jun 2018
with arbitrary order
That may be what you want but that's not the way parfor works. parfor, as designed, is not capable to paralellise your code (with or without handle). You cannot have parallel branches growing the same array at once.
What may work (completely untested, don't have the toolbox):
classdef classB < handle
properties
a;
accum = {};
end
methods
function this = classB(A, accumsize)
this.a = A.value;
this.accum = cell(1, accumsize);
end
function add(this, A, idx)
this.accum{idx} = A.value;
end
function result = gather(this)
result = [this.a, this.accum{:}];
end
end
end
a = classA(10);
numadds = 3
b = classB(a, numadds);
parfor i = 1:numadds
b.add(a, i);
end
b.gather

Sign in to comment.


Translated by