Static Java methods won't execute with parfor loop
6 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Matt
el 22 de Nov. de 2021
Comentada: Matt
el 23 de Nov. de 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)?
0 comentarios
Respuesta aceptada
Mohammad Sami
el 23 de Nov. de 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);
Más respuestas (0)
Ver también
Categorías
Más información sobre Parallel Computing Fundamentals en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!