Static Java methods won't execute with parfor loop

조회 수: 6 (최근 30일)
Matt
Matt 2021년 11월 22일
댓글: Matt 2021년 11월 23일
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)?

채택된 답변

Mohammad Sami
Mohammad Sami 2021년 11월 23일
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
Matt
Matt 2021년 11월 23일
Thanks! I had been misunderstanding the 'AttachedFiles' argument.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Parallel Computing Fundamentals에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by