Main Content

Simulink.sdi.enablePCTSupport

Control when to import data from parallel simulations into the Simulation Data Inspector

Description

Simulink.sdi.enablePCTSupport(mode) configures data import into the Simulation Data Inspector from parallel workers according to the mode specified by mode. You can configure the Simulation Data Inspector to import only data from local workers, or data from local and remote workers. You can also set the mode to manual, which allows you to manually import runs into the Simulation Data Inspector using the Simulink.sdi.sendWorkerRunToClient function. By default, the Simulation Data Inspector is configured for the manual import mode.

example

Examples

collapse all

Configure Simulation Data Inspector parallel worker support to import the output automatically from both local and remote workers.

Simulink.sdi.enablePCTSupport('all')

To prevent the output from Parallel Computing Toolbox™ workers from automatically importing into the Simulation Data Inspector, specify the manual support mode.

Simulink.sdi.enablePCTSupport('manual')

This example shows how to use Simulink.sdi.sendWorkerRunToClient to send runs created using parallel workers manually to the Simulation Data Inspector.

Setup

This example runs several simulations of the vdp model, varying the value of the Gain block, Mu. To set up for the parallel simulation, define a vector of Mu values and configure the Simulation Data Inspector for manual Parallel Computing Toolbox support.

MuVals = [0.1 0.2 0.3 0.4];
Simulink.sdi.enablePCTSupport("manual");

Initialize Parallel Workers

Use parpool (Parallel Computing Toolbox) to start a pool of four parallel workers. This example calls parpool inside an if statement so you only create a parallel pool if you do not already have one.

p = gcp("nocreate");
if isempty(p)
    parpool(4);
end

You can use spmd (Parallel Computing Toolbox) to run initialization code common to all workers. For example, load the vdp model and Simulink.sdi.markSignalForStreaming function to select signals to log to the Simulation Data Inspector. To avoid data concurrency issues when simulating with sim in parfor, create a temporary directory on each worker.

spmd
    load_system("vdp")
    Simulink.sdi.markSignalForStreaming("vdp/x1",1,"on")
    Simulink.sdi.markSignalForStreaming("vdp/x2",1,"on")
    
    workDir = pwd;
    addpath(workDir)
    tempDir = tempname;
    mkdir(tempDir)
    cd(tempDir)
end

Run Parallel Simulations with parfor

To stream data from parallel workers to the Simulation Data Inspector, run parallel simulations using parfor (Parallel Computing Toolbox). Each worker runs a vdp simulation with a different value of Mu. The software cannot access the contents of the parfor loop, so the variable MuVal is defined in the worker's workspace, where the vdp model can see it, using assignin.

parfor (index = 1:4)
    assignin("base","MuVal",MuVals(index));
    set_param("vdp/Mu","Gain","MuVal")
    sim("vdp");

Access Data and Send Run to Client MATLAB

You can use the Simulation Data Inspector programmatic interface on the worker the same way you would in the client MATLAB. This example creates a Simulink.sdi.Run object and attaches the value of Mu used in the simulation with the Tag property.

    IDs = Simulink.sdi.getAllRunIDs;
    lastIndex = length(IDs);
    runID = Simulink.sdi.getRunIDByIndex(lastIndex);
    parRun = Simulink.sdi.getRun(runID);
    parRun.Tag = strcat("Mu = ",num2str(MuVals(index)));
    
    Simulink.sdi.sendWorkerRunToClient   
end

Close Temporary Directories and View Runs in the Simulation Data Inspector

Use another spmd section to delete the temporary directories created on the workers once the simulations complete.

spmd
    cd(workDir)
    rmdir(tempDir,"s")
    rmpath(workDir)
end

In each simulation, the Simulink.sdi.sendWorkerRunToClient function imported runs from all the workers into the Simulation Data Inspector. You can view the data and check the run properties to see the value of Mu used during simulation.

Simulink.sdi.view

Execute parallel simulations of the model slexAircraftExample with different input filter time constants and access the data in different ways using the Simulation Data Inspector programmatic interface.

Setup

Check that the Simulation Data Inspector is empty and that Parallel Computing Toolbox support is configured to import runs created on local workers automatically. Then, create a vector of filter parameter values to use in each simulation.

Simulink.sdi.clear
Simulink.sdi.enablePCTSupport("local")

Ts_vals = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1]; 

Initialize Parallel Workers

Use the gcp function to create a pool of local workers to run parallel simulations if you don't already have one. In an spmd code block, load the slexAircraftExample model and select signals to log. To avoid data concurrency issues using sim in parfor, create a temporary directory for each worker to use during simulations.

p = gcp;
Starting parallel pool (parpool) using the 'Processes' profile ...
02-Nov-2023 16:05:17: Job Queued. Waiting for parallel pool job with ID 1 to start ...
02-Nov-2023 16:06:18: Job Queued. Waiting for parallel pool job with ID 1 to start ...
Connected to parallel pool with 6 workers.
spmd
    % Load system and select signals to log
    load_system("slexAircraftExample")
    Simulink.sdi.markSignalForStreaming("slexAircraftExample/Pilot", 1, "on")
    Simulink.sdi.markSignalForStreaming("slexAircraftExample/Aircraft Dynamics Model", 4, "on")
    
    % Create temporary directory on each worker
    workDir = pwd;
    addpath(workDir)
    tempDir = tempname;
    mkdir(tempDir)
    cd(tempDir)
end

Run Parallel Simulations

Use parfor to run the seven simulations in parallel. Select the value for Ts for each simulation, and modify the value of Ts in the model workspace. Then, run the simulation and build an array of Simulink.sdi.WorkerRun objects to access the data with the Simulation Data Inspector. After the parfor loop, use another spmd segment to remove the temporary directories from the workers.

parfor index = 1:7
    % Select value for Ts
    Ts_val = Ts_vals(index);
    
    % Change the filter time constant and simulate
    modelWorkspace = get_param("slexAircraftExample","modelworkspace");
    assignin(modelWorkspace,"Ts",Ts_val)
    sim("slexAircraftExample");
    
    % Create a worker run for each simulation
    workerRun(index) = Simulink.sdi.WorkerRun.getLatest
end

spmd        
    % Remove temporary directories
    cd(workDir)
    rmdir(tempDir, "s")
    rmpath(workDir)
end

Get Dataset Objects from Parallel Simulation Output

The getDataset function puts the data from a WorkerRun object into a Dataset object so you can easily post-process.

ds(7) = Simulink.SimulationData.Dataset;

for a = 1:7
    ds(a) = getDataset(workerRun(a));
end
ds(1)
ans = 
Simulink.SimulationData.Dataset '' with 12 elements

                         Name        BlockPath                                
                         __________  ________________________________________ 
    1  [1x1 State ]      ''          slexAircraftExample/Actuator Model      
    2  [1x1 Signal]      alpha, rad  ...rcraftExample/Aircraft Dynamics Model
    3  [1x1 State ]      ''          ...cs Model/Pitch Channel/Integrate qdot
    4  [1x1 State ]      ''          ...mics Model/Vertical Channel/Integrate
    5  [1x1 State ]      ''          ...ntroller/Alpha-sensor Low-pass Filter
    6  [1x1 State ]      ''          ...ller/Integrator/Continuous/Integrator
    7  [1x1 State ]      ''          ...ple/Controller/Pitch Rate Lead Filter
    8  [1x1 State ]      ''          ...aftExample/Controller/Stick Prefilter
    9  [1x1 State ]      ''          .../Dryden Wind Gust Models/Q-gust model
   10  [1x1 State ]      ''          .../Dryden Wind Gust Models/W-gust model
   11  [1x1 Signal]      Stick       slexAircraftExample/Pilot               
   12  [1x1 Signal]      alpha, rad  slexAircraftExample/alpha, rad          

  - Use braces { } to access, modify, or add elements using index.

Get DatasetRef Objects from Parallel Simulation Output

For big data workflows, use the getDatasetRef function to reference the data associated with the WorkerRun.

for b = 1:7
    datasetRef(b) = getDatasetRef(workerRun(b));
end
datasetRef(1)
ans = 
  DatasetRef with properties:

           Name: 'Run <run_index>: <model_name>'
            Run: [1×1 Simulink.sdi.Run]
    numElements: 12

Process Parallel Simulation Data in the Simulation Data Inspector

You can also create local Simulink.sdi.Run objects to analyze and visualize your data using the Simulation Data Inspector programmatic interface. This example shows a tag indicating the filter time constant value for each run.

for c = 1:7
    Runs(c) = getLocalRun(workerRun(c));
    Ts_val_str = num2str(Ts_vals(c));
    desc = strcat("Ts = ", Ts_val_str);
    Runs(c).Description = desc;
    Runs(c).Name = strcat("slexAircraftExample run Ts=", Ts_val_str);    
end

Clean Up Worker Repositories

Clean up the files used by the workers to free up disk space for other simulations you want to run on your worker pool.

Simulink.sdi.cleanupWorkerResources

Input Arguments

collapse all

Simulation Data Inspector data import mode for data logged on parallel workers, specified as one of these options:

  • 'manual' — Do not automatically import runs created on parallel workers. You can manually import runs created on parallel workers using the Simulink.sdi.sendWorkerRunToClient function.

  • 'local' — Automatically import runs created on local workers.

  • 'all' — Automatically import runs created on local and remote workers.

Data Types: char | string

Alternative Functionality

You can modify the parallel computing support mode in the Simulation Data Inspector by selecting Preferences > Parallel.

Version History

Introduced in R2017b

expand all