Setting global variables independently on each worker for parallel computation

5 views (last 30 days)
Hello all,
I am working with running a particle swarm optimization scheme in parallel for turbofan model calibration using tmats with cantera enabled functions.
The issue that i am encountering is that the solution class needs to be initialized as a global variable in order for tmats to be able to perform its calculations. In order to do this i try the following lines of code:
% Parallel Computing Setup
TMATSPath = 'D:\TMATS_v1_3_0\TMATS_Library';
CanteraPath = 'D:\Program Files\Cantera\matlab\toolbox';
spmd
addpath(TMATSPath);
addpath(CanteraPath);
global fs
fs = Solution('gri30.yaml');
assignin('base','fs',fs);
end
however spmd does not allow for global variable assignment. I understand that it is impractical to assign global variables for parallel computation. However i am not looking for the variable to be assigned globally across all workers but to be assigned globally within each local worker's workspace. Is there some way to achieve this?
Here is the error message for additional reference:
Error using Testing>CycleCalibration
Error evaluating registered method 'Outputs' of MATLAB S-Function 'TMATSC_ambient' in
'SS_Leap1b1_scaling/Ambient'. The following is the MATLAB call stack (file names and line
numbers) that produced this error:
['D:\TMATS_v1_3_0\TMATS_Library\MATLAB_Scripts\Cantera_Enabled\+TMATSC\FlowDef.m']
[476]
['D:\TMATS_v1_3_0\TMATS_Library\MATLAB_Scripts\Cantera_Enabled\+TMATSC\FlowDef.m']
[97]
['D:\TMATS_v1_3_0\TMATS_Library\MATLAB_Scripts\Cantera_Enabled\TMATSC_ambient.m']
[115]
['D:\Program
Files\MATLAB\R2023b\toolbox\simulink\simulationinput_desktop\+Simulink\+Simulation\+internal\DesktopSimHelper.p']
[0]
['D:\Program
Files\MATLAB\R2023b\toolbox\simulink\simulationinput_desktop\+Simulink\+Simulation\+internal\DesktopSimHelper.p']
[0]
['D:\Program
Files\MATLAB\R2023b\toolbox\simulink\simulationinput\+Simulink\SimulationInput.p']
[0]
['D:\Leap1b\Testing.m'] [90]
['D:\Leap1b\Testing.m'] [60]
['D:\Program Files\MATLAB\R2023b\toolbox\globaloptim\globaloptim\particleswarm.m']
[846]
['D:\Program Files\MATLAB\R2023b\toolbox\globaloptim\globaloptim\particleswarm.m']
[191]
['D:\Program Files\MATLAB\R2023b\toolbox\globaloptim\globaloptim\particleswarm.m']
[166]
['D:\Leap1b\Testing.m'] [60]
Error in Testing>@(x)CycleCalibration(x,MDP,scaling_ranges) (line 60)
[x_opt, fval] = particleswarm(@(x) CycleCalibration(x, MDP, scaling_ranges), numVars, lb,
ub, options);
Error in particleswarm>makeState (line 846)
firstFval = objFcn(state.Positions(numInitialSwarmFvals+1,:));
Error in particleswarm>pswcore (line 191)
state = makeState(nvars,lbMatrix,ubMatrix,objFcn,options);
Error in particleswarm (line 166)
[x,fval,exitFlag,output,points] = pswcore(objFcn,nvars,lbRow,ubRow,output,options);
Error in Testing (line 60)
[x_opt, fval] = particleswarm(@(x) CycleCalibration(x, MDP, scaling_ranges), numVars, lb,
ub, options);
Caused by:
Error using Simulink.Simulation.internal.DesktopSimHelper
Undefined function 'equilibrate' for input arguments of type 'double'.
Failure in initial objective function evaluation. PARTICLESWARM cannot continue.
( equilibrate is undefined for double variables, implying that the function is being found but fs is being read as a double instead as a solution class variable)
Thank you!

Accepted Answer

Edric Ellis
Edric Ellis on 7 Feb 2025
You can modify the global workspace of a parallel pool worker, but you cannot do it directly within the body of an spmd block or a parfor loop. You can write a function to do it, so you could do something like this:
spmd
assignFsInGlobalWorkspace();
end
function assignFsInGlobalWorkspace()
global fs
fs = Solution('gri30.yaml');
assignin('base','fs',fs);
end
My question would be: do you really need fs to be both global and in the base workspace? I'd have thought only the latter was needed for most Simulink models.
  2 Comments
Lucas
Lucas on 11 Feb 2025
Edric,
Thank you for your solution. You are correct, fs only needs be global in the base workspace. I found the command which helps give the other workers access to the global fs variable.
simOut = parsim(simIn, 'ShowProgress', 'on', 'TransferBaseWorkspaceVariables', 'on');
By using 'TransferBaseWorkspaceVariables', all workers gain access to fs and the simulation runs

Sign in to comment.

More Answers (1)

Catalytic
Catalytic on 6 Feb 2025
Edited: Catalytic on 6 Feb 2025
i am not looking for the variable to be assigned globally across all workers but to be assigned globally within each local worker's workspace
If so, I don't think you need to be using global at all. Each worker's "local workspace" is precisely the body of the spmd...end block. So, as soon as you return fs to the spmd block in the line -
fs = Solution('gri30.yaml');
it becomes part of the worker's workspace.
  1 Comment
Lucas
Lucas on 6 Feb 2025
thank you for your input,
Each worker needs it own global fs variable within the simulink model in order for it to run. this is the way that the tmats code was written. fs is an initialized global solution class which allows cantera to solve for fluid states as it passes from a compressor to a turbine for example. This was done for code efficiency purposes as reinitialzing the solution class in each block significantly slows down runtime
It would be really nice if it could be fixed with this suggestion tho.

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!