2

I am trying to call parallel functions within my Matlab-GUI by pushing a startbutton.

For the beginning I tried to call one single function ("ReadTwinCAT") but I'm always getting the following error-message:

"Warning: Unable to save App Designer app object. Save not supported for matlab.apps.AppBase objects."

As I thought I already used parallel functions like this within a GUI, I don't know what I am doing wrong...

Matlab-App-Designer Code:

properties (Access = private)
    running_state = 0; % Description
    tcClient;
    db_conn;
end

methods (Access = private)

    function ReadTwinCAT(app)

        while app.running_state == 1
            disp('running')
            pause(0.1) 
        end  
        disp('stopped')

    end         
end


% Callbacks that handle component events
methods (Access = private)

    function StartButtonPushed(app, event)

       app.running_state = 1;

       pool = gcp(); %Initialize pool of workers

       parfeval(pool, @ReadTwinCAT, 0, app); %Call parallel function

    end
end
timosmd
  • 159
  • 11
  • I'm running into the same problem, I think. My guess is that when you set a property of app like "app.running_state", that change has to be "saved" to update the app handle object, so that change is available to other functions that access the app object. I'm also guessing that in a parfeval call, such saving is not allowed because of thread safety problems. – Brionius Jun 02 '20 at 14:26

1 Answers1

1

Ok, I think I found an answer from Mathworks staff: https://www.mathworks.com/matlabcentral/answers/366576-will-there-be-a-support-of-the-parallel-toolbox-in-matlab-app-designer#comment_720548

Note the limitation of accessing the app object inside the parfor loop or any other functions called though Parallel Computing Toolbox.

If you need to access properties of your app pass them down as values directly, e.g. instead of

b = [0,0];  
parfor i=1:2
    b(i) = app.myprop*2
end

use

tmp = app.myprop;
b = [0,0];  
parfor i=1:2
    b(i) = tmp*2
end

So it seems that you can't access (or it would seem set) the properties of the app object within a parallelized function. If you want to get data out, you'll probably have to set up a communication system using parallel.pool.DataQueue. Your example is tough to parallelize. A better option would probably be to add a listener to your running_state property, and/or use a timer function.

The major downside of this is that the function you call from the timer is not actually parallelized - it runs in the same thread, so if you have a lot of computation in ReadTwinCAT, I think it will cause lag/unresponsiveness in the GUI.

I've modified your code to use a timer instead of parfeval:

properties (Access = private)
    running_state = 0; % Description
    runningTimer;
    tcClient;
    db_conn;
end

methods (Access = private)

    function ReadTwinCAT(app, varargin)
        if app.running_state == 1
            disp('running')
        else
            stop(app.runningTimer);
            disp('stopped')
        end
    end

end

% Callbacks that handle component events
methods (Access = private)

    function StartButtonPushed(app, event)
        app.running_state = 1;

        app.runningTimer = timer;
        app.runningTimer.Period = 0.1;
        app.runningTimer.ExecutionMode = 'fixedRate';
        app.runningTimer.TimerFcn = @app.ReadTwinCAT;
        start(app.runningTimer)
    end

end
Brionius
  • 13,858
  • 3
  • 38
  • 49