MATLAB: Parfor energyplus co-simulation toolbox

bcvtbco-simulation toolboxenergyplusMATLABparfor

I am using the co-simulation toolbox to simulate multiple buildings in energyplus.(Jiri Dostal (2019). EnergyPlus Co-simulation Toolbox (https://www.github.com/dostaji4/EnergyPlus-co-simulation-toolbox), GitHub. Retrieved February 5, 2019.) I managed to use a forloop. To reduce the computation time I would like to run this code in parallel using parfor. However I cannot make it work. Do you have any tips or suggestions? Thanks in advance!
What I tried until now:
I changed for in parfor (see code below). this gives the following error:
Error using mlep/acceptSocket (line 1129)
Java exception occurred:
java.net.SocketTimeoutException: Accept timed out
at java.net.DualStackPlainSocketImpl.waitForNewConnection(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
Error in mlep/start (line 283)
obj.acceptSocket;
Error in cosimeplus (line 3)
parfor c=1:20
adding (c) to all "ep." files. This gives the following error:
Error using cosimeplus (line 3)
Error: The variable ep in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
adding Tabel(c)=logTable This gives the following error:
Error using cosimeplus (line 3)
Error: The temporary variable logTable in a parfor is uninitialized.
See Parallel for Loops in MATLAB, "Uninitialized Temporaries".
%% 2 Instantiate the co-simulation tool
ep=[];
parfor c=1:20
textFileName = ['matlabtest' num2str(c) 'a.idf'];
ep = mlep;
% Building simulation file
ep.idfFile(c) = textFileName;'rt';
% Weather file
ep.epwFile = 'Amsterdam';
% Initialize
ep.initialize;
inputs = ep.inputTable;
outputs = ep.outputTable;
timestep = ep.timestep; %[s]


% Simulation length
endTime = 365*24*60*60; %[s]
% Logging
logTable = table('Size',[0, 1 + ep.nOut],...
'VariableTypes',repmat({'double'},1,1 + ep.nOut),...
'VariableNames',[{'Time'}; ep.outputSigName]);
% Start co-simulation
ep.start;
t = 0;
iLog = 1;
while t < endTime
% Specify inputs
u = [18 30]; % [heating setpoint, cooling setpoint]
% Send inputs & get outputs from EnergyPlus
y = ep.step(u);
% Obtain elapsed simulation time
t = ep.time; %[s]
% Or alternatively by using 'read' and 'write' methods. Please note that the 'read'
% method must preceed the 'write' method.
%{
% Get outputs from EnergyPlus
[y, t] = ep.read;
% Send inputs to EnergyPlus
ep.write(u,t);
%}
% Log data
logTable(iLog, :) = num2cell([t y']);
iLog = iLog + 1;
end
% Stop co-simulation
ep.stop;
%%pe-allocate arrays
% 3 calculate RMSE
Eplus_heating(c)=((sum(logTable.EP_BOILER__Boiler_Gas_Rate(2:8761))))/1000
Eplus_DHW(c)=((sum(logTable.EP_DHW_LOOP_WATER_HEATER__Water_Heater_Gas_Rate(2:8761))))/1000
Eplus_tot(c)=Eplus_heating(c)+Eplus_DHW(c)
end

Best Answer

I think the problem here is that the toolbox is not designed to be run multiple times simultaneously on a single machine. I took a brief scan through the toolbox code, and it looks like the main problem is that I think each worker is attempting to write out the same "socket.cfg" file to indicate to the external process how to communicate. It might work to try and set each mlep instance to have a unique workDir, something like this perhaps (untested!):
parfor c = 1:20
t = getCurrentTask();
d = fullfile(tempdir, sprintf('worker_%d', t.ID));
if ~exist(d, 'dir'), mkdir(d); end
ep = mlep;
ep.workDir = d;
...
end
Related Question