Static Java methods won't execute with parfor loop

12 Ansichten (letzte 30 Tage)
Matt
Matt am 22 Nov. 2021
Kommentiert: Matt am 23 Nov. 2021
I have a simple Java class with a constructor and a factory method, which I compile into TestClass.class and zip into Test.jar:
import java.util.LinkedList;
public class TestClass {
public double myMember;
public TestClass( double x ) {
this.myMember = x;
}
static public LinkedList< TestClass > createLinkedList( double[] x ) {
for( int ind = 0; ind < x.length; ind++ ) {
myList.add( new TestClass( x[ ind ] ) );
}
return myList;
}
}
I execute the createLinkedList factory method within a Matlab function:
function result = TestFunction( x )
result = 0;
foo = TestClass.createLinkedList( x );
for ind = 1:foo.size()
result = result + foo.get( ind-1 ).myMember;
end
return
I call the TestFunction in a "for" loop within another Matlab function and it works fine, but when I use a "parfor" I get an "Undefined variable or class" error, unless I explicitly run javaaddpath each time through the parfor:
function TestScript()
thisDir = fileparts( mfilename( 'fullpath' ) );
javaDir = fullfile( thisDir, 'Java' );
jarFile = fullfile( javaDir, 'TEST.jar' );
nTrials = 12;
%% 1. WORKS: Adding the folder w/ javaaddpath
javaaddpath( javaDir );
foo = zeros( 1, nTrials );
for ind = 1:nTrials
foo( ind ) = TestFunction( rand( 1,10 ) );
end
%% 2. WORKS: Adding the .jar
javarmpath( javaDir );
javaaddpath( jarFile );
foo = zeros( 1, nTrials );
for ind = 1:nTrials
foo( ind ) = TestFunction( rand( 1,10 ) );
end
%% 3. DOES NOT WORK: Running a simple parfor when adding the path
javarmpath( jarFile );
javaaddpath( javaDir );
foo = zeros( 1, nTrials );
poolobj = parpool;
parfor ind = 1:nTrials
foo( ind ) = TestFunction( rand( 1,10 ) );
end
delete( poolobj );
%% 4. DOES NOT WORK: Running a parfor using the AttachedFiles convention
javarmpath( javaDir );
foo = zeros( 1, nTrials );
poolobj = parpool( 'AttachedFiles', jarFile );
parfor ind = 1:nTrials
foo( ind ) = TestFunction( rand( 1,10 ) );
end
delete( poolobj );
%% 5. WORKS: Explicitly adding the jar within the parfor
foo = zeros( 1, nTrials );
poolobj = parpool;
parfor ind = 1:nTrials
javaaddpath( jarFile );
foo( ind ) = TestFunction( rand( 1,10 ) );
end
delete( poolobj );
return
Why aren't methods 3 & 4 working? Shouldn't the parpool workers "inherit" the workspace and classpath when constructed (as in #3)? And why isn't the class being passed to the workers with the "AttachedFiles" (as in #4)?

Akzeptierte Antwort

Mohammad Sami
Mohammad Sami am 23 Nov. 2021
The dynamic java class path is only modified in the process calling the javaaddpath. So for parallel you will have to add your jar file to the path in each of the process before using any functions from it.
You can use the parfevalOnAll function to call javaaddpath in all parallel procss before using parfor.
poolobj = parpool;
F = parfevalOnAll(poolobj,@javaaddpath,0,jarFile);
  1 Kommentar
Matt
Matt am 23 Nov. 2021
Thanks! I had been misunderstanding the 'AttachedFiles' argument.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Parallel Computing Fundamentals finden Sie in Help Center und File Exchange

Produkte


Version

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by