MATLAB Answers

0

parfeval() doesn't call function

Asked by Timo Schmid on 7 Nov 2019
Latest activity Edited by Edric Ellis
on 8 Nov 2019
I am trying to process Data from an UDP Server close to realtime.
For that I wrote this MatLab Code to fill a Buffer with the UDP Datagrams and Process the Data (split the strings, etc.) once the Buffer from my MatLab function is full (myBuffer).
During Processing the data (which takes about 0.9s) I need to go on receiving Data and store them in the (now) emptied Buffer.
I found the parfeval-Function of the "Parallel Computing Toolbox" which might suit my needs as I need my function "ProcessData" to run in the background.
The Problem I encountered is that I can't make it run as the parfeval function doesn't enter my function ProcessData. I tested it with setting a breakpoint in ProcessData() but the program never stops. Did I do anything wrong with the function parameters?
That's what MatLab help says: F = parfeval(p,fcn,numout,in1,in2,...) requests asynchronous execution of the function fcn on a worker contained in the parallel pool p, expecting numout output arguments and supplying as input arguments in1,in2,....
Hope you guys can help me with this problem! Thanks in advance.
function ReadVoltage
%% Specify a Server (host name or IP address) with Port 8080
u = udp('192.168.0.164', 8080); %UDP Object Zuhause
%u = udp('169.254.38.221', 8080); %UDP Object Pilotfabrik
% Buffer in the enclosing function
myBuffer = {}; %Initialisierung
MAXBUFFLEN = 100; %Maximale Anzahl an Eintraegen in Buffer (1 Eintrage = 1 Datagram)
u.InputBufferSize = 4060;
u.ReadAsyncMode = 'continuous';
u.DatagramReceivedFcn = @DatagramReceivedFcn;
u.ErrorFcn = @ErrorFcn;
u.DatagramTerminateMode =
u.Terminator = '!';
%% Initialize Parallel pool
pool = gcp();
%% Oeffnen der Verbindung
fopen(u);
if (~strcmp(u.Status,'open'))
NetworkError(u,'Connection failed!');
end
%% Start Data transmission by trigger
fprintf(u, 'Requesting Data')
%% Callback Funktion
function DatagramReceivedFcn(u,~)
datagram = fscanf(u);
disp('Data Received!');
myBuffer{end+1} = datagram; %Appends datagram to buffer
[~, bufflen] = size(myBuffer);
if bufflen < MAXBUFFLEN
return;
else
f = parfeval(pool, @ProcessData, 1, myBuffer);
myBuffer = {}; %empty Buffer
end
end
function ErrorFcn(u,~)
disp("An Error occured");
end
end
function datagram_values = ProcessData(myBuffer)
stringvalues = split(myBuffer, ";"); %Split Strings
doublevalues = str2double(stringvalues) %Convert Strings do Doubles
dim_doublevalues = size(doublevalues); %Dimension of Double Output Array
i_max = dim_doublevalues(2) %Anzahl der Datenpakete
j_max = (dim_doublevalues(3))-1 %Anzahl der Werte pro Datenpaket; -1 wegen leerem Wert nach ";" am Ende
k_max = i_max*j_max %Gesamtanzahl der Werte in Buffer
k=1;
while k<=k_max
for i = 1:i_max
for j = 1:j_max
datagram_values(k,1)=doublevalues(1,i,j);
k=k+1;
end
end
end
disp(datagram_values);
end

  0 Comments

Sign in to comment.

1 Answer

Answer by Edric Ellis
on 8 Nov 2019
Edited by Edric Ellis
on 8 Nov 2019
 Accepted Answer

Unfortunately, the MATLAB debugger can't stop in code running on the workers - only code running at the client.
In this case, you should try looking at the diary output of the future f, like this:
f = parfeval(..);
wait(f); % wait for the worker to complete
disp(f.Diary); % display the output
If you don't wish to block the client, you could use afterEach to invoke the call to disp, like this:
f = parfeval(..);
afterEach(f, @(f) disp(f.Diary), 0, 'PassFuture', true);

  0 Comments

Sign in to comment.