Integrating Parallel Computing with App Designer for Real-Time UI Updates

38 visualizzazioni (ultimi 30 giorni)
I’ve developed an application with three panels, each responsible for a different task, and I need to update the UI in real-time. However, I’m running into issues because App Designer doesn’t support threading directly and struggles with accessing app property variables. I would like to utilize the Parallel Computing Toolbox to enable parallel execution of tasks and update the UI simultaneously.
I’ve already tried using parfor, parfeval, and spmd to handle parallel execution, but I’m facing difficulties with updating the app property variables in real-time within the App Designer environment. Specifically, these approaches are not integrating well with the app's UI and property variables.
Can you provide guidance on how to properly integrate parallel computing with App Designer while ensuring the app property variables are updated correctly in real-time? Any tips or solutions to resolve this issue would be very helpful!

Risposte (2)

Rick Amos
Rick Amos il 7 Nov 2024
My recommendation is to use a mix of parfeval (to launch parallel work) with afterEach/afterAll (to update the app in response to that work finishing):
You are allowed to update the App inside the afterEach/afterAll function. This means you can think of these as like Callbacks to parallel work.
For an example, create an AppDesigner app named "MyApp" with a button and a UIAxis. Then add the following code:
classdef MyApp < .. % AppDesigner app with a "Start" button and a single UI Axes
methods (Static)
function result = doSomeWork()
pause(1);
result = rand(100, 1);
end
end
methods
% One of the doSomeWork tasks finished with a result
function OneTaskFinished(app, result)
hold(app.UIAxes, "on");
plot(app.UIAxes, result);
hold(app.UIAxes, "off");
drawnow("limitrate", "nocallback");
end
% All tasks finished. This receives the futures because
% PassFuture=true in the above afterAll
function AllTasksFinished(app, futures)
% Report the first error if one is present
for ii = 1:numel(futures)
if ~isempty(futures(ii).Error)
errordlg(getReport(future(ii).Error));
end
end
%... Make the App look like it's idle again
app.Button.Enable = true;
end
end
methods
% Callback for a Start button (add callback through AppDesigner)
function ButtonPushed(app, event)
%... Make the App look like it's running
app.Button.Enable = false;
% Launch some parallel work
for ii = 1:10
futures(ii) = parfeval(@MyApp.doSomeWork, 1);
end
% Setup an app callback run per task
afterEach(futures, @app.OneTaskFinished, 0);
% Setup an app callback run once all work finishes
% PassFuture allows us to understand if any task errored.
afterAll(futures, @app.AllTasksFinished, 0, PassFuture=true);
end
end
end
  8 Commenti
Walter Roberson
Walter Roberson il 28 Nov 2024 alle 18:37
You wrote, "Each process runs continuously". That implies you are using parallel processing. Parallel processing requires either the use of Parallel Computing Toolbox, or else the use of Background Pools. Your code uses parfeval but does not construct a background pool, so you must be using the Parallel Computing Toolbox.
parfeval() automatically opens a parpool if there is no existing parallel pool.
BHARATH
BHARATH il 29 Nov 2024 alle 10:38
@Walter Roberson I should have clarified this earlier. For the CAN functions, they are called by a timer function, which triggers every 1 millisecond. For the DAQ functions, they are invoked through a callback in the Data Acquisition Toolbox, which is triggered after receiving a set of data.
Additionally, I have experimented with Parallel Computing Toolbox functions like parfeval(), parfevalOnAll(), and spmd in my code. My goal was to call button-pressed callback functions from App Designer using these parallel processing functions.
I’m sharing the code I used to create the parallel pool for reference. Let me know if you have suggestions
% Start a parallel pool if none exists
if isempty(gcp('nocreate'))
parpool(); % Start a parallel pool
end
Starting parallel pool (parpool) using the 'Processes' profile ...
Error using parpool (line 133)
No default cluster available. Create a cluster and its associated profile.
% Get the current parallel pool
p = gcp();
% Run tasks on different workers
f1 = parfeval(p, @canRead, 0, app, 1);
f2 = parfeval(p, @ReadIoFromExcel, 0, app);
f3 = parfeval(p, @StartInputAcquisition, 0, app);
f4 = parfeval(p, @StartOutputAcquisition, 0, app);
% Optionally fetch results asynchronously
results = cell(4, 1);
results{1} = fetchOutputs(f1);
results{2} = fetchOutputs(f2);
results{3} = fetchOutputs(f3);
results{4} = fetchOutputs(f4);

Accedi per commentare.


Walter Roberson
Walter Roberson il 7 Nov 2024
The only Mathworks product that is designed for Real-Time work is Simulink Real-Time.
You will never be able to get Real-Time performance from MATLAB (including App Designer.) MATLAB is not designed for Real-Time and will never be designed for Real-Time.

Categorie

Scopri di più su MATLAB Parallel Server in Help Center e File Exchange

Prodotti


Release

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by