Using .Net Assembly Methods in parfor Parallel loops.

조회 수: 12 (최근 30일)
Frank Forkl
Frank Forkl 2017년 11월 13일
편집: Frank Forkl 2017년 11월 29일
I am trying to use methods from a .Net Assembly class inside a parfor loop in MATLAB 2017a. Here is the relevant section of code, omitting the section where the method inputs are generated. I run the addAssembly command on all workers (which posts a lot of unnecessary info to the window, but I can deal with that):
gcp;
pctRunOnAll NET.addAssembly('SinapsXNet');
pctRunOnAll SP = SinapsXNet.SindaPlotting;
parfor i = 1:NumRecords
SP.getAllAtRecord('T',RecordNumbers(i));
TemperatureOut(i,:) = double(getXArray(SP));
end
And this creates the error "Warning: Unable to load .NET object. Saving (serializing) .NET objects into a MAT-file is not supported." This function works without an issue if constructed with a basic 'for' instead of 'parfor'. Is there a workaround for this error?

답변 (1개)

Edric Ellis
Edric Ellis 2017년 11월 13일
In your example, the variable SP is being transferred to the workers, and that uses the same machinery as save and load (despite your use of pctRunOnAll, the body of your parfor loop is using the SP instance transferred from the client). I don't have the necessary code to try this out, but perhaps it might work to do the following:
gcp;
pctRunOnAll NET.addAssembly('SinapsXNet');
SP_c = parallel.pool.Constant(@SinapsXNet.SindaPlotting);
parfor i = 1:NumRecords
SP = SP_c.Value;
SP.getAllAtRecord('T',RecordNumbers(i));
TemperatureOut(i,:) = double(getXArray(SP));
end
This avoids the problem by using parallel.pool.Constant with a function handle to build the .NET object directly on the workers.
  댓글 수: 3
Edric Ellis
Edric Ellis 2017년 11월 20일
That looks like a loop output is somehow a .NET object (that last warning is being thrown at the client when trying to interpret results from the workers). Does the parallel.pool.Constant appear to do the right thing at all? I.e. can you access the .Value field on the workers (using parfor or even spmd), and does it appear to contain the correct object? I.e.
spmd
disp(SP_c.Value)
end
Frank Forkl
Frank Forkl 2017년 11월 22일
편집: Frank Forkl 2017년 11월 29일
So, with a bit more context, what is going on makes a bit more sense. Here is enough to code to actually run if you have the .dll and data file (same as the other post you replied to):
%Read in SINDA Save Files using .NET assemblies
clear;
FP = 'F:\Read Sav File\2017-09-19_ResUp3Ch.sav';
gcp;
pctRunOnAll NET.addAssembly('SinapsXNet');
SP = SinapsXNet.SindaPlotting;
%Load in Data File
reOpen(SP, FP, 'PC');
%Count Numbers, load indicies
RecordNumbers = int64(getIntYArray(SP));
[~,NumRecords] = size(RecordNumbers);
%Iterate through data and output to a matrix:
parfor i = 1:NumRecords
SP.getAllAtRecord('T',RecordNumbers(i));
TemperatureOut(i,:) = double(getXArray(SP));
end
(reOpen, getIntYArray, getAllAtRecord, and getXArray are all methods of the class SinapsXNet.SindaPlotting)
So, the SP object is carrying information with it, specifically the data from the file it loaded. This is why the suggestion to create the object on the workers didn't work, the object wasn't loaded with the data. This code still throws this error:
Warning: Unable to load .NET object. Saving (serializing) .NET objects into a MAT-file is not supported.
> In parallel.internal.pool.deserialize (line 9)
In parallel.internal.pool.deserializeFunction (line 12)
In remoteParallelFunction (line 33)
Error using ReadSINDASav5_SlimPar
(line 16)
I'm stuck as to a solution to this in R2107A (though it does work with a few reversions in R2013A). For parfor to work, SP would need to get passed to the workers, and it appears there isn't a way to do that.

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

카테고리

Help CenterFile Exchange에서 Get Started with Microsoft .NET에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by