Stream Data from a MAT-File as Input for a Parallel Simulation
This example shows how to use Simulink.SimulationData.DatasetRef
objects and the parsim
function to stream input data from a version 7.3 MAT-file for parallel simulations. Consider following the steps outlined in this example when the inputs for your simulation are too large to load into memory. For example, you can use data logged to persistent storage from one set of parallel simulations as input for another.
This example uses parsim
to run multiple simulations of a model, with each simulation using unique input data. The model is based on the Multiple Simulations Workflow Tips sldemo_suspn_3dof
model, modified to use Inport blocks as the source for inputs instead of the Signal Editor block. The model simulates the response of a suspension system to different road conditions. The MAT-file used in this example contains multiple Simulink.SimulationData.Dataset
objects representing various road conditions. The example uses DatasetRef
objects to stream the contents of an entire referenced Dataset
object as simulation input.
You can also stream data for individual signals into parallel simulations run with parsim
using matlab.io.datastore.SimulationDatastore
objects. For details on creating SimulationDatastore
objects, see Stream Individual Signals Using SimulationDatastore Objects.
Load Model and Access Input Data
Load the ex_sldemo_suspn_3dof_parsim_stream
model. The model receives input data through two Inport blocks, and each Dataset
object used as simulation input contains two elements: one for each Inport.
mdl = 'ex_sldemo_suspn_3dof_parsim_stream';
open_system(mdl)
You can use the Simulink.SimulationData.DatasetRef.getDatasetVariableNames
function to evaluate the contents of the MAT-file containing the input data without loading the data into memory. The function returns a cell array that contains elements for the name of each Simulink.SimulationData.Dataset
variable the file contains. Use the function to access the variable names and determine the number of test cases in the file.
varNames = Simulink.SimulationData.DatasetRef.getDatasetVariableNames('suspn_3dof_test_cases.mat');
numTestCases = numel(varNames);
You can stream the test case data into the model using Simulink.SimulationData.DatsetRef
objects. The DatasetRef
object references a variable in the file used to create it and loads the variable data incrementally. Create a DatasetRef
object for each Simulink.SimulationData.Dataset
object in the test cases file.
for idx1 = 1:numTestCases inputData(idx1) = Simulink.SimulationData.DatasetRef('suspn_3dof_test_cases.mat',... varNames{idx1}); end
Configure and Run Parallel Simulations
To use the set of test case inputs as input for a set of parallel simulations, create an array of Simulink.SimulationInput
objects that you can pass to the parsim
function. Use the setExternalInput
function to specify a Simulink.SimulationData.DatasetRef
object corresponding to a test case as data to stream as simulation input.
in(1:numTestCases) = Simulink.SimulationInput(mdl); for idx2 = 1:numTestCases in(idx2) = setExternalInput(in(idx2),inputData(idx2)); end
Use the parsim
function to run a simulation for each test case. When you have the Parallel Computing Toolbox™, the parsim
function runs simulations in parallel. Without the Parallel Computing Toolbox, the parsim
function runs the simulations in serial.
The parsim
function creates a worker pool based on the Parallel Computing Toolbox configuration. By default, parsim
uses a local pool. If you use remote workers, you can use the AttachedFiles
name-value pair to send the MAT-file containing the test case input data to each worker. When you specify the AttachedFiles
name-value pair, parsim
sends a copy of the file to each worker, which can take some time for large files. For streaming input data from a large file, local workers may be faster because the workers have access to the file without creating and sending copies. When you use remote workers, consider storing the MAT-file in a location that all remote workers can access and creating DatasetRef
objects that reference that copy of the file.
out = parsim(in);
[05-Nov-2022 19:23:12] Checking for availability of parallel pool... Starting parallel pool (parpool) using the 'Processes' profile ... Connected to the parallel pool (number of workers: 8). [05-Nov-2022 19:24:02] Starting Simulink on parallel workers... [05-Nov-2022 19:24:33] Configuring simulation cache folder on parallel workers... [05-Nov-2022 19:24:33] Loading model on parallel workers... [05-Nov-2022 19:24:49] Running simulations... [05-Nov-2022 19:25:03] Completed 1 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 2 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 3 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 4 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 5 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 6 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 7 of 20 simulation runs [05-Nov-2022 19:25:03] Completed 8 of 20 simulation runs [05-Nov-2022 19:25:05] Completed 9 of 20 simulation runs [05-Nov-2022 19:25:05] Completed 10 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 11 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 12 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 13 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 14 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 15 of 20 simulation runs [05-Nov-2022 19:25:06] Completed 16 of 20 simulation runs [05-Nov-2022 19:25:07] Completed 17 of 20 simulation runs [05-Nov-2022 19:25:07] Completed 18 of 20 simulation runs [05-Nov-2022 19:25:07] Completed 19 of 20 simulation runs [05-Nov-2022 19:25:07] Completed 20 of 20 simulation runs [05-Nov-2022 19:25:07] Cleaning up parallel workers...
View Simulation Results
You can access the simulation results programmatically when the simulations finish. Create a plot showing the vertical displacement for the vehicle for all the road profile test cases.
if isempty(out(1).ErrorMessage) legend_labels = cell(1,numTestCases); for i = 1:numTestCases if isempty(out(i).ErrorMessage) simOut = out(i); ts = simOut.logsout.get('vertical_disp').Values; ts.plot; legend_labels{i} = ['Run ' num2str(i)]; end hold all end title('Response of a 3-DoF Suspension Model') xlabel('Time (s)'); ylabel('Vehicle vertical displacement (m)'); legend(legend_labels,'Location','NorthEastOutside'); end
You can also view parsim
simulation results using the Simulation Manager. To view results in the Simulation Manager, use the ShowSimulationManager
name-value pair for parsim
. With the Simulation Manager, you can monitor the progress of the runs, view simulation data, and show the parsim
results in the Simulation Data Inspector.
Close Parallel Workers
When you have finished running parallel simulations, you can close the worker pool.
delete(gcp('nocreate'));
Related Topics
Log Data to Persistent Storage
Run Parallel Simulations for a Thermal Model of a House Using parsim