Can I use parfeval in App Designer to plot to a UIAxes while the code keeps running?
23 views (last 30 days)
Show older comments
Hi everyone,
I am building a tool with App Designer which has basically two goals:
- Visualize Data as it is being aquired
- Perform calculations on this data
To simulate this I load a vector containing a bunch of numbers. I epoch the data into chunks of equal size, e.g. 5 seconds with a sampling rate of 250 Hz. I want to plot this chunk using a for loop an animated line and drawnow. While this is being plotted I want to do some calculations, such as Fast-Fourier-Transform or other signal processing routines. The result from these calculations would optimally also be visualized somewhere. The main issue I am having at the moment is however to plot and calculate in parallel.
I was quickly drawn to parfeval, however I feel like this is not easy to run in App Designer for some reasons which are beyond my understanding. One of the problems seems to be that it cannot find my function in my App Designer Class. So when I supply the @app.plotFcn to parfeval, it gives me an error.
So first question: Should I in general not define the functions I want to run in parallel within the class but as a separate .m file?
I also get the following warning: "Warning: While loading an object of class 'MonitorAnesthesia':
Unable to load App Designer app object. Load not supported for matlab.apps.AppBase objects. "
So second question: Should I simply put the for loop into the function I want to run in parallel, let it give me a value, and then plot it outside using an animated line and drawnow. Could this be a solution? I think I am not understanding to a 100% how the pafeval works and how best to use it. So it would also be great if you can simply point me into a different direction if I am completly off here.
Thank you very much
Julian
0 Comments
Accepted Answer
Matt J
on 6 Jun 2023
Edited: Matt J
on 6 Jun 2023
A mechanism equivalent to .mat file saving is how data is transferred to parpool workers. The plotFcn that you give to parfeval must therefore not reference the app object because an app object cannot be saved to a .mat file. Can you not extract just the data you need for plotting and build an anonymous or nested function based on that alone?
2 Comments
Matt J
on 6 Jun 2023
Edited: Matt J
on 6 Jun 2023
Your code is difficult to read because it is unformatted and has no line breaks (something I have now corrected for you).
In any case, because of what Walter said, I think the best thing to do is give the non-graphical operation to parfeval and do the plotting on the host. Below is a simplified example, which is a callback for the attached single-button app. It simply opens a figure with 3 random subplots while summing the data for each plot in the background (backgroundCalc).
% Button pushed function: ParfevalLoopButton
function ParallelPlotButton(app, event)
figure;
for i=1:3
data=rand(1,10);
F=parfeval(backgroundPool, @backgroundCalc,1, data);
subplot(1,3,i);plot(data);
wait(F)
end
function y=backgroundCalc(x)
y=sum(x);
end
end
More Answers (2)
Hiro Yoshino
on 6 Jun 2023
As for the 1st question, are you familiar with "Object Oriented Programming"?
You should write your code in an OOP manner in the App Designer and the function like things you can define in the class are "Methods". So I am wondering if the "methods" can be passed as a function hundle to parfeval. (I suppose parfeval requires a funciton handle as an argument?). You should try with separated functions to see if it works.
As for the 2nd question.
I would suggest you use parfeval + background. This let the time-comsuming command run behind the sence and let the next code run in a parallel manner.
Walter Roberson
on 6 Jun 2023
Regardless of whether you use a parallel pool or the newer background pool, no parallel worker of any kind can directly affect the display.
This is not exactly the same as saying that you cannot create graphics in a parallel worker: you can create graphics on parallel workers, but they are created in memory. copies of graphics objects that are created on parallel workers can be sent back to the client process by using parallel data queues.
Because the parallel workers cannot affect the graphics display, it is typically not useful to send graphics objects into parallel workers. It is possible though -- you can send in copies of graphics objects, understanding that in doing so the copies the workers receive will be disconnected from graphics.
So for example if you had created a histogram() then you could deliberately pass the handle to the uiaxes into a parallel worker for it to examine the histogram properties and other related objects -- but any changes that the workers made to the received objects would not affect the display. It's like photocopying, sort of.
You cannot pass app to a parallel worker, or anything that has a copy of the app handle. But you can pick out individual properties of the app and pass them in
parfeval(@my_worker, 1, app.UIbutton7)
for example
2 Comments
Walter Roberson
on 6 Jun 2023
The short summary: you create an endpoint in the client, arrange for the endpoint to get to the worker, then the worker can write data to the endpoint, and the client can read the results while the workers are still executing.
The myworker function is supplied from a separate .m file, right? It is not part of the App Designer class which it is being called from, right?
Consider a function that is part of the App Designer class. There are three possibilities:
- The function might be the class constructor for the app class. The function would be trying to create an object of class app . Attempting to execute such a function on a parallel worker would require that the parallel worker be able to handle items of the appropriate class... but transfering members of the class across the parallel boundary is not permitted. It would be anywhere between tricky and impossible to get this to function properly
- The function might be a regular method of the app class. In such a case, the app object needs to be a parameter to the method, somewhere in the parameter list. But transporting app objects across parallel boundaries is not permitted. So the @my_worker cannot be the handle to a regular method of the app class.
- The function might be a static method of the app class. In such a case, the app object is not necessarily involved. If the static method did not refer to the app or any properties of the class... it might maybe be possible to pass it in to parfeval ?? I wouldn't rule it out at the moment.
See Also
Categories
Find more on Asynchronous Parallel Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!