Static Java methods won't execute with parfor loop

8 visualizaciones (últimos 30 días)
Matt
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)?

Respuesta aceptada

Mohammad Sami
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);
  1 comentario
Matt
Matt el 23 de Nov. de 2021
Thanks! I had been misunderstanding the 'AttachedFiles' argument.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Parallel Computing Fundamentals en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by