Static Java methods won't execute with parfor loop

4 ビュー (過去 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 件)

カテゴリ

Find more on Parallel Computing Fundamentals in Help Center and File Exchange

製品


リリース

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by